Day two: one character of punctuation, fifteen ruined renders

Six stills from one sequence: a lit control desk, a bearded man asleep in a flight chair, a hand resting on illuminated buttons, his face front-on, a wide shot of him standing at a window filled by a ringed planet, and a close-up of his eyes.

Day two · 9 August 2026 · sessions S-011 to S-017

Fifteen consecutive renders produced a bald, bearded man who was not our actor. I proposed three explanations for it. All three were wrong, and the real cause was one character of punctuation.

That was the end of the day. Before it, we made the project’s first real scene, discovered that a feature we had been writing prompts for does not exist, learned that camera references are charged by the second, and found the one free improvement that outperformed everything else we tried all week.

Sessions

7

Renders wasted on a stranger

15

Cause, in characters

1

Cuts landed within

3 frames

Cost of a 2nd reference

+78%

Continuity errors from bad syntax

0

First, the good part

A scene, not a collection of test shots

The day opened by finding work nobody had written down. The previous session had ended before logging its last hour, and six rendered shots plus an assembled cut were sitting on disk with no document referring to them.

They were recoverable, and the reason is worth knowing if you ever run this kind of pipeline unattended: the renderer embeds the complete recipe inside every video file it writes. Model, sampler, seeds, resolution, references, the full prompt text. So the settings below are exact rather than remembered.

The limit of that safety net

It recovers the settings, never the reasoning. A file can tell you the seed was 60003. It cannot tell you why that shot was 2.3 seconds long. Write down the thinking as you go; the machine handles the rest.

What they amounted to was SIGNAL: six independent renders sharing two references, covering an insert, a medium, a low insert, a close-up, a wide and an extreme close-up, at deliberately unequal lengths from 2.3 to 3.8 seconds. Assembled: 16.9 seconds. Identity, costume, set and lighting all held across all six.

SIGNAL, assembled — the first time this project produced something that behaves like a scene. Six separate renders, cut together. Listen to it: there is dialogue and there is room sound. What there is not, as we were about to discover, is music.

A feature that was not there

Three shots asked for a continuing string cue. There is no music at all

The open question had been whether a musical score generated independently in three consecutive shots would stitch across the cuts. It cost one playback to answer, and the answer dissolved the question: Gabe listened, and there is no music in any shot, including the three that asked for it.

The field exists in the schema and is simply inert when you run the open weights. The best explanation is the same preprocessing layer that handles prose in the hosted commercial service — it presumably services that field too, and locally there is no equivalent. So score became a post-production step, which is how films have always done it anyway.

The economics nobody warns you about

Reference images are not free capacity. They are a surcharge

The model accepts nine reference images, and after day one we knew several could be bound to a single character. It reads like a budget of nine. It is nothing of the kind, and this was the most practically useful measurement of the day.

What each extra reference costs Measured at both ends, on shots identical apart from reference count. 0 3.0 6.0 seconds per frame 1.88 1 reference the set only, no face 3.34–3.57 2 references set + one face ~5.6 3 references set + two faces +78–90% +64% THE RULE THAT FOLLOWS A shot with no character in it should carry the set reference and nothing else. Inserts are the cheapest tempo you can buy — and they hide an edit. Three independent measurements agreeing within half a percentage point · the nine-slot ceiling is nowhere near the real constraint
The curve is steep and it diminishes, which means the first face you add is the expensive one. Budgeting references by count rather than by render minutes will quietly double the length of a night’s work.

A methodological trap came with it, and it bit us later the same day. Adding a reference changes the conditioning, so an identical seed no longer reproduces the same framing. Two renders that differ in reference count are comparable on identity but not pixel-comparable. The seed stops being a control the moment references change.

The biggest free win of the week

How you write a shot controls when things happen in it

Gabe had a persistent complaint that was hard to pin down: the actor seemed to perform everything at once and then wait. It looked like haste. We turned it into a measurement, and it turned out to be exactly that.

Three framings, two prompt styles, everything else identical. The old style crams 54 to 59% of all motion into the first third of the clip, peaking around 0.67 seconds — the model does the whole action immediately and coasts. The rewritten style spreads the motion and moves the peak to 2.3–2.6 seconds of a three-second shot.

Where the movement happens in a three-second shot Same actor, same set, same length. Only the wording of the instruction changed. FIRST THIRD 0 s 1 s 2 s 3 s motion old style — peak 0.67 s 54–59% of all motion before 1 s rewritten — peak 2.3–2.6 s the action plays across the shot The change: describe a shot as a journey with a starting pose rather than a list of things that occur. Shots then begin in the pose they were told to begin in, instead of restarting the action from neutral.
A complaint about timing, turned into a number and then fixed by rewording. No extra render time, no extra references, no model change. It remains the largest effect measured on this project.

Cut placement turned out to be genuinely solved in the same stretch of work. You can write cuts inside a single render at stated timestamps, and they land: twelve cuts across two scenes, every one within three frames of where it was written. No systematic bias to compensate for — one batch ran slightly early, another slightly late, all inside 0.13 seconds. Identity, set and even the position of a raised hand survive across an internal cut.

But it is not cheaper, which was my assumption and was wrong. Cost per frame rises with clip length, so packing four angles into one long render costs more than four short ones — and forfeits the ability to re-roll a single angle you dislike. Use it when shots must match exactly, not by default.

