Fix capture flow + bulletproof telemetry handler + add ControllerNavigator
ClaudeDemoController.Start coroutine rewrite — capture wasn't loading
ClaudeDemoController.Start coroutine rewrite — capture wasn’t loading the Combat scene or initializing an encounter. Sequence asset specifies sceneToLoad: “Combat” but the controller never honored it; ScriptedInputs fired into a null CombatManager. Now:
- Resolve weapon class by name from GameFlowManager.weaponClasses
- GameState.StartNewRun(weaponClass, difficulty) sets up PlayerState
- ApplySequenceRunState overrides the deck / gear / health
- Resolve enemies from EnemyDatabase by name; stage on GameFlowManager.currentEncounterEnemies
- SceneManager.LoadScene(“Combat”) — bypassing SceneTransitioner so we don’t get fade overlays in captured footage
- Wait until CombatManager.Instance != null AND phase == PlayerTurn before activating ScriptedInputProvider (max 8s with clean exit on timeout)
- Camera + UI tweaks AFTER scene loads (so main camera is combat cam)
- Recorder + scripted inputs start last
ControllerNavigator — new MonoBehaviour at Assets/Scripts/UI/ that layers controller input over the existing pointer-driven combat UI. Unity Input System (already installed via com.unity.inputsystem) reads Gamepad.current; controller events synthesize calls to existing PlayCardFromHand / EndPlayerTurn / ChangeStance entry points so gameplay logic is untouched.
Bindings: L1 / R1 — cycle cards in hand A — play selected card (or confirm target) B — cancel targeting Y — end turn D-pad up/right/left — Front/Mid/Back stance D-pad in targeting — cycle alive enemies Start — open Escape menu
Input mode (Mouse vs. Controller) auto-detected: any gamepad input switches to Controller mode + shows focus rings; mouse movement
3px switches back to Mouse mode + hides rings. Mouse players see no overlap with the existing pointer code.
Focus rings built from 4 thin Image-based borders (no shader, no sprite atlas dependency). Cyan ring on cards; red ring on enemies during targeting. Parented to the target’s RectTransform so they follow card animations.
CombatUIManager exposes IReadOnlyList
CombatSceneBuilder.Start spawns ControllerNavigator after combat inits in both code paths (mid-run + standalone test).
Telemetry stats handler — bulletproof error path. Root cause of the “Unexpected token ’<’” dashboard error: aeRes.json() on an HTML body threw, the catch block tried aeRes.text() which ALSO threw because the body had already been consumed, and the function crashed. Fixed:
- Wrap entire handler in top-level try/catch returning JSON
- Read body as text FIRST (single read), then JSON.parse the string
- 404 / “table does not exist” responses are caught explicitly and returned as { data: [], notice: ‘dataset_empty’ } status 200, so the dashboard renders “No data yet” cleanly until events flow
- Every failure path returns a structured JSON object with data: [] so the dashboard’s r.json() never throws
Co-Authored-By: Claude Opus 4.7 (1M context) [email protected]
Commit 775ed43 by astafford8488.