Skip to content
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e780835
feat(ui): integrate Neurotoxic Overworld HTML design
DaFum Apr 25, 2026
4ff02f4
fix(ui): apply glitch button and fix layout feedback
DaFum Apr 25, 2026
e9e957c
fix: Node tests, GlitchButton conversion, React UI bugs, and HUD/Radio
DaFum Apr 25, 2026
ba9d091
test(ui): fix overworld tests and replace skip with implementation
DaFum Apr 25, 2026
4bedb09
feat(overworld): integrate new overworld design
DaFum Apr 25, 2026
978fd83
fix(overworld): address PR review comments for UI, CSS, and i18n
DaFum Apr 25, 2026
bf64288
fix(overworld): resolve review comments for class mismatches, i18n, o…
DaFum Apr 25, 2026
5420a03
fix(css): lower z-index of crt, scan, and noise overlays
DaFum Apr 25, 2026
ffe45f0
fix(tests): resolve failing Overworld.test.jsx syntax error
DaFum Apr 25, 2026
4ed2067
fix(overworld): resolve code review comments on HUD types, animation …
DaFum Apr 25, 2026
d1d6f53
fix(overworld): prevent reference error for undefined van props in me…
DaFum Apr 25, 2026
1c52078
fix(overworld): add missing translation keys for EventLog
DaFum Apr 25, 2026
38f5dea
fix(overworld): clean up unused components, memory leaks, and duplica…
DaFum Apr 25, 2026
13bd280
fix(overworld): resolve React Rules of Hooks violations and condition…
DaFum Apr 25, 2026
3126f9c
fix(overworld): resolve code review comments and layout fixes
DaFum Apr 25, 2026
32d4b2a
fix(overworld): finalize translation structure and conditional CRT ef…
DaFum Apr 25, 2026
221e451
fix: remove duplicate overworld mute controls
DaFum Apr 25, 2026
d90fca1
fix: make overworld log/menu updates concurrency-safe
DaFum Apr 25, 2026
0ee0778
fix: restore overworld keyboard shortcuts handlers
DaFum Apr 25, 2026
c53c499
fix: align overworld menu setter typing with usage
DaFum Apr 25, 2026
b6106ae
fix: resolve remaining overworld review findings
DaFum Apr 25, 2026
0dfca54
fix: address overworld menu and event log review follow-ups
DaFum Apr 25, 2026
621871c
style: run prettier on src
DaFum Apr 25, 2026
6221010
fix: resolve remaining overworld and typing review findings
DaFum Apr 25, 2026
5dec2ae
fix: remove unreachable blood bank modal wiring
DaFum Apr 25, 2026
693d10f
feat: restore reachable blood bank flow in overworld
DaFum Apr 25, 2026
11d8d6a
fix: align overworld menu options with legacy actions
DaFum Apr 25, 2026
ac79da5
docs: add distinct gotchas across all AGENTS files
DaFum Apr 25, 2026
6b20c78
fix: address remaining overworld review findings
DaFum Apr 25, 2026
e53ef58
Merge pull request #1389 from DaFum/codex/fix-timeout-not-cleared-on-…
DaFum Apr 25, 2026
f67ef35
Update src/ui/overworld/OverworldHUD.tsx
DaFum Apr 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,32 @@ jobs:
- name: Ensure no new @ts-nocheck debt in src
run: pnpm run guard:nocheck

typecheck:
name: Typecheck
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: ${{ env.PNPM_VERSION }}

- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: '22.13.0'
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts

- name: Run TypeScript checks
run: pnpm run typecheck

locale-smoke-tests:
name: Locale Smoke Tests
runs-on: ubuntu-latest
Expand Down
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,7 @@
- `.cjs` extension is required for ad-hoc Node scripts that use `require()`.
- Use `process.env.VITE_VAR` for env vars needing Vite/node:test dual compatibility.
- Pollinations API key is safe to publish.

## Recent Findings (2026-04)

- Overworld regressions often come from action reachability; when refactoring grouped menus, explicitly preserve every legacy entry point or remove the backing hook in the same patch.
1,146 changes: 0 additions & 1,146 deletions Neurotoxic Overworld.html

