← Devlog

I shipped a world that was just another world with a red filter

A flat colour filter reads as fake because it has no material story — one hue across every object, no decay, no contrast. Here's why that fails, and what art-directing an AI reskin for real actually takes.

June 23, 2026 devlogaiart-direction

A week ago I shipped the secret final world of my game — a rogue AI boss that reads your board and adapts. Great mechanic. To dress it, I cheated: reused the existing Earth-endgame art and pushed it through a 13-line script that made everything red. Shipped in a day. It also looked like exactly what it was — one world with a filter on it.

Why a filter reads as fake

Red means evil for about ten seconds. Then your eye starts asking questions a flat tint can’t answer. The reason is material story: in a real scene, every surface tells you what it’s made of — rust catches light differently than concrete, glass differently than ash. A colour multiply throws all of that away. It maps every pixel to the same hue, so a crystal, a satellite dish, a plain cube and a comms tower all become the same orange-red object wearing different outlines. Players can’t name it, but they feel the flatness, because nothing in the frame has weight. The old background made it worse: a near-black void with one tiny probe. No grime, no decay, no contrast — for an AGI-gone-rogue finale, “red = bad” is the laziest read there is.

The brief came back short: redesign it. Fallout meets Matrix. Post-apocalyptic.

Two worlds that hate each other

Fallout and Matrix pull opposite ways — warm dusty atompunk versus cold digital green. Smashed together that’s mud. But the fiction handed me the seam: the AGI turned, and its corrupted processes are clawing into reality. So instead of blending the two I made them fight, as two layers:

  • The dead physical world (Fallout): ash concrete, rust, rebar, scorch, wrecked retro-industrial junk. Warm, desaturated, lifeless.
  • The infection bleeding through (Matrix): phosphor-green code-rain, glowing cracks, screens still scrolling code. The enemy path itself becomes the AGI’s data-conduit — a green seam the processes crawl down toward the exit.

That contrast is the whole trick. A single hue is one note; rust-versus-green is a sentence — reality decaying into code. The fix for a flat reskin is never a better filter. It’s an idea with two sides.

The bonus I didn’t plan: it’s now the only green world in the game. USA runs hype, China and Africa warm, Europe privacy-blue, Earth and Space cosmic. Drop in green and it instantly reads as the machine world — and it freed up red to mean pure danger again, where it belongs: on the VFX, not on every rock.

Twenty-three rolls in one sitting

Then it was just work. New cracked-irradiated-concrete ground baked into the iso tiles, a full wasteland backdrop (dead rubble up front, a ruined data-megacity behind, code-rain on a corrupted core), five floor decals, and a sixteen-piece set of ruins — toppled server racks, a CRT still scrolling code, a gutted cooling tower venting green, skyscrapers dissolving into code-voxels. Twenty-three generations, one session. Three things from that grind are worth keeping.

Cohesion is a batch operation. The sixteen ruins had to look born of the same world, so I rolled them in one normalized pass — identical framing, scale, and wording — and judged the whole contact sheet before installing a single piece. This matters because the generator is text-to-image with no shared anchor between calls: each roll is an independent draw from the model’s distribution. Regenerate one piece alone later and it lands at a different scale and perspective, and the set quietly stops matching. You can’t patch cohesion in afterward; you have to mint it all at once.

Tune the substrate, don’t fight it. The fresh concrete texture came out too bright — right material, wrong darkness next to the game’s other worlds. The fix wasn’t re-prompting; it was the tile-bake blend, mixing the raw texture roughly half-and-half with an ash tint until the tone sat where the other worlds sit. The art gives you the material; a numeric knob gives you the mood.

Sometimes you fix it in code, not in the prompt. One scorch decal kept generating as a rounded square. I told the model “NO square, NO slab.” It drew a square. Re-rolled. Another square. A square scorch reads as a fake tile and kills the illusion. So I stopped arguing and multiplied the cut’s alpha by a wobbly radial falloff — a sine-driven wobble on the radius so the corners just dissolve into a blob. The lesson generalizes: when a model has a stubborn shape bias, re-rolling burns generations fighting a prior you can’t see. Post-process the silhouette instead. You can’t always win the prompt fight; you can always win in numpy.

The whole-board wash, for free

Last piece: a green colour-grade over the entire board so tiles, ruins and even the units sit under the same sickly phosphor light — without touching the HUD, which has to stay readable. Sounds like a plumbing job. It was about six lines: a single green rectangle at SCREEN blend, low alpha, dropped over the board. My game already renders the board and HUD on two separate cameras, and anything created before the HUD camera exists gets ignored by it automatically. So the rectangle washes the whole world and leaves the interface alone, no per-unit tint plumbing. The architecture I’d cursed at for months finally paid me back — a grade mask I got for free because the camera split already drew the line.

What it taught me

A colour filter is a placeholder, not a world. The red script was the right call to ship the mechanic. But art-directing a reskin isn’t picking a better hue — it’s deciding what the place actually is, then giving it two sides that argue: a dead substrate and a localized infection. Contrast carries the narrative, which is why I kept the green on the path, the screens and the cracks and nowhere else. Green on every surface would just be the red problem in a new coat.

AI made the textures. It did not make the world. The model was the brush. Someone still has to be the painter.