06 — Cinematic Director
A non-linear timeline editor for camera paths, weather cues, NPC blocking, and storyboard scenes. Drive cameras with Bezier and spline interpolation. Export to MP4, WebM, GIF, or share as an interactive viewer. Replay any recorded simulation session as a cinematic.
1. Camera paths are part of the world
Camera paths are authored inside the world document (World.json#world.cameraPaths[])
so the same camera path can be used by:
- The Cinematic Director in the editor.
- Live sessions (GM plays a fly-through during a game).
- The Adventure Craft runtime (intro cutscene when players enter a zone).
- The mobile companion (preview videos).
The 3D engine never owns camera path state. It is a projection of World.json.
2. Camera path model
interface CameraPath {
id: string;
name: string;
kind: 'flythrough' | 'orbit' | 'follow_npc' | 'cutscene' | 'replay';
duration: number; // seconds (derived from last keyframe.t)
loop?: boolean;
easing: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'cubic-bezier';
keyframes: Array<CameraKeyframe>;
/** Optional Bezier handles (one per keyframe). */
handles?: Array<{ in: Vec3; out: Vec3 }>;
}
interface CameraKeyframe {
t: number; // seconds
position: Vec3;
lookAt?: Vec3;
fov?: number; // 10..120 degrees
roll?: number; // -180..180
aperture?: number; // depth of field, f-stop
focusDistance?: number; // metres
easing?: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'cubic-bezier';
holdFor?: number; // seconds to hold this keyframe before moving
}
lookAt and position together define an orientation. If only position is given,
the camera keeps its current orientation.
2.1 Path kinds
flythrough— free camera path.position+ optionallookAt.orbit— circles a target. Computed at runtime fromtarget + radius + theta.follow_npc— lockslookAtto a specific NPC.positioninterpolates between keyframes; the camera always looks at the NPC.cutscene— authored scene with dialogue, camera, and NPC blocking.replay— generated from a simulation log (see §7).
3. Timeline editor
+---------------------------------------------------------------+
| Path: "Show my kingdom" · 30s · loop |
+---------------------------------------------------------------+
| Tracks |
| ───────────────────────────────────────────── |
| 📷 Camera ●──────●─────●────────●──●──────● |
| 🌤️ Weather [storm] |
| 🌅 Lighting [sunrise→day→sunset→night] |
| 👥 NPCs [A: greet] [A: leave] |
| 💬 Dialogue "Welcome..." "Farewell." |
| 🎵 Music [ambient] [battle theme] |
| ⚡ Effects [lightning × 2] |
+---------------------------------------------------------------+
| 00:00 ●─── 00:10 ─── 00:20 ─── 00:30 ─── 00:40 ─── 00:50 |
| ▶ ⏸ ⏹ ⏮ ⏭ speed: 1× 2× 4× 8× |
+---------------------------------------------------------------+
Tracks:
- Camera — position + lookAt + FOV + roll + DOF keyframes.
- Weather — weather profile changes (e.g. "switch to storm at 0:25").
- Lighting — time of day changes (sunrise, sunset, night).
- NPCs — move / animate / speak keyframes.
- Dialogue — play a dialogue node.
- Music — play / stop / crossfade music tracks.
- Effects — particle bursts, lightning, magic FX.
Multiple paths can be sequenced on a higher-level Storyboard:
Scene 1: "Mountain view"
Scene 2: "Follow hero"
Scene 3: "Castle battle"
4. Interpolation
4.1 Linear
Default for most tracks. Cheap, predictable.
4.2 Cubic Bezier
Custom ease curve per keyframe. Bezier handles are visible on the timeline:
┌─ out handle
│
●───────●───────●
│
└─ in handle
The user drags handles; the editor previews the curve live.
4.3 Spline
Catmull-Rom interpolation through all keyframes. Produces smooth paths with minimal authoring. Good for fly-throughs.
4.4 Easing presets
ease-in— slow start, fast end.ease-out— fast start, slow end.ease-in-out— slow at both ends.cubic-bezier— custom.
5. Camera properties
5.1 Position & look-at
Vec3 in world-space metres. Snap to grid, snap to object, or free.
5.2 FOV
10..120 degrees. Lens presets:
14mm— extreme wide, fish-eye feel.24mm— wide.35mm— natural.50mm— standard.85mm— portrait.135mm— telephoto.
5.3 Roll
-180..180 degrees. Dutch angles, intentional disorientation.
5.4 Depth of field
aperture— f-stop (1.4 wide, 16 narrow).focusDistance— metres from camera.
Aperture and focus distance are animated together to enable rack focus effects.
5.5 Motion blur
Per-keyframe motionBlur flag enables Three.js post-processing during fast moves.
6. Recording & export
The Cinematic Director drives the 3D engine frame-by-frame and captures frames.
6.1 Export formats
| Format | Notes |
|---|---|
| MP4 | H.264 via WebCodecs API + ffmpeg.wasm fallback. |
| WebM | VP9, smaller files, slower encode. |
| GIF | For previews and social sharing; capped at 10 s. |
| Interactive viewer | A self-contained .html bundle that plays the path in the browser with no server. |
| .gas-cinematic | The world document + camera path + replay log; importable into another world. |
The Interactive Viewer is the killer feature: a creator ships a 5 MB HTML bundle that plays the cinematic in any browser, with no install, no server.
6.2 Export pipeline
Capture frames (WebGL canvas → PNG buffer)
│
▼
Encode (MP4 via WebCodecs / WebM via libwebm / GIF via gif.js)
│
▼
Optional: re-encode with ffmpeg.wasm for higher quality or different codec
│
▼
Write to file (download) or upload to GAS marketplace
6.3 Resolution presets
| Preset | Resolution | Notes |
|---|---|---|
480p | 854 × 480 | quick preview |
720p | 1280 × 720 | standard |
1080p | 1920 × 1080 | full HD |
4K | 3840 × 2160 | premium (Phase 4) |
vertical-1080 | 1080 × 1920 | TikTok / Reels |
square-1080 | 1080 × 1080 |
7. Replay-as-cinematic
Any recorded simulation session can be replayed as a cinematic.
const cinematic: CameraPath = {
id: 'replay_01H8X...',
name: 'Auto-replay of session 2026-07-29',
kind: 'replay',
source: 'gas://replay/session-2026-07-29@1.0.0',
keyframes: '/* derived from replay log */'
};
The replay system reads the simulation event log and synthesises camera moves:
- Cut to the player whenever an action is taken.
- Orbit the action whenever combat starts.
- Slow zoom on the NPC whenever dialogue begins.
- Match the GM's manual camera moves if GM mode was used.
Auto-replay is the cinematic equivalent of screen recording; perfect for sharing session highlights.
8. Sound design
The Director schedules audio cues on dedicated tracks:
- Music — crossfade between tracks at keyframe boundaries.
- Ambience — wind, water, fire, city — driven by weather profile.
- Voice — dialogue lines triggered by NPC blocking.
- SFX — footsteps, door open, sword clash.
All audio is GAS-packaged and licence-tracked.
9. Storyboard mode
The Director exposes a Storyboard view for high-level editing:
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Scene 1 │→ │ Scene 2 │→ │ Scene 3 │
│ Mountain │ │ Follow │ │ Castle │
│ view │ │ hero │ │ battle │
│ 30s │ │ 20s │ │ 45s │
└────────────┘ └────────────┘ └────────────┘
Each scene is a CameraPath. Drag to reorder. Click to edit. The Storyboard is the "movie editor" UI; the Timeline is the per-scene editor.
10. AI-assisted cinematography (Phase 7)
An AI assistant (Claude / GPT-class) can:
- Suggest camera moves from a high-level prompt:
- "Show my Viking kingdom" → flies above clouds, descends to the island, orbits the capital, zooms into the great hall.
- Generate storyboards from a prompt and a list of NPCs.
- Recommend music by mood.
The AI operates on the same World.json shape — it never invents data outside the
schema. Suggestions are inserted as drafts; the user can accept or reject.
11. Determinism & replay correctness
A camera path + a World.json + a Replay log produces byte-identical output
on every machine. This is required for:
- Sharing cinematics with identical visuals.
- Marketplace preview thumbnails.
- Test fixtures.
Procedural features use the deterministic RNG (§11 of
04-3d-world-engine.md).