Merge branch 'develop' into feat/repair-game

This commit is contained in:
Tom Boullay
2026-05-11 17:31:14 +02:00
48 changed files with 5816 additions and 35 deletions
+43 -3
View File
@@ -44,8 +44,44 @@ Keep the player and map octree outside the Rapier provider until there is a deli
## Audio
- `src/managers/AudioManager.ts` currently provides pooled one-shot sound playback and looped music playback.
- Trigger interactions may play audio directly through `AudioManager`.
- `src/managers/AudioManager.ts` provides pooled one-shot playback, looped music playback, category volumes, and optional stereo pan for one-shot sounds.
- Supported audio categories are `music`, `sfx`, and `dialogue`.
- Trigger interactions may play SFX directly through `AudioManager`.
## Settings Menu
- `src/managers/stores/useSettingsStore.ts` stores settings for music volume, SFX volume, dialogue volume, subtitle visibility, subtitle language, repair runtime, and menu visibility.
- `src/components/ui/GameSettingsMenu.tsx` renders the in-game options menu.
- `src/components/ui/GameUI.tsx` mounts the settings menu as an HTML overlay outside the canvas.
- `Esc` opens and closes the menu, and `src/world/player/PlayerController.tsx` ignores player input while the menu is open.
- Volume changes are forwarded to `AudioManager` by category.
## Dialogues And Subtitles
- `public/sounds/dialogue/dialogues.json` is the runtime dialogue manifest.
- Dialogue audio files live under `public/sounds/dialogue/`.
- Subtitle files live under `public/sounds/dialogue/subtitles/{fr|en}/`.
- The current subtitle model is one SRT file per voice and language.
- `src/types/dialogues/dialogues.ts` contains the dialogue manifest types.
- `src/utils/dialogues/dialogueManifestValidation.ts` validates manifest shape at runtime.
- `src/utils/dialogues/loadDialogueManifest.ts` loads the manifest and SRT cues, with French fallback when the selected language is missing.
- `src/utils/subtitles/parseSrt.ts` parses SRT blocks and timecodes.
- `src/utils/dialogues/playDialogue.ts` plays dialogue audio and synchronizes the active subtitle against the audio element time.
- `src/managers/stores/useSubtitleStore.ts` stores the currently displayed subtitle cue.
- `src/components/ui/Subtitles.tsx` renders the subtitle overlay.
- `src/world/GameDialogues.tsx` currently triggers dialogue entries that define a `timecode`.
- Dialogue playback is queued so multiple dialogue requests do not overlap.
## Cinematics
- `public/cinematics.json` is the runtime cinematic manifest.
- `src/types/cinematics/cinematics.ts` contains cinematic manifest types.
- `src/utils/cinematics/cinematicManifestValidation.ts` validates manifest shape at runtime.
- `src/utils/cinematics/loadCinematicManifest.ts` loads `/cinematics.json`.
- `src/world/GameCinematics.tsx` triggers cinematics that define a global `timecode`.
- Cinematics use GSAP timelines to animate the active camera position and look target.
- `dialogueCues` on a cinematic trigger dialogue IDs at times relative to the cinematic start.
- `src/managers/stores/useGameStore.ts` exposes `isCinematicPlaying`, used to lock player input during cinematics.
## Debug System
@@ -74,6 +110,9 @@ Keep the player and map octree outside the Rapier provider until there is a deli
- `src/pages/editor/page.tsx` is the route-level editor page for `/editor`.
- `src/components/editor/EditorControls.tsx` renders the HTML editor control panel.
- `src/components/editor/EditorDialogueManifestPanel.tsx` edits `public/sounds/dialogue/dialogues.json`.
- `src/components/editor/EditorCinematicManifestPanel.tsx` edits `public/cinematics.json`.
- `src/components/editor/EditorSrtPanel.tsx` renders the dialogue SRT editor inside the editor control panel.
- `src/components/editor/scene/EditorScene.tsx` composes the editor canvas scene, camera controls, lights, shortcuts, and map rendering.
- `src/components/editor/scene/EditorMap.tsx` renders map nodes, fallback cubes, selection highlighting, and transform controls.
- `src/controls/editor/FlyController.tsx` provides player-style editor navigation.
@@ -97,6 +136,7 @@ Keep the player and map octree outside the Rapier provider until there is a deli
- The repository is a prototype, not the full intended game runtime.
- `src/world/debug/TestMap.tsx` is part of the active scene composition.
- There is no central gameplay orchestrator such as `GameManager`.
- The mission state exists in Zustand, but zones, cinematics, dialogue, and the full repair sequence are not implemented.
- Mission state exists in Zustand and the repair flow is implemented as a prototype for the current repair missions.
- Cinematics and dialogues exist as prototype timecode-driven systems; dialogue branching and broader gameplay orchestration are still limited.
- The player uses octree collision and simple movement rules, not a complete gameplay physics stack.
- Editor save-to-server is implemented as a Vite dev-server plugin, not a production backend API.
+90 -2
View File
@@ -23,6 +23,9 @@ src/
├── components/
│ └── editor/
│ ├── EditorControls.tsx
│ ├── EditorCinematicManifestPanel.tsx
│ ├── EditorDialogueManifestPanel.tsx
│ ├── EditorSrtPanel.tsx
│ └── scene/
│ ├── EditorMap.tsx
│ └── EditorScene.tsx
@@ -37,10 +40,14 @@ src/
│ └── editor/
│ └── editor.ts
└── utils/
├── dialogues/
│ └── loadDialogueManifest.ts
├── editor/
│ └── loadEditorScene.ts
── map/
└── loadMapSceneData.ts
── map/
└── loadMapSceneData.ts
└── subtitles/
└── parseSrt.ts
```
## Responsibilities
@@ -57,6 +64,12 @@ src/
`src/components/editor/EditorControls.tsx` renders the HTML control panel outside the canvas.
`src/components/editor/EditorDialogueManifestPanel.tsx` renders the dialogue manifest editor. It loads `dialogues.json`, edits dialogue entries, previews selected dialogue playback, creates missing French SRT cues, and saves the manifest through a dev-server endpoint.
`src/components/editor/EditorCinematicManifestPanel.tsx` renders the cinematic manifest editor. It loads `cinematics.json`, edits camera keyframes and dialogue cues, previews selected cinematics in the editor canvas, and saves the manifest through a dev-server endpoint.
`src/components/editor/EditorSrtPanel.tsx` renders the dialogue subtitle editor inside the control panel. It loads the dialogue manifest, loads one SRT file per voice/language, validates cue structure, previews dialogue audio, and can save SRT files through a dev-server endpoint.
`src/controls/editor/FlyController.tsx` provides editor movement controls for player-style navigation.
`src/utils/map/loadMapSceneData.ts` is shared by the game map and editor. It loads `/map.json` and resolves available `public/models/{name}/model.glb` files first, then falls back to `public/models/{name}/model.gltf`.
@@ -134,6 +147,78 @@ The editor supports two output paths:
The dev-only `/api/save-map` endpoint is implemented by the Vite plugin in `vite.config.ts`. It writes to `public/map.json` and enforces a maximum payload size.
## Dialogue SRT Editing
Dialogue subtitle editing is part of the `/editor` side panel.
Runtime dialogue files are grouped under `public/sounds/dialogue/`:
```txt
public/
└── sounds/
└── dialogue/
├── dialogues.json
└── subtitles/
├── fr/
│ ├── narrateur.srt
│ ├── fermier.srt
│ └── electricienne.srt
└── en/
└── ...
```
The current model is one SRT file per voice and language. A dialogue entry references the cue it needs through `subtitleCueIndex`; it does not own a dedicated SRT file.
`EditorSrtPanel` uses:
- `loadDialogueManifest()` to read `/sounds/dialogue/dialogues.json`
- `parseSrt()` to validate local textarea content and find active cues during audio preview
- `/api/save-srt` to write edited SRT files during local development
- `/api/validate-dialogues` to validate the manifest, linked audio, French SRT files, and referenced cue indexes
SRT timecodes are relative to the dialogue audio file being previewed, not to the global game timeline.
Missing English SRT files are warnings, not errors, because runtime loading falls back to French subtitles when the selected language is not available. Keep this behavior until the English translation workflow is ready.
## Dialogue Manifest Editing
`EditorDialogueManifestPanel` edits `public/sounds/dialogue/dialogues.json` in memory and persists it through `/api/save-dialogues`.
The panel supports:
- adding a dialogue entry
- deleting a dialogue entry
- editing `id`, `voice`, `audio`, `subtitleCueIndex`, and optional `timecode`
- previewing the selected dialogue through `playDialogueById()`
- creating a missing French SRT cue through `/api/save-srt`
When a dialogue is added, the editor computes the next `subtitleCueIndex` for the selected voice from the manifest. The generated SRT cue is a valid placeholder block and should be edited later in the SRT panel.
`/api/save-dialogues` is implemented in `vite.config.ts`. It validates manifest shape before writing to `public/sounds/dialogue/dialogues.json`.
## Cinematic Manifest Editing
`EditorCinematicManifestPanel` edits `public/cinematics.json` in memory and persists it through `/api/save-cinematics`.
The manifest shape is:
```ts
interface CinematicDefinition {
id: string;
timecode?: number;
cameraKeyframes: CinematicCameraKeyframe[];
dialogueCues?: CinematicDialogueCue[];
}
```
`cameraKeyframes` are relative to the cinematic start. At least two keyframes are required and keyframe times must increase.
`dialogueCues` are also relative to the cinematic start and reference dialogue IDs from `dialogues.json`. They are used by `GameCinematics` to synchronize dialogue playback with camera timelines. A dialogue synchronized this way should not also define a global `timecode` in `dialogues.json`.
The editor preview sends the selected `CinematicDefinition` to `EditorScene`, where GSAP animates the current editor camera. Orbit and fly controls are disabled during preview.
`/api/save-cinematics` is implemented in `vite.config.ts`. It validates manifest shape before writing to `public/cinematics.json`.
## Styling
Editor styles are in `src/index.css` under the `/* Editor page */` section. Classes are prefixed with `editor-` to avoid collisions with the game UI.
@@ -144,3 +229,6 @@ Editor styles are in `src/index.css` under the `/* Editor page */` section. Clas
- Large `map.json` files are not virtualized, culled, or LOD-managed.
- There is no snap-to-grid, duplication, material editing, or object creation workflow.
- Save to Server is a Vite dev-server helper, not a production backend API.
- SRT Save is also a Vite dev-server helper, not a production backend API.
- Dialogue and cinematic manifest saves are Vite dev-server helpers, not production backend APIs.
- Dialogue creation still uses placeholder audio paths until real MP3 files are added.