feat: add InteractiveActionSource and playable browser game (Slice 17.5) - #80
Open
Jamerrone wants to merge 2 commits into
Open
feat: add InteractiveActionSource and playable browser game (Slice 17.5)#80Jamerrone wants to merge 2 commits into
Jamerrone wants to merge 2 commits into
Conversation
) Implement the playable browser game entry with full interactive UI alongside the existing transcript replay debugger, per the Slice 17.5 acceptance criteria. Key decisions: - InteractiveActionSource buffers PlayerActions pushed via DOM event handlers and drains them at the next BrowserDemoLoop tick boundary; exportTranscript() returns the recorded (tickIndex, action) pairs in TranscriptFile-compatible shape. - Two Vite MPA HTML entries: game at / (index.html + game.ts) and replay debugger at /replay (replay/index.html + replay/main.ts). One vite.config.ts handles both. - demos/game-data/ seeds from a verbatim copy of shared-data/ with the scenario's waveTrigger overridden to {"kind":"manual"} so the player controls wave timing. shared-data/ and its tests are entirely unaffected. - Vite plugin (renamed gameDataPlugin) emits both data.json (shared-data) and game-data.json (game-data) to dev server and production build; ADR-0021 already documented this two-bundle design. - game.ts implements: menu → scenario card → playing → win/loss overlay state machine; Idle/Build/Inspect interaction modes; tower palette with cost/affordability and armed-ghost cursor; Inspect panel with attack summary, sell button (refund computed from cost + purchased upgrade costs × refundPercent), TargetingStrategy dropdown (all 5 built-ins) with tag-priority sub-picker (up/down reorder + add/remove); tiered UpgradeTree cards with ○/✓/🔒 badges and locked-state tooltips; send-wave button (Send / spawning… / hidden after last wave); export-transcript download; 3-second failure toast for ActionResult failures. - Canvas overlays: tile tinting (Build: green/red via free-placement validation; Inspect on Guard Tower: per ADR-0011 rally eligibility within rallyPointRange); range circles (Build cursor, Inspect selected, hover Tower/Enemy/Guard); ghost tower in Build mode; rally overlays when Guard Tower is in Inspect (placement radius, engagement zone circles, rally point marker). - replay/main.ts updates the replay debugger with a source picker: default demo transcript or user-supplied .json via file input; both bundles fetched on load; scenario id resolved against whichever registry contains it. - package.json scripts flattened: dev/build/preview map directly to vite; *:browser namespacing removed; test:e2e replaces test:browser. - Headless vitest test (test/interactive-action-source.test.ts): 6 tests covering unit push/drain behaviour, transcript export shape, and an end-to-end run that places a Tower and sends a Wave against game-data via MaxSpeedClock. Files changed (12): demos/browser/action-source.ts: add InteractiveActionSource demos/browser/game.ts: new game entry (menu, game loop, interactive UI) demos/browser/index.html: new game HTML (replaces transcript replay at /) demos/browser/replay/index.html: replay HTML at /replay demos/browser/replay/main.ts: replay entry with file picker + dual-bundle resolve demos/game-data/: new content directory (14 JSON files; scenario uses manual waveTrigger) vite.config.ts: two-bundle plugin, MPA rollupOptions.input for both entries package.json: script flattening (dev/build/preview/demo:cli/test:e2e) playwright.config.ts: webServer.command updated to npm run preview test/browser/browser-demo.test.ts: navigate to /replay/?headless (replay route) test/interactive-action-source.test.ts: 6 new vitest unit + e2e tests Verification: 0 typecheck errors, kernel-purity clean, 414/414 unit tests pass (+6 new). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove unused AudioRenderer import in game.ts - Drop redundant `as HTMLElement` casts (palettePanel/inspectPanel are already HTMLElement after the non-null assertion) - Remove unused `registry` parameter from drawInspectOverlay and drawHoverOverlay; update call sites in drawOverlays - Flatten triple-nested if in drawHoverOverlay using optional chaining - Remove unused buildRegistry and TowersState imports in test file - Remove dead makeNullRenderer helper that was never called Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #56
Summary
Adds
InteractiveActionSourceso the tower-defense engine can accept real-time keyboard/mouse input, and wires it into a fully playable browser game at thedemos/browserentry point. A newdemos/game-data/directory holds all JSON content (maps, enemies, towers, waves, scenario, upgrades, difficulty) for the "Defend the Pass" scenario. A separate replay viewer entry (demos/browser/replay/) is also added for reviewing recorded game sessions.Test Plan
test/interactive-action-source.test.ts(143 lines) was added, covering the newInteractiveActionSourceclass.test/browser/browser-demo.test.tswas updated to reflect the revised multi-entry Vite config.