Skip to content

W-024: demo-dnd live entity/trait devtools panel (DND-F10)

Type: feature · Size: S · Epic: E-dnd-m1 · Target: apps/demo-dnd · Breaking: no Depends: W-019, W-020, W-021, W-023, W-044, W-047, W-050, W-051 Refs: demo-dnd brief §5 (DND-F10); demo-dnd spec DND-100..109, acceptance A5 and A6; ecs-devtools spec DEVTOOLS-001..005, DEVTOOLS-014, DEVTOOLS-033, DEVTOOLS-051, DEVTOOLS-056..058, DEVTOOLS-062, DEVTOOLS-064, DEVTOOLS-065, DEVTOOLS-072, DEVTOOLS-080..082, L9, L11; W-044; W-047

Goal

Mount <WorldInspector /> in apps/demo-dnd with a host-owned open and close control. Call registerNames for the demo traits and relations and setEntityLabel from Name. Run acceptance A5 and A6 of the demo-dnd spec (DND-108, DND-109), which set the item to accept.

Steps

  • S1 (DND-100, DND-101; DEVTOOLS-001, DEVTOOLS-002, DEVTOOLS-004, DEVTOOLS-005, DEVTOOLS-014): add an exported registerDndNames(world) that calls registerNames with the 13 traits and the HasEffect relation under their export names, and call it once for the app world at module load. setupEncounter calls setEntityLabel(world, e => e.get(Name)?.value). Headless tests: getName returns each name, also after restartEncounter and after a repeated registerDndNames; combatants and Poisoned are labelled by Name, and a HasEffect pair's targetLabel is "Poisoned". files: apps/demo-dnd/src/ecs/world.ts, apps/demo-dnd/src/ecs/actions.ts, apps/demo-dnd/src/ecs/devtools.test.ts
  • S2 (DND-102, DND-103, DND-104, DND-105, DND-106, DND-107; DEVTOOLS-033, DEVTOOLS-051, DEVTOOLS-056, DEVTOOLS-057, DEVTOOLS-058, DEVTOOLS-065, DEVTOOLS-072, DEVTOOLS-080, DEVTOOLS-081, DEVTOOLS-082, L9, L11): add src/ui/devtools/ with a "Devtools" Button/Toggle (aria-pressed) and the mounted <WorldInspector /> in a side column (min 320 px). App.tsx owns open (closed by default) and a restart counter used as the inspector's React key. The game-area key handler maps I to the toggle and keeps the existing key rule (DND-016). The inspector gets the injected schedule and timer through options. Component tests with a real world in WorldProvider, one it per ID: toggle via button and I mounts and unmounts the panel; fresh encounter lists heroes, monsters, and Poisoned with badges, no templates, plus one template per kind with "Show excluded"; usePoison, ticks, and defeat update the Pairs row, Health text, and Defeated badge without panel input; restart with a selection shows only new combatants and "Select an entity"; the seeded scripted fight (DND-033) ends with the same state and log with the panel open and closed; the listed game keys in the panel or on a button call no game action and are not preventDefaulted, and Enter on "End turn" calls endTurn once. No change to packages/ecs-*. files: apps/demo-dnd/src/ui/devtools/devtools-panel.tsx, apps/demo-dnd/src/App.tsx, apps/demo-dnd/src/ui/input/*, apps/demo-dnd/src/ui/devtools/devtools-panel.test.tsx
  • S3 (acceptance; DND-108, DND-109; DEVTOOLS-062, DEVTOOLS-064): run the demo-dnd spec's acceptance items A5 (panel beside the game at 1280×720, both themes) and A6 (60 FPS with the panel open during a full monster round) in pnpm --filter demo-dnd dev

Log

  • 2026-11-01 Depends W-025 replaced by W-047 (F04); W-025 split and dropped (Triage)
  • 2026-11-01 demo-dnd spec approved (W-013 done). Acceptance moved from ecs-devtools A1..A3 to demo-dnd A5 and A6 (Triage). Refs extended to DND-100..109 and the DEVTOOLS IDs listed above
  • 2026-11-01 open deps, not done: W-019 (Depends) and W-047 (Depends). W-044 (name registry, needed by DND-100) is not in Depends; Triage to decide whether to add it
  • 2026-11-01 spec defaults applied: OQ7 (devtools panel is read-only, DND-108); OQ9 (Poisoned entity visible, see W-023)
  • 2026-11-01 Depends completed, steps handed to Planner (Triage)
  • 2026-11-01 steps defined: 3 steps; open: Depends not done on the board and missing W-020..W-023, restart key source (Planner)
  • 2026-11-01 Depends extended (Triage) from DND-100..109: DND-100 names PoisonStrike (W-023) and HasEffect (W-020). DND-103..106 need the setup (W-019), the turn and defeat flow (W-020, W-021), and usePoison, the ticks and the Poisoned entity (W-023). DND-107 tests A, Escape, Tab, Enter (W-021, W-051), P (W-023), and E and R (W-050), so those handlers must exist. W-022 is not needed: no DND-100..109 requirement depends on monster AI.
  • 2026-11-01 Correction (Triage): the earlier "Depends completed" line only meant the Depends list was completed, not that the dependencies are done. Stays in Later until every Depends item is done.
  • 2026-11-01 held: waits on the OQ6 decision after the W-039 S1 spike (decision logged in W-039 first) (Triage)