# Editor User Guide

The map editor is available at `/editor`. It is a browser-based tool for editing the runtime map, cinematic manifest, dialogue manifest, and SRT subtitle files without manually jumping between JSON and subtitle files.

## Purpose

Use the editor when you need to:

- move, rotate, scale, add, or delete objects from `public/map.json`
- inspect the raw JSON generated by the editor
- preview and edit cinematics from `public/cinematics.json`
- create, preview, and validate dialogue entries from `public/sounds/dialogue/dialogues.json`
- edit FR/EN SRT subtitle files per voice

The map editor reads the same map data as the runtime scene:

- `public/map.json` contains the current hierarchical runtime map.
- `public/models/{name}/model.glb` contains the matching 3D model for each object name. `model.gltf` is still supported as a fallback during migration.
- Missing models are displayed as gray fallback cubes, so incomplete maps remain editable.

## Map Node Format

`public/map.json` is hierarchical. Group nodes such as `Scene`, `blocking`, `vegetation`, or `agriculture` organize the map. Editable object nodes still use the same transform fields:

| Field      | Description                                       |
| ---------- | ------------------------------------------------- |
| `name`     | Model folder name in `public/models/{name}`       |
| `type`     | Object category                                   |
| `position` | Object position as `[x, y, z]`                    |
| `rotation` | Object rotation as `[x, y, z]`, expressed radians |
| `scale`    | Object scale as `[x, y, z]`                       |

## Panel Layout

The right panel is split into dropdown groups:

- `Editor`: map transform tools, shortcuts, selection, view mode, JSON preview, and file actions.
- `Cinematics`: editor for `public/cinematics.json`.
- `Dialogues`: editor for `public/sounds/dialogue/dialogues.json`.
- `SRT`: editor for subtitle files in `public/sounds/dialogue/subtitles/`.

Only the `Editor` group is open by default. Open the other groups when you need audio or cinematic tooling.

## Map Editing Workflow

1. Open `/editor` in the local app.
2. Click an object in the scene to select it.
3. Use `Shift + right click` on other objects to add or remove them from the current multi-selection.
4. Choose a transform mode: translate, rotate, or scale.
5. Drag the transform gizmo in the 3D view. With multiple objects selected, the gizmo transforms the selected group and writes each object transform back to `map.json`.
6. Keep `Snap terrain on move` enabled when placing objects on the terrain.
7. Use `Center on object` or `Reset camera` from the `View` section when navigating large maps.
8. Adjust scale numerically from the `Selection` section if the gizmo is not precise enough.
9. Check the JSON inspector if you need exact values.
10. Use undo or redo if the transform is not correct.
11. Export the JSON or save it to the dev server.

## Adding And Deleting Nodes

Use `Add Node` to create a new editable object under the `blocking` group.

- The new object starts as a fallback cube at `[0, 0, 0]`.
- Name it with the model folder name you want, for example `maison1`.
- If `public/models/{name}/model.glb` or `model.gltf` exists, saving and reloading will display the matching model.
- If no matching model exists, the node stays editable as a gray cube.

Use the trash button in `Selection` to delete the selected node from the map tree.

## Controls

| Action               | Input                      |
| -------------------- | -------------------------- |
| Select object        | Click object               |
| Toggle multi-select  | `Shift` + right click      |
| Deselect             | `Esc` or click empty space |
| Lock selection       | `Lock` button in Selection |
| Clear selection      | `X` button in Selection    |
| Translate mode       | `T`                        |
| Rotate mode          | `R`                        |
| Scale mode           | `S`                        |
| Undo                 | `Ctrl+Z`                   |
| Redo                 | `Ctrl+Y`                   |
| Locked view movement | `WASD`, `ZQSD`, arrows     |
| Move up              | `Space`                    |
| Move down            | `Shift`                    |

## Selection

The `Selection` section shows the selected object name and its index in `public/map.json`.

- Click an object to select it.
- Use `Shift + right click` on objects to add or remove them from a multi-selection.
- When several objects are selected, the gizmo appears on the selection group and applies translate, rotate, or scale to each selected node.
- Click empty space or press `Esc` to clear the selection.
- Use the `X` button to clear the selection explicitly.
- Use the `Lock` button to protect the current selection while editing.
- Use the scale fields to edit X/Y/Z scale precisely.
- Use the trash button to remove the selected object.

## Terrain Snapping

`Snap terrain on move` is enabled by default. When you move an object, the editor samples the terrain height at the object's X/Z position and updates its Y position.

This is intended for map objects that should sit on the ground. Disable it when you intentionally need a floating object.

`Lock terrain` is also enabled by default. The terrain stays visible, but terrain clicks are ignored so normal objects remain easier to select. Disable it only when you need to select or transform the terrain node itself.

When selection is locked:

- clicking another object does not change the selection
- clicking empty space does not clear the selection
- pressing `Esc` does not clear the selection
- the `X` button still clears the selection intentionally

## View Mode

The `Lock view` action switches the editor into a movement mode closer to the runtime player camera. Use it to navigate larger scenes while keeping the transform tools available.

The camera action switches between `Center on object` and `Reset camera`. Selecting an object also focuses the camera on that object automatically.

## JSON Inspector

The `JSON` section shows the editable node data:

- When no object is selected, it shows the full map node list.
- When an object is selected, it highlights the JSON lines for that object.

Use it to verify exact numeric transform values before saving or exporting. The JSON inspector is read-only; transform values are changed through the gizmo in the scene.

## Saving Changes

### Export JSON

`Export JSON` downloads the current hierarchical map tree as `map.json`. Use this when you want to manually replace `public/map.json`.

### Save To Server

`Save to server` is available only during local development. It writes the edited hierarchical map back to `public/map.json` through the Vite dev-server endpoint.

