2026.05.30

Delivering Magic

AI has made it easier than ever to make software without fully understanding software. It’s easy to think of this as a new superpower that we all have access to, but the real advantage isn’t in the execution. It’s knowing enough to create the kinds of magical experiences that can only come from understanding.

Observations

A meme with three Spidermen pointing at each other, representing the product, engineering, design triad.
We can all do each other's jobs now. Sort of.

We misunderstand each other’s work. Designers think they can code. Developers think design is mostly taste. Product managers think both are more replaceable than they are. This is Dunning-Kruger at scale – the less we know about something, the easier it looks from the outside.

Designers are particularly guilty of celebrating that we are all now coders, but great software isn’t a few lines of clever output. It’s a duck on water. Above the surface: serene, apparently effortless. Below: a constant flurry of paddled feet. This is what maintenance, debugging, architecture, tradeoffs, documentation, naming, refactoring, evaluation, constraints discovery, and more looks like. The written code is only a small part of the picture.

A meme with a duck swimming on water. The duck is the code, the paddling feet are everything else.
What we see is often the result of a lot of work that we don't see. What we don't see, we tend to underestimate.

AI makes this confusion worse, not better. It fills the gaps in thinking whether we know those gaps are there or not. This leads to working prototypes built on foundations we don’t understand, going in a directions we didn’t choose, and full of decisions we can’t evaluate.

A meme joking about drawing an owl starting with two circles. Everything between the two circles and the expert drawing of the owl is magic.
AI fills the gaps in our understanding, whether we recognize those gaps or not.

Richard Feynman put it plainly: “The first principle is that you must not fool yourself – and you are the easiest person to fool.” His solution was the Feynman Technique: understand something well enough to explain it simply, to a twelve-year-old, or admit that you don’t understand it yet.

This is where my day job and my night job have started to overlap.

I’ve been building a game for a couple of years now. On the surface, it’s beautiful. Beneath it, there are thousands and thousands of lines of code. I’m increasingly vibing with parts of it, but that’s only possible because I spent two years first building a real understanding of what’s underneath. I watched countless tutorials, read and re-read Godot documentation, and spent days getting lost in Stack Overflow rabbit holes. I wrapped my head around classes and APIs, not just to code, but to understand, and this became the foundation I needed to vibe responsibly.

I was also using ChatGPT to ask questions and search for solutions to problems that were hard to describe. Sometimes it worked. Sometimes it didn’t understand the basics of Godot. Sometimes it hallucinated features that didn’t exist, helpfully apologizing when I called it out. The foundation I’d built wasn’t just useful for writing code; it was useful for recognizing bullshit. Without it, I would have lost weeks chasing dead ends that looked convincing on the surface.

Then I started using Claude Code. I gave it access to the full codebase. It didn’t always lead to success, and it often led to token spend I didn’t completely understand, but it mostly didn’t lead to catastrophic results. The difference between “mostly not catastrophic” and “reliable” came down to how much we both aligned and understood what I was asking it to do.

Physicist Richard Feynman standing in front of a chalkboard, declaring that we must not fool ourselces.
Fooling ourselves is dangerous. As designers, it's even more dangerous because our failures in understanding get passed onto users.

Learnings

A few things have become clear through all of this.

Know your architecture. If you can’t draw how the pieces relate to each other, you’re going to end up with a cathedral sitting on a foundation meant for a single-story home. I try to keep AI working on the outer details rather than the foundation… but sometimes, especially when refactoring, there’s a vertical slice, a change that cuts all the way through. There I’m always extremely watchful and much heavier-handed in how I manage what it does.

Align before execution. AI has a memory problem, so you can’t assume it’s holding the right context. My pattern now: ask for an approach first. Spend anywhere from five minutes to an hour refining that approach together. Then allow execution. My statistical friend has admitted, when challenged, to wandering off, going down rabbit holes, and acting before it understands. Getting aligned first means less spinning later.

Create and maintain documentation. I started by asking Claude to document my codebase. Now we maintain that documentation together. It’s useful for onboarding, but more importantly it’s useful for guiding the approach to sticky problems and for catching regressions. Sometimes Claude undoes something we did intentionally. When that happens, I ask it not only to fix or revert, but to update the documentation so the decision is recorded.

Assess the output. I review the code to make sure I understand the execution. Not every detail, but enough to be confident that decisions were made in a way that won’t constrain the game later. UI is easy for me to read (I can see the boxes and buttons in the code). Physics, lighting, shaders still require actual testing.

Start with the smallest piece you can carve out. Refactors are the biggest risk, so it’s important to start as small as you can. Define that chunk and get it right. Then allow the AI to work on the next part. Instruct it explicitly to ask questions about anything ambiguous before proceeding, rather than making assumptions you’ll have to undo later.

Takeaways

The most common mistake I see people making with AI-assisted development isn’t using it too much. It’s using it without understanding enough to evaluate what it’s giving them. The output looks right and the prototype works. The duck is gliding over the water. But under the surface, nobody’s really sure what’s happening. Eventually, that catches up.

Feynman’s principle still holds. AI doesn’t make anyone less likely to fool themselves. It makes us more likely to, faster and with more confidence.

But there’s a more interesting version of this story for designers. Understanding how things work isn’t just a defensive posture – it’s a genuine superpower. When we know what’s actually happening under the water, we can design experiences that feel magical precisely because we’re working with the grain of the system. We stop designing for an idealized version of the technology and start designing for what it can actually do — which is usually stranger and more interesting.

The alternative is shipping gaps. Moments in the experience where something should work and doesn’t. Where the seam between what was designed and what was built exposes that nobody fully understood the space in between. Those aren’t usually failures of craft. They’re failures of understanding.

Designers who understand what they’re doing well enough to explain it to a child don’t just avoid the gaps. They find and deliver experiences that feel magical.

Cinderella's transformation from rags to ballgown enabled not by magic, but by understanding.
It's deep understanding, not AI, that enables us to deliver truly magical experiences.