Current state: {mainState}
; +} +``` + +This is better than reading the whole store, because the component re-renders only when `mainState` changes. + +## Updating Game State + +Prefer explicit actions from the store. + +```ts +const advanceGameState = useGameStore((state) => state.advanceGameState); + +advanceGameState(); +``` + +For development and debug tooling, direct setters also exist: + +```ts +const setMainState = useGameStore((state) => state.setMainState); + +setMainState("bike"); +``` + +Direct setters are useful for debug panels, but production gameplay should prefer business actions such as: + +- `advanceGameState` +- `completeBike` +- `completePylone` +- `completeFerme` +- `completeMission` + +Mission gameplay that can target `bike`, `pylone`, or `ferme` should prefer generic mission actions: + +```ts +const setMissionStep = useGameStore((state) => state.setMissionStep); +const completeMission = useGameStore((state) => state.completeMission); + +setMissionStep("bike", "inspected"); +completeMission("bike"); +``` + +This keeps reusable gameplay components such as `RepairGame` from duplicating mission-specific branches like `setBikeState`, `setPyloneState`, and `setFermeState`. + +## Settings Store + +`useSettingsStore` owns player-facing settings and forwards audio volume changes to `AudioManager`. + +State: + +- `isSettingsMenuOpen` +- `musicVolume` +- `sfxVolume` +- `dialogueVolume` +- `subtitlesEnabled` +- `subtitleLanguage` +- `repairRuntime` + +Audio setters clamp values between `0` and `1`, then call: + +```ts +AudioManager.getInstance().setCategoryVolume(category, nextVolume); +``` + +This keeps UI state and browser audio state synchronized. + +Current caveat: `repairRuntime` is stored and displayed in the settings menu, but the repair game does not consume it yet. Treat it as a staged architecture hook rather than an active runtime switch. + +## Subtitle Store + +`useSubtitleStore` is intentionally tiny. + +State/actions: + +- `activeSubtitle` +- `setActiveSubtitle` +- `clearActiveSubtitle` + +`playDialogueById()` writes to this store while dialogue audio plays. `Subtitles` reads from it and respects `useSettingsStore().subtitlesEnabled`. + +## World Integration + +`src/world/GameStageContent.tsx` subscribes to `mainState` and mounts the repair-game content. + +Current production repair placement: + +```tsx +Aucun dialogue synchronise avec cette cinematic.
+ ) : ( + (selectedCinematic.dialogueCues ?? []).map((cue, cueIndex) => ( +{status}
+{status}
+