This file was deleted.

4 changes: 4 additions & 0 deletions api/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ Applies to `api/**`.
- Treat request bodies and query params as `unknown` at the route boundary, then narrow with explicit validators before use.
- Keep API response shapes stable during type migrations; when a payload contract changes, update client consumers and API tests in the same PR.
- Avoid widening handler-local data to `Record<string, any>`; prefer concrete interfaces or `Record<string, unknown>` with narrowing.

## Recent Findings (2026-04)

- Avoid backend endpoint additions for features that are not reachable in current UI flows; dead client paths create misleading API surface expectations.
4 changes: 4 additions & 0 deletions api/leaderboard/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ Applies to `api/leaderboard/**`.

- Song IDs may require canonical mapping before submission; avoid trusting raw client IDs.
- Maintain deterministic error payloads so tests and clients can branch predictably.

## Recent Findings (2026-04)

- Leaderboard submissions should stay decoupled from Overworld menu organization; UI nav changes must not affect song ID resolution or submit payload shape.
84 changes: 63 additions & 21 deletions public/locales/de/ui.json
Original file line number Diff line number Diff line change
Expand Up @@ -507,10 +507,6 @@
"member": {
"unknown": "Unbekannt"
},
"menu.close": "MENÜ SCHLIEßEN",
"menu.inventory": "INVENTAR",
"menu.open": "MENÜ",
"menu.upgrades": "UPGRADES",
"merch_press.button": "MERCH-PRESSE",
"merch_press.confirm": "PRESSE STARTEN",
"merch_press.cost_label": "KOSTEN",
Expand Down Expand Up @@ -602,22 +598,6 @@
"no_save_found": "Kein Speicherstand gefunden!",
"nowPlaying": "Spielt jetzt: {{name}}",
"overload.toxic": "TOXISCHER OVERLOAD",
"overworld.band_hq_button": "BAND HQ",
"overworld.event_log": "EREIGNISPROTOKOLL:",
"overworld.header.tourPlan": "TOURPLAN",
"overworld.location_secured": "{{location}} gesichert.",
"overworld.locations_loaded": "Locations geladen: {{count}}",
"overworld.radio_station": "FM 66.6",
"overworld.refuel": "AUFTANKEN",
"overworld.repair": "REPARIEREN",
"overworld.save_game": "SPIEL SPEICHERN",
"overworld.status.nextStop": "Nächster Halt",
"overworld.status.onRoad": "Unterwegs",
"overworld.status.selectLocation": "Markierte Location auswählen",
"overworld.status.traveling": "UNTERWEGS...",
"overworld.tour_active": "{{date}}: Tour aktiv.",
"overworld.traveling_van": "Reisevan",
"overworld.void_clinic_button": "LEEREN-KLINIK",
"pirate_radio.button": "PIRATENSENDER",
"pirate_radio.controversy_gain": "KONTROVERSE",
"pirate_radio.cooldown": "IM ABKLINGEN",
Expand Down Expand Up @@ -985,5 +965,67 @@
"unit.km": "km",
"unlocked": "FREIGESCHALTET: {{unlock}}!",
"visual_interface": "VISUELLE SCHNITTSTELLE",
"volume.set": "Lautstärke auf {{pct}}% setzen"
"volume.set": "Lautstärke auf {{pct}}% setzen",
"menu": {
"management": "MANAGEMENT",
"hq_desc": "Band & Gear verwalten",
"quests_desc": "Aktive Ziele",
"stash_desc": "Schmuggelware & Inventar",
"side_hustles": "NEBENJOBS",
"radio_desc": "Ruf verbessern",
"merch_desc": "Bootlegs drucken",
"darkweb_desc": "Neue Tracks leaken",
"logistics": "LOGISTIK",
"refuel_desc": "Van volltanken",
"repair_desc": "Schäden reparieren",
"bloodbank_desc": "Blut gegen Bargeld tauschen",
"clinic_desc": "Mitglieder heilen",
"system": "SYSTEM",
"save_desc": "Fortschritt speichern",
"options_count": "optionen",
"actions": "AKTIONEN",
"back_to_actions": "ZURÜCK ZU AKTIONEN",
"close": "MENÜ SCHLIESSEN",
"open": "MENÜ ÖFFNEN",
"options_count_upper": "OPTIONEN",
"options_count_lower": "optionen",
"inventory": "INVENTAR",
"upgrades": "UPGRADES"
},
"overworld": {
"shortcuts": {
"help": "Hilfe umschalten",
"mute": "Stumm / Laut",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor: inconsistent German translation for the same shortcut concept.

overworld.shortcuts.mute is "Stumm / Laut" while the existing shortcuts.mute (line 798) in this same file is "Stumm / Ton an" for the same toggle concept. Either is grammatical, but the duplicated pair is semantically equivalent and should read the same to avoid drift between the global shortcuts overlay and the overworld-specific list.

🌐 Suggested fix
-      "mute": "Stumm / Laut",
+      "mute": "Stumm / Ton an",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"mute": "Stumm / Laut",
"mute": "Stumm / Ton an",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@public/locales/de/ui.json` at line 998, Normalize the German phrasing for the
mute toggle by making overworld.shortcuts.mute match the existing shortcuts.mute
wording; update the value of overworld.shortcuts.mute (the
"overworld.shortcuts.mute" key) to the same string used by "shortcuts.mute"
("Stumm / Ton an") so both shortcut lists use identical, consistent text.

"event": "Event-Option wählen",
"hit_notes": "Noten treffen (Gig)",
"close": "Overlays schließen"
},
"low_fuel": "WENIG BENZIN",
"keyboard_shortcuts": "Tastenkürzel",
"band_status": "Band Status",
"harmony": "Harmonie",
"radio_station": "FM 66.6",
"event_log_entries": "einträge",
"event_log_entries_one": "eintrag",
"event_log_entries_other": "einträge",
"locations_loaded": "Tour initialisiert. {{count}} Locations geladen.",
"tour_active": "{{date}}: Tour aktiv.",
"location_secured": "{{location}} gesichert.",
"event_log": "EVENT LOG",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 German locale lost translation for overworld.event_log — shows English 'EVENT LOG' instead of German

The restructured German locale file replaces the translated value "EREIGNISPROTOKOLL:" with the English string "EVENT LOG" for the overworld.event_log key. This means German-language users will see English text in the Event Log header.

Old vs new German locale values

Old flat key: "overworld.event_log": "EREIGNISPROTOKOLL:"

New nested key: "overworld": { "event_log": "EVENT LOG" }

The English locale correctly has "EVENT LOG", but the German locale should retain a German translation (e.g. "EREIGNISPROTOKOLL" or "EVENTPROTOKOLL").

This violates the AGENTS.md rule: "I18n: Update both public/locales/en/*.json and public/locales/de/*.json in the same change" — while both files were updated, the German value regressed to English.

Suggested change
"event_log": "EVENT LOG",
"event_log": "EREIGNISPROTOKOLL",
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

"header": {
"tourPlan": "TOURPLAN"
},
"status": {
"traveling": "REISEN...",
"nextStop": "Nächster Halt",
"onRoad": "UNTERWEGS",
"selectLocation": "WÄHLE EINEN ORT"
},
"band_hq_button": "BAND HQ",
"refuel": "TANKEN",
"repair": "REPARIEREN",
"void_clinic_button": "VOID CLINIC",
"save_game": "SPIEL SPEICHERN",
"traveling_van": "Reisevan"
}
Comment thread
DaFum marked this conversation as resolved.
}
84 changes: 63 additions & 21 deletions public/locales/en/ui.json
Original file line number Diff line number Diff line change
Expand Up @@ -507,10 +507,6 @@
"member": {
"unknown": "Unknown"
},
"menu.close": "CLOSE MENU",
"menu.inventory": "INVENTORY",
"menu.open": "MENU",
"menu.upgrades": "UPGRADES",
"merch_press.button": "MERCH PRESS",
"merch_press.confirm": "START PRESS",
"merch_press.cost_label": "COST",
Expand Down Expand Up @@ -602,22 +598,6 @@
"no_save_found": "No save game found!",
"nowPlaying": "Now Playing: {{name}}",
"overload.toxic": "TOXIC OVERLOAD",
"overworld.band_hq_button": "BAND HQ",
"overworld.event_log": "EVENT LOG:",
"overworld.header.tourPlan": "TOUR PLAN",
"overworld.location_secured": "{{location}} secured.",
"overworld.locations_loaded": "Locations loaded: {{count}}",
"overworld.radio_station": "FM 66.6",
"overworld.refuel": "REFUEL",
"overworld.repair": "REPAIR",
"overworld.save_game": "SAVE GAME",
"overworld.status.nextStop": "Next Stop",
"overworld.status.onRoad": "On the road",
"overworld.status.selectLocation": "Select a highlighted location",
"overworld.status.traveling": "TRAVELING...",
"overworld.tour_active": "{{date}}: Tour active.",
"overworld.traveling_van": "Traveling Van",
"overworld.void_clinic_button": "VOID CLINIC",
"pirate_radio.button": "PIRATE RADIO",
"pirate_radio.controversy_gain": "CONTROVERSY",
"pirate_radio.cooldown": "ON COOLDOWN",
Expand Down Expand Up @@ -985,5 +965,67 @@
"unit.km": "km",
"unlocked": "UNLOCKED: {{unlock}}!",
"visual_interface": "VISUAL INTERFACE",
"volume.set": "Set volume to {{pct}}%"
"volume.set": "Set volume to {{pct}}%",
"menu": {
"management": "MANAGEMENT",
"hq_desc": "Manage members & gear",
"quests_desc": "Active objectives",
"stash_desc": "Contraband & inventory",
"side_hustles": "SIDE HUSTLES",
"radio_desc": "Boost reputation",
"merch_desc": "Print bootlegs",
"darkweb_desc": "Leak new tracks",
"logistics": "LOGISTICS",
"refuel_desc": "Gas up the van",
"repair_desc": "Fix van damage",
"bloodbank_desc": "Trade blood for cash",
"clinic_desc": "Heal members",
"system": "SYSTEM",
"save_desc": "Record progress",
"options_count": "options",
"actions": "ACTIONS",
"back_to_actions": "BACK TO ACTIONS",
"close": "CLOSE MENU",
"open": "OPEN MENU",
"options_count_upper": "OPTIONS",
"options_count_lower": "options",
"inventory": "INVENTORY",
"upgrades": "UPGRADES"
},
"overworld": {
"shortcuts": {
"help": "Toggle Help",
"mute": "Mute / Unmute",
"event": "Select Event Option",
"hit_notes": "Hit Notes (Gig)",
"close": "Close Overlays"
},
"low_fuel": "LOW FUEL",
"keyboard_shortcuts": "Keyboard Shortcuts",
"band_status": "Band Status",
"harmony": "Harmony",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"radio_station": "FM 66.6",
"event_log_entries": "entries",
"event_log_entries_one": "entry",
"event_log_entries_other": "entries",
"locations_loaded": "Tour initialized. {{count}} locations loaded.",
"tour_active": "{{date}}: Tour active.",
"location_secured": "{{location}} secured.",
"event_log": "EVENT LOG",
"header": {
"tourPlan": "TOUR PLAN"
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"status": {
"traveling": "TRAVELING...",
"nextStop": "Next Stop",
"onRoad": "ON THE ROAD",
"selectLocation": "SELECT A LOCATION"
},
"band_hq_button": "BAND HQ",
"refuel": "REFUEL",
"repair": "REPAIR",
"void_clinic_button": "VOID CLINIC",
"save_game": "SAVE GAME",
"traveling_van": "Traveling Van"
}
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
}
4 changes: 4 additions & 0 deletions src/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ Applies to everything under `src/` unless a deeper `AGENTS.md` overrides it.

- `useArrivalLogic` owns arrival routing and scene transitions after travel completion.
- Minigame hooks (`useTourbusLogic`, `useRoadieLogic`) must stay reactive-only (no direct PIXI imports).

## Recent Findings (2026-04)

- Theme-token migrations should be completed per file: if one module switches to RGB token variables, finish all remaining literal color usages in that module before merging.
3 changes: 2 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const SCENES_WITHOUT_HUD: Set<GamePhase> = new Set([
GAME_PHASES.SETTINGS,
GAME_PHASES.CREDITS,
GAME_PHASES.GAMEOVER,
GAME_PHASES.OVERWORLD,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Global HUD suppression for Overworld is intentional but broad

Adding GAME_PHASES.OVERWORLD to SCENES_WITHOUT_HUD at src/App.tsx:24 suppresses the global HUD (which includes money, fuel, van condition, band status, audio controls, and keyboard shortcuts). The new OverworldHUD component (src/ui/overworld/OverworldHUD.tsx) re-implements most of this functionality with the overworld-specific CSS styling. This is a significant behavioral surface area change — any features the global HUD provides that OverworldHUD doesn't (e.g., certain tooltip interactions, accessibility patterns from src/ui/HUD.tsx) will be lost in the Overworld scene. Verified that key features (money display, fuel/condition bars, band member status, harmony bar, keyboard shortcuts) are all present in the new component.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

GAME_PHASES.TRAVEL_MINIGAME,
GAME_PHASES.PRE_GIG_MINIGAME,
GAME_PHASES.CLINIC
Expand Down Expand Up @@ -99,7 +100,7 @@ function GameContent() {
<div className='crt-overlay pointer-events-none fixed inset-0 z-(--z-crt) mix-blend-overlay opacity-50' />
)}

{/* Hide HUD in Intro/Menu/Settings/Credits/GameOver */}
{/* Hide global HUD in scenes that provide their own overlays or no HUD UI. */}
{!SCENES_WITHOUT_HUD.has(currentScene) && <HUD />}

<ToastOverlay />
Expand Down
4 changes: 4 additions & 0 deletions src/assets/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ Applies to `src/assets/**`.
- Keep asset metadata interfaces narrow and explicit; avoid loosely typed loader payloads.
- If asset key/path conventions change, update typed import maps and all consuming loaders/tests together.
- Prefer additive metadata fields over repurposing existing keys to preserve backward compatibility with save fixtures and tests.

## Recent Findings (2026-04)

- Keep generated image prompts stable for map pins/icons during UI refactors; changing prompt keys can break perceived continuity even when paths still resolve.
4 changes: 4 additions & 0 deletions src/components/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ Applies to `src/components/**`.
- Keep component prop interfaces and runtime `propTypes` optional/required flags synchronized.
- For reusable components, export explicit prop types and avoid `any` passthrough props.
- When a prop accepts external/untrusted objects, type as `unknown` at the boundary and narrow before access.

## Recent Findings (2026-04)

- For categorized action menus, keep a one-to-one mapping between action unions and rendered items to prevent unreachable handlers hiding in lookup maps.
9 changes: 5 additions & 4 deletions src/components/PixiStageController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
import { NoteManager } from './stage/NoteManager'
import { getGigTimeMs } from '../utils/audioEngine'
import { withTimeout } from './stage/utils'
import type { StageControllerOptions } from '../types/components'
import type { RhythmGameRefState } from '../types/rhythmGame'

/**
* Manages Pixi.js stage lifecycle and rendering updates.
*/
class PixiStageController extends BaseStageController {

// Getters and Setters for backward compatibility with existing tests
get colorMatrix() {
return this.toxicFilterManager?.colorMatrix ?? null
Expand Down Expand Up @@ -96,14 +97,14 @@
*/
_initManagersAndStartLoading() {
// Initialize Managers and start loading assets in parallel
this.crowdManager = new CrowdManager(this.app, this.stageContainer)

Check failure on line 100 in src/components/PixiStageController.ts

View workflow job for this annotation

GitHub Actions / Typecheck

Argument of type 'Application<Renderer> | null' is not assignable to parameter of type 'Application<Renderer>'.
const crowdLoad = withTimeout(
this.crowdManager.loadAssets(),
'Crowd Assets'
)

this.laneManager = new LaneManager(
this.app,

Check failure on line 107 in src/components/PixiStageController.ts

View workflow job for this annotation

GitHub Actions / Typecheck

Argument of type 'Application<Renderer> | null' is not assignable to parameter of type 'Application<Renderer>'.
this.stageContainer,
this.gameStateRef
)
Expand All @@ -113,14 +114,14 @@
// LaneManager owns the rhythm container.
const rhythmContainer = this.laneManager.container

this.effectManager = new EffectManager(this.app, rhythmContainer)

Check failure on line 117 in src/components/PixiStageController.ts

View workflow job for this annotation

GitHub Actions / Typecheck

Argument of type 'Application<Renderer> | null' is not assignable to parameter of type 'Application<Renderer>'.
const effectLoad = withTimeout(
this.effectManager.loadAssets(),
'Effect Assets'
)

this.noteManager = new NoteManager(
this.app,

Check failure on line 124 in src/components/PixiStageController.ts

View workflow job for this annotation

GitHub Actions / Typecheck

Argument of type 'Application<Renderer> | null' is not assignable to parameter of type 'Application<Renderer>'.
rhythmContainer,
this.gameStateRef,
(x: any, y: any, color: any) =>
Expand Down Expand Up @@ -150,7 +151,7 @@
*/
manualUpdate(deltaMS: number) {
if (!this.app || this.isDisposed) return
this.handleTicker({ deltaMS })

Check failure on line 154 in src/components/PixiStageController.ts

View workflow job for this annotation

GitHub Actions / Typecheck

Argument of type '{ deltaMS: number; }' is not assignable to parameter of type 'Ticker'.
}

/**
Expand All @@ -165,18 +166,18 @@

const state = this.gameStateRef?.current

if (!state || state.isGameOver) {

Check failure on line 169 in src/components/PixiStageController.ts

View workflow job for this annotation

GitHub Actions / Typecheck

Property 'isGameOver' does not exist on type '{}'.
return
}

const elapsed = getGigTimeMs()

this.toxicFilterManager.update(state, elapsed, this.stageContainer)

Check failure on line 175 in src/components/PixiStageController.ts

View workflow job for this annotation

GitHub Actions / Typecheck

Object is possibly 'null'.

this.laneManager.update(state)
this.crowdManager.update(
state.combo ?? 0,

Check failure on line 179 in src/components/PixiStageController.ts

View workflow job for this annotation

GitHub Actions / Typecheck

Property 'combo' does not exist on type '{}'.
state.isToxicMode ?? false,

Check failure on line 180 in src/components/PixiStageController.ts

View workflow job for this annotation

GitHub Actions / Typecheck

Property 'isToxicMode' does not exist on type '{}'.
elapsed
)
this.noteManager.update(state, elapsed, this.laneManager.layout)
Expand All @@ -202,7 +203,6 @@
)
}


/**
* Disposes Pixi resources and removes the canvas.
* @returns {void}
Expand Down Expand Up @@ -235,5 +235,6 @@
* @param {object} params - Controller dependencies.
* @returns {PixiStageController} Controller instance.
*/
export const createPixiStageController = (params: import("../types/components").StageControllerOptions<import("../types/rhythmGame").RhythmGameRefState>) =>
new PixiStageController(params)
export const createPixiStageController = (
params: StageControllerOptions<RhythmGameRefState>
) => new PixiStageController(params)
4 changes: 4 additions & 0 deletions src/components/minigames/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ Applies to `src/components/minigames/**`.
- Do not import PIXI into logic-only hooks; scene/frame components should consume prepared logic objects.
- Completion overlays should use provided completion state instead of recomputing reducer data.
- Arrival routing is owned by `useArrivalLogic`: components/controllers must dispatch completion results (completion action/event) and let shared arrival routing + scene transition logic run there.

## Recent Findings (2026-04)

- Overworld menu refactors must not alter minigame launch contracts; launch actions should remain routed through scene/hooks, not direct component side effects.
Loading
Loading