← Back to Blog

Where AI Falls Down: Taste

July 2026

I wrote previously about how strict type systems and aggressive compilers make AI-assisted development work well. The argument was simple: deterministic checks catch the categories of mistakes AI is most prone to, and the tighter the feedback loop, the faster you go. I still believe that.

But building a game broke the pattern.

EvoFactory

EvoFactory is a real-time cell biology simulation. You control a single cell in an infinite procedurally generated world, absorb resources, build organelles, set up gene regulation rules to automate production, and unlock a tech tree. The core simulation—resource spawning, crafting, particle physics, rule evaluation—is written in Rust and exposed to Godot 4 via GDExtension. The rendering and UI are GDScript.

The Rust side is well-suited to AI development. Types enforce that a zymase can only process glucose, that mRNA crafting consumes the right number of amino acids, that gene regulation rules reference valid metrics. The compiler catches structural errors. Integration tests verify the data contracts between Rust and Godot. When I ask the AI to add a new organelle type or a new tech tree node, the build-test loop keeps it honest.

The problem is everything else.

What Tests Can't See

A game is not an API. The thing that matters most—whether it feels right to play—is the thing that's hardest to pin down in an assertion.

My test suite can verify that the interior view renders the correct number of particles, that drag-and-drop collision detection triggers at the right distance, that the tech panel reports the right progress values. It can even run headless in CI. What it cannot tell me is whether the cell's movement feels sluggish, whether the resource distribution makes exploration rewarding, whether the gene regulation panel is intuitive, or whether the dimetric projection looks right when you scroll to the edge of a chunk boundary.

These are taste problems. They're the gap between "correct" and "good."

The Regression Problem

In a backend system, regression means something broke—a function returns the wrong value, an endpoint throws an error, a test fails. You can detect it mechanically. In a game, regression often means something got worse. The particle diffusion constant changed and now the interior view feels frantic. The camera interpolation was adjusted and now panning feels floaty. A rendering refactor changed the draw order and now organelle tooltips appear behind the membrane.

None of these are bugs in the traditional sense. The code is correct. The tests pass. The game is just worse.

I've written aggressive e2e tests for EvoFactory—headless GDScript tests that exercise the full Rust-to-Godot pipeline, checking array sizes, state transitions, and mutation contracts. They catch real problems. But they are structurally blind to the class of regressions that matter most in a game. You can assert that the camera position is a number. You cannot assert that the camera feels good.

AI and Taste

This is where the junior engineer analogy breaks down, or maybe where it's most accurate. Junior engineers can write correct code that makes the product worse. They can refactor a UI component and make it technically cleaner while destroying the visual rhythm. They can "fix" a slow animation by removing the easing function. They can add a feature that's well-implemented and completely wrong for the user experience.

AI does all of these things, but with less awareness. When I ask Claude to add a tutorial overlay to EvoFactory, it produces a working tutorial system—staged hints, dismissable panels, correct state tracking. What it doesn't do is consider whether the tutorial interrupts gameplay flow, whether the hint text is the right size relative to the game world, or whether the overlay color clashes with the resource particles. These decisions require seeing the game, playing the game, caring about how the game feels.

The model has no eyes. It can reason about code, but it can't experience what the code produces.

What Still Works

The strict-compiler thesis isn't wrong—it's incomplete. For EvoFactory's Rust simulation core, the approach works exactly as well as it did for Splendor's Haskell engine. Types catch structural errors. Tests catch logical errors. The build loop keeps the AI from introducing mechanical bugs.

But the simulation core is maybe 40% of what makes a game a game. The rest is rendering, input handling, animation timing, visual feedback, spatial relationships, sound, pacing—all the things that add up to feel. And feel is a human judgment that no test suite I know how to write can automate.

For now, my workflow is split. I let the AI drive the simulation logic, the data layer, the serialization, the build pipeline—anything where correctness is well-defined and mechanically verifiable. For the visual and experiential layer, I write the code myself or review every AI-generated change by playing the game. There's no shortcut. The only test for taste is a human with taste.