fix(engine): add_location defaults discovered=True so runtime-named places stay on the Atlas (#261/#371 follow-up) - #408
Conversation
…laces stay on the Atlas (#261/#371 follow-up) PR #371 (#261) added `discovered: bool = False` to the Location model and taught seed_world to set discovered=True on the world's day-1 regions + ingested areas. The runtime world-building path `add_location` (servers/engine/server.py) was NOT updated: its `Location(...)` constructor never set `discovered`, so a place the DM named into the world mid-play serialized `discovered=False` and the Atlas predicate (viewer/server.py :: _atlas_visible_location_ids) hid it until the party visited it. That is a silent behavior change vs. pre-#371, where add_location'd places appeared on the Atlas immediately (the field didn't exist, and the predicate treats absent/None as visible). Decision: runtime-added places should be VISIBLE by default. ----------------------------------------------------------- A place the DM names into the world mid-play is, by that act, KNOWN — the player should see it. Evidence this is the right default, not fog-of-war: * seed_world sets day-1 regions discovered=True — "known" == True. * Pre-#371, add_location'd places were visible. * The model already has a SEPARATE `hidden` flag for deliberate suppression (predicate line: `if row.get("hidden"): continue`), so `discovered` was never meant as the runtime "hide it" lever. * The model's False default exists so FOG-OF-WAR SEEDS must opt in; the runtime path was simply missed when the field landed. Fix (additive, engine-only): * Add `discovered: bool = True` param to add_location. * Thread it into the NEW-Location constructor only. * UPDATE path (location_id reuse) is untouched → an existing place's discovered state is PRESERVED, never clobbered by the default. * Pass `discovered=False` to add a rumoured/far-off place that stays fog-of-war until visited (the deliberate path #371 enabled). * make_current=True still arrives the party (visited=True) → visible regardless, unchanged. Tests: servers/engine/tests/test_add_location_discovered.py (4) 1. default add_location → discovered=True AND visited=False (visible purely via discovered — the regression fix) 2. discovered=False → fog-of-war opt-in preserved 3. update path (location_id reuse) preserves discovered=False (no clobber) 4. make_current=True → visited=True + current (visible regardless) Verification: ast.parse clean on both files. Engine pytest left to CI (this checkout is not on the local test-execution allowlist). Scope: engine-only, additive. Does NOT touch PR #371, the viewer predicate, or any seed. Filed from an isolated worktree off origin/main (shared canonical checkout is used by parallel sessions). Refs: follow-up to #371 / #261; sibling to the #380 atlas-tier work. DO NOT MERGE yet (per owner — parallel agent still at work).
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe PR extends the ChangesLocation visibility discovery parameter
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Comment |
…laces stay on the Atlas (#261/#371 follow-up) (#650) PR #371 added `discovered: bool = False` to the Location model (fog-of-war seeds opt IN) but the runtime path `add_location` was never updated — so a place the DM names into the world mid-play serialized discovered=False and the Atlas hid it until the party visited it. Pre-#371 those places were visible. This threads a `discovered: bool = True` param into the new-Location constructor only (the update path preserves an existing place's discovered state), keeps deliberate fog-of-war expressible via discovered=False, and adds a 4-test regression suite. Closes #408. Co-authored-by: Eva <arncalso@gmail.com>
TL;DR
Reviewing an external suggestion, I verified a real regression the additive
discoveredfield (PR #371 / #261) introduced on the runtime path:add_locationnever setdiscovered, so a place the DM names into the world mid-play serializeddiscovered=Falseand the Atlas hid it until the party visited it. Pre-#371 those places were visible. This restores that withdiscovered: bool = Trueas the default, keeps deliberate fog-of-war expressible viadiscovered=False, and adds a 4-test regression suite.The bug (verified, file:line anchored)
servers/engine/models.py:828—Location.discovered: bool = False(added by fix(openworlds): atlas-seed — #261 #371 so fog-of-war seeds must opt in).servers/engine/server.py(add_location) — the new-Location constructor wasLocation(name=…, description=…, hex=coords, region=region, travel_times=tt)with nodiscovered=→ every runtime-added place serializeddiscovered=False.viewer/server.py:2241-2244(_atlas_visible_location_ids) — a place shows whenvisited OR discovered is True OR discovered is None;discovered is False and not visited→ hidden. Old snapshots (field absent →None) stay visible, so the regression bites only the runtimeadd_locationpath, where the model default makes it an explicitFalse.Net: a far-off / future-destination place the DM adds (without
make_current) is invisible on the Atlas until visited — a silent change from pre-#371 behavior.Why
discovered=Trueis the right default (not fog-of-war)seed_worldsets day-1 regionsdiscovered=Trueadd_location'd places were visiblehiddenflag (predicate line 2240) for deliberate suppressiondiscoveredwas never the runtime "hide it" leverFalsedefault exists so fog-of-war seeds opt inA place the DM names into the world mid-play is, by that act, known — the player should see it. Deliberate fog-of-war stays available via
discovered=False.The fix (additive, engine-only)
add_locationgains adiscovered: bool = Trueparam, threaded into the new-Location constructor only.location_idreuse) is untouched → an existing place'sdiscoveredis preserved, never clobbered by the default (so editing a hidden place's description doesn't reveal it).make_current=Truestill arrives the party (visited=True) → visible regardless; unchanged.discovered=Falserumour path + thehidden-vs-discovereddistinction.Tests —
servers/engine/tests/test_add_location_discovered.py(4)discovered=Trueandvisited=False(proves visibility comes from the flag, not a visit — the regression fix)discovered=False→ fog-of-war opt-in preserved (discovered/visitedboth False)location_idreuse, defaultdiscovered=True) → existingdiscovered=Falsepreserved, description updatedmake_current=True→visited=True+ becomescurrent_location_id(visible regardless)Verification:
ast.parseclean on both files. Engine pytest left to CI (this canonical checkout is not on the local test-execution allowlist; same approach as my prior engine PRs).Process notes
origin/main— the shared canonical checkout is used by parallel sessions, so no branch-op touched it.Collision audit
servers/engine/server.pyadd_locationregion is not in the main agent's current hot path (their recent work isviewer/+ the DM skill — skill(dm): force the engine combat loop when combat is warranted #404, fix(viewer): render chronicle narration exactly once, in order, via a stable key (#405) #407). Additive param + one constructor kwarg; the update path is untouched.DO NOT MERGE yet
Per owner — the parallel agent is still at work. Ready for review.
Provenance
External-AI suggestion ("Decide discovered= for runtime add_location"), independently verified against the tree before implementing. Follow-up to #371 / #261.
Summary by CodeRabbit
New Features