Flow AA four-shot scene as one render, with the cuts written inside it.
Flow BIdentical but for one reference picture. The cuts are frame-identical to Flow A.
ANDROMEDA v1Eleven shots, 29 seconds. Eight cuts written, seven landed within two frames.
Three directing questions were answered here too, all of them Gabe’s. A real open mouth needs lower teeth and the edge of the tongue described. An emotional change needs writing as muscle movement with a duration, or the actor keeps the resting face from the reference photograph. And physical build belongs in the subject definition, where it reads through into wide shots.

The lesson that reframed the project

Six continuity failures, and not one was a prompt error

ANDROMEDA was the most ambitious thing built so far: a soldier in powered armour walks a corridor, enters a code, steps into an operations hall full of working crew, crosses to a window and speaks one line at the sight of the Andromeda galaxy. Three scenes, eleven shots, 29 seconds.

Gabe audited it and found six failures. A keypad on the door’s left in one scene, with the arm reaching from the other side in the next. Crew present in two scenes and absent in the third. A door behind him that vanished when he turned. A galaxy that drifted. An unrequested glow. Uncontrolled reflections.

None of them was a syntax error. They were all the same omission — no plan of the set existed.

Every prompt described what the camera saw. Nothing described where anything was. A model with no memory between renders cannot infer that the door is behind the actor unless that shot’s prompt says so, in that camera’s terms. We had been asking eleven separate strangers to describe the same room from memory.

The conclusion now governs the project: every shot needs its start and end position — arms, feet, face, gaze, contact — plus explicit spatial references for the set and the actors, a stated location for everything in the environment, and a per-character continuity record. All of it before a single prompt is written. That moves the work from writing prompts to planning a shoot and generating prompts from the plan.

So the set got a ground plan, in metres

The rebuild produced a continuity bible written in coordinates rather than adjectives. An origin at the centre of the door threshold, axes stated, every object’s position fixed — and, crucially, a camera map giving each shot’s position and the galaxy’s apparent position from that camera.

The set, as coordinates Origin at the centre of the door threshold · x starboard, y forward · every figure in metres OPERATIONS HALL · 24 m WIDE · y 0 → 18 the galaxy · x 0 · z 2.6 tilt, core and dust lanes all locked in text BANK A · y 6.5 5 stations BANK B · y 10.5 4 stations CORRIDOR y −24 → 0 origin (0, 0) — the door threshold keypad side is stated, so the reaching arm cannot swap R1 R2 R3 R4 the actor track: a position at the head and tail of every single shot at R4 he stands on the galaxy’s centre line — his skull must eclipse the core
The bible also carries an appearance lock: one canonical sentence per object, reused byte-for-byte in every prompt that shows it. Including the back of the armour — never photographed, and therefore reinvented on every render until it was frozen in words.

And then the bald stranger

One character of punctuation, fifteen ruined renders

Fifteen renders came back with a bald, bearded man in them. Not a drifting likeness — a different person entirely. I proposed three prompt-level explanations in turn. Each was plausible. Each was wrong.

"ref_images": { "ref_image_0": [...] }     ← silently ignored
"ref_images.ref_image_0": [...]            ← correct

The input is declared as a flat dotted key, and it is optional. Supply a nested object instead and nothing matches it, the value resolves to empty, and the renderer runs the prompt as pure text-to-video — with no error and no warning. Every reference we thought we were sending was being discarded. The model was inventing a man from the text description, and doing it consistently enough to look deliberate.

What caught it was not reading the code. It was a test that could not be argued with: run the same prompt twice with the reference resolution set differently, and compare the two outputs numerically. They were bit-identical. If changing a reference parameter changes nothing about the output, the references are not in the graph at all.

Fixed, the same prompt and seed produced the likeness immediately — and took 22.5 minutes instead of 13.

The render time was the tell all along. Those fifteen renders had been suspiciously fast, because they were doing less work than we thought. A cost we had no baseline for looked like good news. This is now the first section of the prompting playbook, ahead of everything else, because it invalidates every observation made underneath it.

The methodological lesson is larger than the bug. Earlier in the same session I had concluded that fewer references give a better likeness — by comparing two renders that used different prompts. Likeness varies more between prompts than between reference configurations, so that comparison measured nothing at all. It produced a confident, entirely false finding.

Hence the rule that now governs every comparison on this project: only same-seed, same-prompt arms are evidence. Applied properly to a controlled pair, the real answer emerged — two references do beat one, and the working budget is three or four in total, never five.

ANDROMEDA v2 — five renders, 994 frames, 41.4 seconds, one seed throughout, rebuilt from the ground plan with the references actually connected. Prompts were generated from a single source file and checked automatically before queueing: locked phrases byte-identical, cut timestamps inside the clip, every length on the model’s frame grid, every single-actor shot declaring who is not in frame.

One last thing from that checker, worth knowing if you build one. It cannot read for sense. A human pass afterwards still caught a shot allotting 3.25 seconds to a line that takes nearly three, a 1.5-second shot asked to contain both a door close and a smile, and two sentences mangled by string concatenation. Automated consistency and human reading catch different classes of error. Run both.


Next: the galaxy that was never mirrored.

Day three tests whether a set survives being seen from a new angle, finds out why one room never looked right in any shot, and produces the first genuine trade-off of the project — a choice between a picture that is beautiful and a picture that does what it was told.

Sources: docs/01_SESSION_LOG.md S-011 to S-017 · experiments E-008 to E-015 · research R-010, R-011 · decisions D-026 to D-031 · docs/BIBLE_andromeda.md, docs/09_CONTINUITY_AND_BLOCKING.md. Cut timings measured with scene detection; render times from the renderer’s own execution history.