Add Phase 12: native RPG world state
Structured world/player/NPC stats, two-way flags, and sticky milestones per scenario (stat_schema). The AI proposes a per-turn delta; a Python engine referees it (clamp to min/max, per-turn cap, cooldown, counters). Band word-labels plus a fixed stat guide (descriptions + full ranges) keep the model grounded. World State drawer + Insights delta report; undo/retry roll it back via the Phase 11 snapshot pattern. - migrations 26-28 (scenarios.stat_schema, adventures.world_state, actions.world_state_before); all nullable, additive, safe on existing rows - migration 29 raises the default context budget 4096 -> 16384 (custom values preserved) - seeded demo scenario 04-rpg-world-state.json (Bandit Camp) - 19 new tests (33 total pass) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
64356414b1
commit
4dac445f90
@@ -94,6 +94,8 @@ def _matches(scenario: models.Scenario, data: dict) -> bool:
|
||||
the write and avoid churning rows on every boot."""
|
||||
if any(getattr(scenario, f) != data.get(f, "") for f in _SCALARS):
|
||||
return False
|
||||
if (scenario.stat_schema or None) != (data.get("stat_schema") or None):
|
||||
return False
|
||||
have_cards = sorted(_card_tuple(c, lambda o, f: getattr(o, f)) for c in scenario.story_cards)
|
||||
want_cards = sorted(
|
||||
_card_tuple(c, lambda o, f: o.get(f, ""))
|
||||
@@ -133,6 +135,8 @@ def _update_scenario(db, scenario: models.Scenario, data: dict) -> None:
|
||||
def _apply_scalars(scenario: models.Scenario, data: dict) -> None:
|
||||
for field in _SCALARS:
|
||||
setattr(scenario, field, data.get(field, ""))
|
||||
# Phase 12: RPG world-state template (a JSON dict, not a scalar string).
|
||||
scenario.stat_schema = data.get("stat_schema") or None
|
||||
|
||||
|
||||
def _populate_children(db, scenario: models.Scenario, data: dict) -> None:
|
||||
|
||||
Reference in New Issue
Block a user