Same prompt, two engineers:
Fable and Opus build the same DOOM
Both got the identical brief — a mobile-portrait DOOM-style raycaster, gpt-image-2 wall panels + enemies, "make it look good." Both wrote a from-scratch software raycaster in TypeScript, no engine. Clean rooms, zero shared code. Then we went part by part through what each one chose. The same fork shows up at every layer.
what you actually see


part 1 — floors & ceilings
Fable wins. Opus didn't skip floors — it drew them the cheap way, as two flat gradients, so the ground reads as a featureless dark void. Fable cast a real textured, perspective-correct floor.
// per screen row, project the world-space
// ground point and sample a floor texture
for (let y = 0; y < VIEW_H; y++) {
const isFloor = y > horizon;
const rowDist = halfH / (isFloor ? y-horizon : horizon-y);
const shade = this.fog(rowDist) * (isFloor?1:0.62);
// ...sample floorTex per pixel across the row
}this.ceil = ctx.createLinearGradient(0,0,0,half);
this.ceil.addColorStop(0, `rgb(${CEIL_RGB})`);
this.ceil.addColorStop(1, `rgb(${FOG})`);
this.floor = ctx.createLinearGradient(0,half,0,H);
// ...filled as 2 solid bands. no texture, no perspective.Why this fork?
Textured floor-casting is the single fiddliest, most break-prone piece of a raycaster — ~30 lines of perspective math that's easy to get subtly wrong. The gradient is 4 lines and cannot break. Opus made a risk-aversion trade: take the robust-but-plain win. Fable spent the complexity for the ground texture. Remember this trade — it repeats.
part 2 — wall texturing
Fable wins on sharpness. Both run the identical ray math. The split is the final draw: Fable writes texels by hand into a pixel buffer (crisp). Opus slices a 1px column and lets the browser stretch it (soft/blurry).
for (let y = y0; y < y1; y++) {
const px = tpx[ty*tw + texX]; // nearest texel
let r=(px&255)*shade, g=..., b=...; // fog × pixel
u32[y*VIEW_W + x] = 0xff000000|(b<<16)|(g<<8)|r;
}drawImage stretches a 1px slice shortcutctx.drawImage(tex, texX,0,1,tex.height, x,start,1,lineH);
// browser bilinear-stretches the 1px column
// vertically → soft, slightly blurred wallspart 3 — fog & distance
Fable wins. Fable folds fog into the pixel's own color — true darkening that keeps contrast. Opus paints a semi-transparent fog-colored rectangle on top, which uniformly washes distant detail toward flat black. That overlay is exactly the "muddy" look.
let shade = this.fog(perpDist) * boost
* jitter[cell] * zoneLight[cell]; // + light zones
r = texel_r * shade; // darkens the real colorconst fog = Math.exp(-dist * FOG_DENSITY);
ctx.fillStyle = `rgba(${FOG},${1-b})`;
ctx.fillRect(x, start, 1, lineH); // veil over the wallpart 4 — lighting
Fable wins. Fable gives each cell its own animated light zone — broken-ballast flicker, hell-pulse, dim — updated every frame. Opus uses one global light scalar times a static per-cell hash. One breathes; one is uniform.
private zoneLight: Float32Array; // one per cell
// each frame: pulse / flicker / dim modes + muzzle boost
if (z.mode==='flicker') /* harsh broken-ballast */
if (z.mode==='pulse') /* slow hell breathing */function cellBright(x,y){ /* static hash jitter */ }
let b = fog * sideShade * cellBright(mx,my) * light;
// `light` is a single number for the whole scenepart 5 — doors
Fable wins. Fable modeled real Wolf3D-style sliding doors right inside the ray loop — the ray hits the door plane at the cell midline and slides it into the jamb. Opus's loop has no door case at all: every solid cell is just a wall.
if (cell===DOOR) {
const dMid = side===0 ? sideX-deltaX*.5 : sideY-deltaY*.5;
let u = hitCoord - Math.floor(hitCoord);
u -= open; // door slides into the jamb
if (u >= 0) { tex = door; break; }
}if (tile > 0) break; // every solid cell = a plain wall.
// no midline, no slide, no door texture branch.part 6 — the enemy fused to the gun
Opus shipped IRONMAW with a demon glued on top of the gun. Its QA never caught it — and here's the twist: it wasn't a code bug at all. The fix came only when Opus was told to record combat video and read the frames.


