fix(openworlds): persist house + biography in engine snapshot (Closes #383) - #656
Conversation
…383) Loop-10 follow-up to #277/#369. PR #369 wired `house` + `biography` from the Creation wizard's inputs into the bindHero spec, but the engine seating path silently dropped both fields. A player who authored House + Biography in the wizard saw both vanish the moment they hit Bind. Threads both fields end-to-end (additive, schema additive-only): 1. servers/engine/models.py Character gains house/biography (str = "") 2. servers/engine/server.py create_character kwargs + constructor 3. scripts/play.sh bindHero spec -> create_character bridge 4. viewer/server.py /character-surface read-model projection 5. screen-character.jsx "of House X" subtitle + Biography paragraph Empty strings are honest no-ops — additive defaults deserialize existing snapshots unchanged; NPC/monster spawn call sites keep working. Regression guard: servers/engine/tests/test_house_biography_persistence.py (4 tests: kwargs accept, model persistence, empty defaults, round-trip). Revives PR #392 (rebased onto current main; LineagePanel empty-guard also includes biography so a bio-only hero isn't dropped).
|
Warning Review limit reached
More reviews will be available in 22 minutes and 45 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Comment |
TL;DR
Loop-10 follow-up to #277. PR #369 wired
house+biographyfrom the Creation wizard's inputs into thebindHerospec, but the engine seating path silently dropped both fields: the Character model,create_character's signature, theCharacter()constructor call,play.sh's spec-to-create_character bridge, and the/character-surfaceprojection. A player who authoredHouse = "Three Bells"+ a Biography in the wizard saw both vanish the moment they hit Bind.This PR threads both fields end-to-end + adds the UI rendering + the regression test #383's AC asked for. Revives #392, rebased onto current main.
Closes
The five sites threaded
servers/engine/models.pyCharactergainshouse: str = ""andbiography: str = ""in the identity block._StrictModelrejects extra fields — adding them at the model is what makes accepting these kwargs possible. Additive: defaults deserialize existing snapshots unchanged.servers/engine/server.pycreate_charactersignature accepts both kwargs (positional callers unaffected) + theCharacter(...)constructor threads them insidecampaign_lock.scripts/play.shcreate_characterkwargs now reads both fields from the spec dict with""coalesce. The single place the wizard's prose crosses the process boundary into the engine.viewer/server.py_character_sheetprojectshouseandbiographyto the/character-surfaceread-model via_text()for string safety. (Projection region only — no parity-lane / move-intent / live-view code touched.)viewer/openworlds/screen-character.jsxLineagePanelrenders a "Biography" section with eyebrow label +whiteSpace: pre-wrapwhen set. Both honest-empty otherwise. The empty-guard now also includesbiography, so a bio-only hero (no race/flavor) isn't dropped.Tests
New:
servers/engine/tests/test_house_biography_persistence.py— 4 teststest_create_character_accepts_house_and_biography_kwargsTypeErroron calltest_house_and_biography_persist_on_the_character_modeltest_house_and_biography_default_to_empty_when_omitted""notNonetest_house_and_biography_round_trip_through_get_characterVerification
test_character_skill_normalization+test_action_economy(additive-safety)screen-character.jsxtransformed viavendor/babel-standalone-7.29.0.min.js(node+vm)ast.parseon all modified .py + new testbash -n scripts/play.shOut of scope (intentionally)
personality/backstoryor mergebiographyinto them. These stay DISTINCT — engine-side flavor stays inlineageNote; player-authored biography stays inbiography.update_characterpath here."".Provenance
Revives #392 (same approach, rebased onto current main — diff context had drifted). Verified NOT superseded: main has only one unrelated
biographymention (a dossier comment inserver.py) and allhouserefs arehouse_rules/house-difficulty — nohouse/biographyCharacter field, signature kwarg, projection, or render existed before this PR.Engine invariant respected: engine remains the sole state writer; schema change is additive-only.