Campaign scenes and choices
Between missions a campaign can show three kinds of screen. They are built and shown on sample data today; real campaigns will fill them from their nodes.
Scenes
A scene is a conversation or an interlude. The place is named at the top left, the speakers stand on both sides (up to two a side), and the line is typed out in a box at the bottom with the speaker's name plate above it.
- Space, Enter or a click finishes the line being typed, then goes to the next one.
- Esc or Skip scene jumps to the end of the scene.
- L or the language chip cycles the subtitles: English, German, Japanese. A line without a translation shows in English and carries an EN chip.
- A VOICE chip marks a line that has a recorded voice (the cue is stored; playback comes with the audio pass).
- Speakers are portrait slots for 2D character art: the author names a PNG per person; until it exists a tinted bust stands in.
Choices
A decision is a calm page with no timer: the question, two to four answers as large cards, and a line saying the decision is permanent. Press 1 to 4 or click. An answer whose condition is not met stays visible but greyed, with the reason in red ("Needs Edda alive").
Party roster
The heroes that arrive at the next chapter: portrait, class, level, experience, abilities with their levels, six item sockets, and what was lost in red words. A fallen hero stays on the page, dimmed.
In the editor's command palette (Ctrl+K): Campaign scene (sample), Campaign choice (sample), Party roster (sample), Cycle subtitle language.
Depth, design (planned)
A scene is a stack of layers, far to near: background, mid ground, characters, foreground (leaves, mist, dust). Each layer carries a depth z; the page moves a layer by z times the pointer's offset from the centre (small, eased, springy) plus a slow idle drift, so the picture lives without input. Everything is transforms on pooled nodes: no per-frame allocation, and nothing runs while no scene is open.
Characters breathe and bob a little, tilt toward the pointer, and have a rim light and a soft contact shadow so a flat portrait sits in the scene. The speaker steps forward in depth (larger, lit); the others dim and sit slightly back. Entrances and exits slide along the depth curve.
Depth of field: far layers are softly blurred and the near foreground more; this blur is intentional (the named design), and the focused layer is perfectly crisp. Light: god rays, a vignette, a colour grade per mood and a bloom on lamps. The camera moves per beat (slow push-in, pan) and these are data in the scene file, not code.
Reduce motion switches the parallax and drift off and shows the still image. Until art exists, placeholder layers (stacked gradients and silhouettes) show the effect so the mechanics can be tested.
Alternatives considered for the motion model: (1) per-layer offset by pointer (chosen: cheap, readable); (2) a real 3D camera with billboards (more correct, costs a depth pass, and the art is flat anyway); (3) gyro-style tilt only (needs a device sensor, nothing on desktop); (4) scripted camera only, no pointer (calm but dead on a static line); (5) video loops per scene (heavy, not data driven). Chosen: (1) plus data-driven camera moves from (4).
Depth, built (2026-11-06)
The depth above is in: layered placeholder scene, pointer parallax, idle drift, camera beats per line, the speaker stepping forward, breathing and lean, soft far and near layers, rays, grade and vignette, and reduce motion as a still image. Not yet: a true blur of imported art (it needs a render pass), and camera beats in the campaign file.
Layered art for a scene (the pipeline, planned)
A map author gives a scene real art by dropping files in a folder, with no code. One folder per scene, next to the campaign file: scenes/<scene id>/, holding PNGs with transparency and a scene.toml:
# scenes/salt_gate/scene.toml
mood = "dusk" # grade: dusk, dawn, night, day, storm
[[layer]]
file = "sky.png"
depth = 0.0 # 0 far, 1 near; the characters stand at 0.55
[[layer]]
file = "harbour.png"
depth = 0.3
[[layer]]
file = "leaves.png"
depth = 0.9 # near layers are drawn soft on purpose
[[beat]] # a camera beat, by line number (from 0)
line = 1
push = 0.03
pan = -0.012
secs = 5.0Rules: layers are drawn far to near, the characters between the layers below and above 0.55; a layer is at least the window's size plus 12 per cent so a shift never shows an edge (draw it 4800 by 2700 for a 4K window); a missing file or no scene.toml falls back to the placeholder silhouettes. A character's art is a PNG on the cast entry (the portrait slot today). Depth of field is applied by the engine, not painted into the files: draw every layer sharp.