Why the first QA missed it
Opus verified combat numerically — fire, then check the __game.enemies counter dropped. ✅ passes. But a counter is blind to where a sprite is drawn. Fable, on the same kind of fast-state problem, had escalated on its own: "timing's against me — let me record video and pull frames with ffmpeg." It watched combat in motion. The bug that's invisible to a number is obvious in a frame.
part 7 — how each tested itself
Fable wins — and this is the deepest split. Both had ffmpeg + Playwright sitting right there. Fable reached for video; Opus reached for assertions.
// 8 self-play bot runs · 5 ffmpeg calls · video frames
"Timing luck is against me — let me record a
video instead and pull frames with ffmpeg."
// → looks at combat IN MOTION// e2e: "shoot → enemy drops, no console errors"
expect(__game.enemies).toBeLessThan(before); // ✅
// verifies combat WORKS, never that it LOOKS rightthe pattern
Read down the list — it's the same decision every time
Floors: textured cast vs flat gradient. Walls: hand-written pixels vs browser stretch. Fog: multiplied-in vs painted-on. Lighting: animated zones vs one scalar. Doors: modeled vs skipped. QA: video vs counter. Fable eats complexity for the look at every fork; Opus takes the robust shortcut at every fork. That's why Fable's renderer is 485 lines and Opus's is 215 — and why one looks like DOOM and the other looks like a tech demo. The knowledge is identical. The taste isn't.
SO WHAT'S SCAFFOLDABLE?
When we forced Opus to do the video loop it skipped — record combat, read frames — its screenshot-reads jumped 7 → 46, it out-verified Fable, and it caught the gun bug with a sharper diagnosis than any human review. The diligence was 100% scaffoldable.
But on the parts that need taste from a blank page — should the floor be textured? should fog darken or veil? is that material "painted metal" or "brown cardboard"? — no scaffold closed the gap. Opus could see its materials were wrong (it scored them 4/10) and still couldn't make them right.
The clean line: a harness can make any model see its own bugs. It can't make it generate beauty. Catch is scaffoldable. Create is intrinsic. That's where the moat is.
the fusion experiment — can two blind Opus beat one?
The page above ends on a wall: create is intrinsic. So we tested the most-hyped way around it. OpenRouter just shipped "Fusion" (Fable-tier answers from cheaper models); an open-source clone runs two Opus 4.8 on the same task, blind to each other, then a third Opus reads both and writes the final — "one run can be confidently wrong; two, cross-examined, can't hide it." We ran exactly that on the Opus DOOM: two blind builders each pushed the same v2 toward HULLROT with video QA, then an Opus judge fused them into v3. Clean rooms, a blindness watchdog, every score checked against the reference by eye.
part 8 — the five frames, side by side
Same corridor, same vantage. Watch the floor tone and the walls as you read left to right — the two blind builds each fixed a different thing and broke a different thing.
part 9 — where fusion earned its keep
Fusion genuinely beat both single runs — for the precise reason the trick predicts. The two blind builders converged where it mattered and diverged where it counted.
The cross-examination moment
The sharpest play wasn't a merge — it was a rejection. Builder A scored its own glow-orbs a 7/10 and shipped them, confidently wrong. Builder B, blind to A, simply never built them. The judge, holding both against the reference, used B's clean build as evidence that A's confident feature was a regression — and dropped A's entire glow path. Then it took B's walls+lighting, swapped in A's warm floor, grafted A's lit gun. Result: v3 has B's muted walls AND A's warm floor — the one frame that has neither build's wart. That's "two cross-examined can't hide it," and the screenshots confirm it.
part 10 — what fusion could NOT do
Now look at v3 against HULLROT again. v3 is the cleanest Opus frame — but it's still not in the same room as Fable, and the reason is the whole point.
The judge said it itself
Its own verdict file: "Fusion was worth it precisely because the failures were complementary rather than shared — had both builds made the same mistake, fusion would have inherited it." That's the law of this trick. It is a disagreement engine: it amplifies the cases where one run caught what another missed. It is powerless over the cases where every run is wrong the same way — which is exactly where taste from a blank page lives.
SO WHERE DOES FUSION SIT?
Fusion is real, and it worked: v3 (~8.4) cleanly beat both single runs (~6.8 and ~7.5) by taking the right half of each and rejecting one builder's confident mistake using the other as a witness. On the build axis, two-blind-plus-judge genuinely lifts quality — for free of any new model.
But it lifts the same axis the rest of this page already named. Fusion is a catch mechanism: cross-examination catches divergent errors. It is not a create mechanism: it produced nothing neither builder had, and it never dented the shared blind spot that keeps every Opus run a tier below HULLROT. Three Opus that all lack the same taste don't vote their way to it.
The clean line, updated: a harness can make a model see its own bugs (video QA) and now cross-examine away its confident ones (fusion). It still can't make it generate the taste no copy of it has. Fusion widens "catch." The moat is still "create."




