diff --git a/backend/app/seed_data/04-rpg-world-state.json b/backend/app/seed_data/04-rpg-world-state.json index 6c882a4..3f747ac 100644 --- a/backend/app/seed_data/04-rpg-world-state.json +++ b/backend/app/seed_data/04-rpg-world-state.json @@ -4,7 +4,7 @@ "prompt": "Dawn breaks grey over the treeline as you and Gwen crouch at the edge of the bandit camp. Smoke curls from a dying fire; three bedrolls lie empty. Somewhere ahead, the stolen caravan strongbox waits.\n\nGwen checks her bowstring and looks to you. \"Quiet, or loud?\"", "memory": "The player and Gwen, a loyal ranger ally, are raiding a bandit camp to recover a stolen strongbox. The player is a capable adventurer. This is a dangerous but winnable encounter.", "authors_note": "Keep it tense and consequential. Reckless moves should cost health; clever ones should pay off. Gwen reacts to how the player treats her.", - "ai_instructions": "Write in second person, present tense. End each reply where the player can act. Let the world state guide the fiction — if the player is badly hurt, show it.", + "ai_instructions": "Write in second person, present tense. End each reply where the player can act. Let the world state guide the fiction — if the player is badly hurt, show it. In any fight, reflect the outcome in the numbers every turn: reduce the health of whoever is struck, raise the bandit leader's aggression as he is pressed, and adjust Gwen's trust based on how the player treats her.", "tags": "demo, rpg, world-state, combat, short", "stat_schema": { "world": { diff --git a/backend/app/worldstate/engine.py b/backend/app/worldstate/engine.py index c18bbf0..52bfbd3 100644 --- a/backend/app/worldstate/engine.py +++ b/backend/app/worldstate/engine.py @@ -19,14 +19,18 @@ STAT_SECTIONS = ("world", "player") # Appended once to the system prompt so the model knows how to report changes. EMIT_RULE = ( - "After your narration, if and ONLY IF something in the world state changed this " - "turn, append a fenced code block labelled `state` containing a JSON object of " - "the CHANGES ONLY, as deltas (not new totals). Use paths like " - '"player.hp", "world.day", "npc.." (use the exact npc id shown in the ' - 'world state, e.g. npc.gwen.trust); "flags.": true or false to toggle an ' - 'on/off state; and "milestones.": true when an objective is completed. Send ' - "only things that actually changed; never restate unchanged values. If nothing " - "changed, omit the block entirely. Example:\n" + "You maintain a numeric world state. Treat your own narration as authoritative: " + "whenever what you write implies a change — someone takes damage or heals, time " + "passes, an emotion or relationship shifts, a fight intensifies, an item is gained " + "or lost, or an objective is completed — you MUST record it, including the numbers, " + "not just on/off flags. After your narration, append a fenced code block labelled " + "`state` with a JSON object of the CHANGES ONLY, as deltas (not new totals). Update " + "every stat the scene affected this turn, not only the easy ones. Use the paths " + 'exactly as shown in the world state: "player.hp", "world.day", "npc.." ' + '(e.g. npc.gwen.trust — use the id in parentheses, not the display name); ' + '"flags.": true or false to toggle an on/off state; and "milestones.": ' + "true when an objective is completed. Send only things that actually changed and " + "never restate unchanged values; if truly nothing changed, omit the block. Example:\n" '```state\n{"player.hp": -15, "npc.gwen.trust": 5, "milestones.escaped": true}\n```' )