American Revolution — an interactive documentary

Inspiration

Every painting of the Revolution is a lie of stillness. Leutze painted Washington Crossing the Delaware seventy-five years later, from Germany, and filled it with morning light — the real crossing happened at night, in sleet. Benjamin West's painting of the Treaty of Paris is famously half-blank because the British commissioners refused to sit. We grew up on frozen, mythologized images of these ten years, and suddenly the technology exists to un-freeze them — to stand on the wharf, pole the boat, hold the quill. We wanted to see if generative worlds could carry real history with a documentary's honesty instead of a game's fantasy.

What it does

Nine chapters, 1773–1783, in a browser. The design is built on a grammar of three "registers of presence": Witness (walkable gaussian-splat scenes — frozen moments, because splats are frozen, and that limitation feels like memory), Participant (live world-model sequences — steering a Durham boat through ice while a scripted storm arrives on schedule), and Actor (precise 3D interactions — you sign your real name on the Declaration as a 57th signer, and find it again ten years later, browned and aged, under museum glass). One rule governs everything: splats for reverence, world models for chaos, the engine for consequence.

How we built it

  • GPT Image 2 (via fal) generates the starting frames — one image conditions both generators, becoming the art bible for the whole piece.
  • World Labs Marble 1.1 Plus turns those frames into walkable splat worlds (rendered with Spark inside three.js), shipping collider meshes we raycast for ground.
  • Reactor / Lingbot World 2 runs the live scenes: WebRTC video at 1664×960, ~61 ms from input command to next generated chunk. Prompt hot-swapping mid-generation became our "scripted beats" system — the nor'easter hits at the 90-second mark no matter where you steer.
  • ElevenLabs (eleven_v3) voices a cast of four — a documentary narrator plus diegetic voices who shout the instructions, because our script rule says the narrator never tells you what to do.
  • The narration script itself is the data model: every line is a cue with an ID and a trigger (zone-enter, dwell, model-event), compiled straight into scene manifests. The engine doesn't know history; the script does.
  • Much of the build ran as autonomous AI agents working a GitHub issue board, governed by a committed decisions.md — binding creative rules (violence ceiling, embodiment-per-register, approval gates) so taste stayed human while execution parallelized.

Challenges

Making generative video behave like a scene was the hardest problem — world models want to wander, documentaries need beats to land. The answer was timed prompt-steering plus a "degrade, never break" ladder: live session → pre-rendered fallback → narration over black, same cues in all three. Splat worlds arrived in non-metric units with grounds that weren't where metadata implied; our alignment raycast once hit tree canopy 31 meters up and quietly buried the world. Automated code review caught brutal async races — a GPU session that kept billing after a failed connect, a rebase that silently deleted our own director. And the deepest challenge was editorial: writing narration where the record is genuinely unsettled ("No one knows who fired it. No one ever will") without hedging it into mush.

What we learned

Constraints are grammar: a splat's frozenness reads as memory, a world model's shimmer reads as adrenaline — match the medium's flaw to the moment's feeling and it stops being a flaw. Scripts can be compiled like code. Silence is a sound design tool. And autonomous agents can build remarkably fast — if the humans write down what they actually care about.

Built With

Share this project:

Updates