Part one taught arithmetic to fly a drone. This one brings the camera down to eye level — into the halls, onto the thrones, out to the gates — and then has to teach the judging what a wall is.
Same rule as part one: everything below this is machinery. These frames were composed from a save file's furniture — a camera standing in a doorway, sitting in a chair, posted up on a courtyard flagstone. No human framed any of them.
Part one ended with 1,411 photographs, all of them taken from the air: four bearings around each build, forty degrees up, far enough back to frame the whole box. Good photographs of buildings. But nobody who built these places ever saw them that way. They saw them from the hall floor, from the head of the table, from the gate coming home at night.
So the brief for this round was specific: the main room. The highest room with the biggest window. A chair, at a table. The main gate. The courtyard. And each of those through four skies — sunrise, sunset, a clear starry night, and a raging storm.
An orbit needs one fact per structure: its bounding box. An interior shot needs to know what a room is, and the box cannot say. But the save can. Every placed object in the world is a record with a position and a prefab id — every chair, every table, every gate hinge and every torch. The analytics cache had been storing them all along; nothing had ever asked.
One of part one's open items closed itself here. Prefab names used to be opaque hashes; a committed in-game dump of the prefab table now resolves 99.6% of 9.1 million objects to names at parse time. Once pieces have names, a vocabulary falls out: seats and tables, gates and doors, windows, fires, floors, roofs, walls. Group the floors into half-metre elevation bands and you have storeys. Grid the roof pieces and the cells with nothing overhead are courtyard candidates.
The plan file grew one column: mode=interior, a fourteenth field that
older builds of the plugin simply never read. Inside the game it changes two things.
The ground clamp — which keeps an orbit camera out of hillsides by forcing it
two metres up — relaxes to twenty centimetres, because two metres of "safety"
puts an indoor lens at the ceiling. And occlusion recovery turns off: outdoors it
climbs the camera out of foliage, indoors every rescue is a teleport through the
roof.
Then the receipts corrected the constants. The planner had assumed the lens rides 1.5 m above the player's feet; the receipts measured 1.8 m, frame after frame. Every standing camera in the pilot was composed three-tenths of a metre too high, which is the difference between a room and the underside of its ceiling joists. Assumed, then measured, then fixed — the same lesson part one learned about golden hour.
The first seated shots put the camera exactly at the chair's position. For plain chairs that worked. For thrones, the lens spawned inside the throne's own collider, and the engine's camera-collision resolved the disagreement by hurling the view seventeen metres into the air. The receipt is what caught it: the planner asked for a seat, the lens reported back from the sky.
{
"shot": "seat_storm", "mode": "interior", "clearance": "planned",
"planned": { x: ···, y: 41.99, z: ··· }, ← the seat of the throne
"placed": { x: ···, y: 41.99, z: ··· }, ← the engine agreed
"lens": { x: ···, y: 58.42, z: ··· }, ← the camera did not
"lens_offset_m": 17.106 ← supposed to be ~1.8
}
The fix is thirty-five centimetres: spawn the camera just forward of the backrest, toward whatever the seat faces. The first attempt at that fix overshot to seventy — and produced a macro photograph of the far edge of the table. Composition at half-metre scale is a different sport than composition at a hundred metres.
Two more corrections rode along. The rig now runs in god and ghost mode, set by reflection at the start of every shot — courtyards have wolves, and a death mid-plan costs a respawn wait and puts a freshly visible corpse-run character in frame, because the hide-player toggle binds to the body that died. The operator spotted that one live, watching a run: a pink-armoured figure photobombing a courtyard at dawn.
Part one measured golden hour and clamped every exterior frame into the band 0.33–0.77 of the day, because outside that band facades go dark. That rule is an exterior rule, and this round deliberately breaks it. A starry night is the whole point of a night shot; an interior carries its own hearth light. The night value did move once — 0.97 came back black even outdoors, 0.90 keeps the stars and the last of the sky — and storm stayed on the value the old manual sweeps had already proven.
The aesthetic model that ranks these frames was borrowed — a CLIP encoder and a small LAION head that were on the machine for an unrelated photo library. Indoors it faced new ways to fail, so the question was asked properly: is the borrowed scorer actually any good here?
Twelve pilot frames were labelled by hand — six keepers, six duds — and four scorers were benchmarked on all thirty-six keeper-versus-dud pairs.
| Scorer | Pairs right | |
|---|---|---|
| LAION aesthetic head (the incumbent) | 36 / 36 | kept — the borrowed scorer was never the problem |
| Same, HUD cropped out first | 35 / 36 | text in frame turns out not to matter at model resolution |
| CLIP zero-shot text probes | 35 / 36 | no better, and another thing to tune |
| 7B vision model, 1–10 rubric | — | see below |
The sharpest question in this round came from the operator, watching frames come in: is this image mostly a tree branch — or is the subject behind the branch, so the branch adds a layer of depth? That is not a taste question. It is a geometry question, and geometry can be measured.
Every frame now runs through a monocular depth model, and the depth map is asked the questions a photographer would ask: is there a visible background? Is something near-depth sitting across the eye-line, or hugging the frame edges as a framing device? How many distinct depth layers hold real pixels?
The plan was a three-layer bench: aesthetic to filter, depth to veto, and a local 7B vision model as the final judge, reading each frame against a rubric — does this feel like standing in the scene? The model ran. It returned its verdict on all eighty frames it was shown: 8.0. Every single time. Same number, near-identical sentence. Small vision models compress absolute scales into a single polite answer, and an instrument with one reading is not an instrument.
The honest fix is already known and not yet built: ask the model to compare two frames rather than rate one — pairwise verdicts survive scale compression — and give the job to bigger eyes. The judging column ships in the data today, labelled for what it is: a reason-generator with a constant attached.
One more thing changed shape here. The thresholds above stopped being constants in a script and became sliders: the whole bench now lives in a reactive notebook where the frames ride inside the sortable dataframe — reorder by any instrument and the pictures reorder with it. That idea arrived as a tip from a reader of part one. Wheels were not rebuilt.
published: false until a person promotes it. The instruments
shortlist; they do not consent on anyone's behalf. These are still other people's
houses — now including their living rooms.