You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Combat becomes a MODE of the stage, not a separate screen: a fight starts from where everyone is standing and ends back at rest — plus day/night lighting live from the campaign clock.
Design (verified seams)
start_combat (server.py:4039) gains an additive param seeding combatant cells from stage_cell (absent ⇒ today's spawn behavior). end_combat (server.py:6976) writes survivors' cells back to stage_cell. Gates-read-gauges holds: combat READS stage at entry, WRITES only at exit.
Combat grid and scene grid MUST be the same grid (dimensions/cells) — verify at seed time or the gate below fails by construction.
EVAL — the NO-TELEPORT gate
Scripted full loop (explore→talk→fight→loot→move-on): combat entry cells == last rest cells; exit cells == combat end cells; no actor jumps. Text-tier byte-identity.
Risks tracked
Mid-combat cross_door/travel (refuse or resolve — decide in-sprint with a test either way); foes lacking spawn keys (fallback cells).
[HIGH] Mid-combat cross_door/travel RULING: REFUSED while combat.active — the engine rejects with a clear error (mirroring existing combat-gated verbs); no mid-fight room transition in W4 scope. A fleeing-through-the-door mechanic is a future issue, not this epic.
[HIGH] Grid-mismatch RULING: the start_combat stage-seeding param activates ONLY when the location's scene_grid dimensions match the combat grid (verify at seed time); on mismatch → today's spawn behavior (additive default), log a WARN-level line. Legacy campaigns therefore degrade gracefully.
[HIGH] Foes lacking spawn placements: seed from the foes spawn bucket first, overflow per W1's ruling (zone_anchors id-sorted then party-adjacent vacant cells, round-robin) — never fail the combat start over placement.
[MED] EVAL instrument named: (a) deterministic engine test — a scripted explore→start_combat→end_combat sequence asserting entry cells == prior stage_cells and exit cells == combat-end cells (the NO-TELEPORT gate, servers/engine/tests/); (b) ONE box render pair (rest frame + combat frame, same scene) as visual evidence. The blind-playtest loop eval belongs to W5, not W4.
Roadmap §4b/W4 (PR #1316). Depends: W1-W3; coordinate with S8 (demo assembly).
What
Combat becomes a MODE of the stage, not a separate screen: a fight starts from where everyone is standing and ends back at rest — plus day/night lighting live from the campaign clock.
Design (verified seams)
start_combat(server.py:4039) gains an additive param seeding combatant cells fromstage_cell(absent ⇒ today's spawn behavior).end_combat(server.py:6976) writes survivors' cells back to stage_cell. Gates-read-gauges holds: combat READS stage at entry, WRITES only at exit.EVAL — the NO-TELEPORT gate
Scripted full loop (explore→talk→fight→loot→move-on): combat entry cells == last rest cells; exit cells == combat end cells; no actor jumps. Text-tier byte-identity.
Risks tracked
Mid-combat cross_door/travel (refuse or resolve — decide in-sprint with a test either way); foes lacking spawn keys (fallback cells).
ADDENDA — takeover review (2026-07-03, architect-ratified)
[HIGH] Mid-combat cross_door/travel RULING: REFUSED while combat.active — the engine rejects with a clear error (mirroring existing combat-gated verbs); no mid-fight room transition in W4 scope. A fleeing-through-the-door mechanic is a future issue, not this epic.
[HIGH] Grid-mismatch RULING: the start_combat stage-seeding param activates ONLY when the location's scene_grid dimensions match the combat grid (verify at seed time); on mismatch → today's spawn behavior (additive default), log a WARN-level line. Legacy campaigns therefore degrade gracefully.
[HIGH] Foes lacking spawn placements: seed from the foes spawn bucket first, overflow per W1's ruling (zone_anchors id-sorted then party-adjacent vacant cells, round-robin) — never fail the combat start over placement.
[MED] EVAL instrument named: (a) deterministic engine test — a scripted explore→start_combat→end_combat sequence asserting entry cells == prior stage_cells and exit cells == combat-end cells (the NO-TELEPORT gate, servers/engine/tests/); (b) ONE box render pair (rest frame + combat frame, same scene) as visual evidence. The blind-playtest loop eval belongs to W5, not W4.
[HIGH] Depends on: [EPIC][W1] Scene at Rest — party + NPCs rendered in the room outside combat #1318 (stage_cell) + [EPIC][W2] Walk — within-room movement outside combat (walk_to + click-to-move + glide) #1319 (walk_to writes stage_cell)