new RPG system
This commit is contained in:
+23
-42
@@ -1,6 +1,12 @@
|
||||
"""Shared context blocks for RPG narrator / plot LLM calls."""
|
||||
|
||||
from services.rpg_plot import count_active_quests
|
||||
import json
|
||||
|
||||
from services.rpg_story import (
|
||||
format_step_for_narrator,
|
||||
normalize_story_arc,
|
||||
step_progress,
|
||||
)
|
||||
|
||||
|
||||
def format_narrator_context(
|
||||
@@ -8,46 +14,21 @@ def format_narrator_context(
|
||||
quests: list | None,
|
||||
status_quo: str = "",
|
||||
) -> str:
|
||||
parts: list[str] = []
|
||||
arc = arc or {}
|
||||
beats = arc.get("beats") or []
|
||||
if not isinstance(beats, list):
|
||||
beats = []
|
||||
arc = normalize_story_arc(arc or {}) if arc else {}
|
||||
return format_step_for_narrator(arc, quests, status_quo)
|
||||
|
||||
parts.append(f"Plot phase: {arc.get('phase', 'opening')}. Scripted beats left: {len(beats)}.")
|
||||
if not beats:
|
||||
parts.append(
|
||||
"IMPORTANT: Scripted beats are EXHAUSTED (quests may already be done). "
|
||||
"The story must CONTINUE — do not stall. "
|
||||
"Always return 2-4 meaningful choices for the player's next actions. "
|
||||
"You may add quest_updates with status 'active' for NEW optional threads. "
|
||||
"Do NOT re-activate quests the player already completed unless they explicitly revisit that thread."
|
||||
)
|
||||
elif count_active_quests(quests) == 0:
|
||||
pending = [
|
||||
(b.get("title") or b.get("id") or "beat")
|
||||
for b in beats[:3]
|
||||
if isinstance(b, dict)
|
||||
]
|
||||
parts.append(
|
||||
"IMPORTANT: No active quests but scripted beats remain — arc was likely desynced. "
|
||||
"The engine will inject the next beat; prefer choices that fit pending beats: "
|
||||
+ ", ".join(pending)
|
||||
+ ". Do NOT treat the arc as finished."
|
||||
)
|
||||
hint = (arc.get("next_beat_hint") or "").strip()
|
||||
if hint:
|
||||
parts.append(f"Arc hint: {hint}")
|
||||
|
||||
if quests:
|
||||
parts.append("Quest log:")
|
||||
for q in quests:
|
||||
parts.append(f" [{q.get('status', 'active')}] {q.get('title', '')}")
|
||||
else:
|
||||
parts.append("Quest log: (empty)")
|
||||
|
||||
sq = (status_quo or "").strip()
|
||||
if sq:
|
||||
parts.append(f"Status quo: {sq[:400]}")
|
||||
|
||||
return "\n".join(parts)
|
||||
def format_arc_summary_for_runtime(arc: dict | None) -> str:
|
||||
arc = normalize_story_arc(arc or {}) if arc else {}
|
||||
if not arc:
|
||||
return ""
|
||||
cur, total = step_progress(arc)
|
||||
return json.dumps(
|
||||
{
|
||||
"title": arc.get("title"),
|
||||
"global_story": (arc.get("global_story") or "")[:300],
|
||||
"step": f"{cur}/{total}",
|
||||
"status": arc.get("status", "active"),
|
||||
},
|
||||
ensure_ascii=False,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user