The button is hidden in production builds because production persistence is not implemented.

## Editing Dialogue Subtitles

The side panel includes two separate audio text tools:

- `Dialogues` edits the dialogue manifest, which links dialogue IDs to audio files and SRT cue indexes.
- `SRT` edits the actual subtitle text and cue timings.

The important model is: one dialogue entry points to one cue inside one SRT file. The SRT file is grouped by voice and language, not by dialogue.

### Dialogue Manifest

Use the `Dialogues` panel to edit `public/sounds/dialogue/dialogues.json` without opening the JSON file manually.

Each dialogue entry contains:

| Field              | Meaning                                                           |
| ------------------ | ----------------------------------------------------------------- |
| `id`               | Unique dialogue ID used by cinematics and runtime triggers        |
| `voice`            | Voice file group: `narrateur`, `fermier`, or `electricienne`      |
| `audio`            | Runtime audio path, usually under `/sounds/dialogue/`             |
| `subtitleCueIndex` | Cue number inside the selected voice/language SRT file            |
| `timecode`         | Optional global runtime trigger time, in seconds from scene start |

Available actions:

- `Reload` reloads the manifest from disk.
- `Add` creates a local dialogue entry for the current voice and assigns the next available SRT cue index.
- `Save` writes the manifest through the local Vite dev server.
- `Preview dialogue` plays the selected dialogue and shows subtitles in the editor overlay.
- `Create FR SRT cue` creates the matching French SRT cue if it is missing.
- `Delete dialogue` removes the selected entry locally.

After using `Add`, save the manifest to keep the new dialogue entry. The generated SRT cue is written immediately to the French SRT file, but the dialogue manifest is still only local until `Save` is clicked.

New dialogue audio paths start as placeholders such as `/sounds/dialogue/new_dialogue_24.mp3`. Replace them with real MP3 paths before validating the final asset set.

Recommended workflow for a new dialogue:

1. Open `Dialogues`.
2. Click `Add`.
3. Choose the correct `voice`.
4. Replace the generated `id` with a readable stable ID.
5. Replace the placeholder `audio` path with the real MP3 path.
6. Check the generated `subtitleCueIndex`.
7. Click `Create FR SRT cue` if the cue does not exist yet.
8. Click `Save`.
9. Open `SRT`, edit the cue text and timings, then save the SRT file.
10. Run `Validate` from the SRT panel.

### SRT Editor

Use the `SRT` panel to edit one subtitle file at a time.

1. Choose a voice: `narrateur`, `fermier`, or `electricienne`.
2. Choose a language: `FR` or `EN`.
3. Edit the SRT text directly in the textarea.
4. Use the audio preview to check the selected dialogue.
5. Use `Set start`, `Set end`, `-100ms`, and `+100ms` to adjust the selected cue timing against the audio.
6. Use `Save SRT` during local development, or `Export SRT` to download the file manually.

Each SRT file belongs to one voice, not one dialogue. Cue indexes must match the `subtitleCueIndex` values referenced by the dialogue manifest.

SRT timings are relative to the dialogue audio file, not to the global game timeline and not to the cinematic timeline. For example, `00:00:01,000` means one second after that dialogue audio starts.

## Validating Dialogue Assets

Use `Validate` in the SRT panel to check the dialogue manifest and linked assets.

The validation checks:

- `public/sounds/dialogue/dialogues.json`
- referenced dialogue audio files
- French SRT files
- subtitle cue indexes referenced by the manifest

Missing English SRT files are warnings, not errors, because the runtime falls back to French subtitles. This is intentional until the English translation workflow is ready.

## Editing Cinematics

Use the `Cinematics` panel to edit `public/cinematics.json`.

Each cinematic contains:

- an `id`
- an optional global `timecode`
- two or more camera keyframes
- optional dialogue cues synchronized to the cinematic timeline

Camera keyframes define:

- `time`: seconds relative to the cinematic start
- `position`: camera position `[x, y, z]`
- `target`: point the camera looks at `[x, y, z]`

Dialogue cues define:

- `time`: seconds relative to the cinematic start
- `dialogueId`: an entry from `public/sounds/dialogue/dialogues.json`

Recommended workflow for a cinematic:

1. Open `Cinematics`.
2. Select an existing cinematic or click `Add`.
3. Set a stable `id`.
4. Add or adjust camera keyframes.
5. Keep keyframe `time` values increasing from start to end.
6. Add dialogue cues when a dialogue must start during the camera sequence.
7. Click `Preview cinematic` to test the camera path in the editor canvas.
8. Click `Save` when the manifest is correct.

Available actions:

- `Reload` reloads the cinematic manifest from disk.
- `Add` creates a new local cinematic with two camera keyframes.
- `Save` writes `public/cinematics.json` through the local Vite dev server.
- `Preview cinematic` plays the selected camera animation in the editor canvas.
- `Add keyframe` and `Remove` edit the camera path.
- `Add dialogue` and `Remove` edit dialogue cues linked to the cinematic.
- `Delete cinematic` removes the selected cinematic locally.

Cinematic dialogue cues are the preferred way to synchronize a dialogue with a cinematic. Avoid also giving the same dialogue a global `timecode`, or it can be triggered twice.

Use `dialogueCues` when the dialogue belongs to a cinematic. Use a dialogue `timecode` only for simple global scene timing outside a cinematic.

## Current Limitations

- The editor only modifies existing nodes.
- It does not create or delete objects.
- It does not edit model files or textures.
- It does not provide production persistence.
- Fallback cubes indicate missing models; they are editor placeholders, not exported assets.
- SRT saving is a local Vite dev-server helper, not a production backend feature.
- Dialogue and cinematic saves are local Vite dev-server helpers, not production backend features.
