Fernando MeloneFernando Melone
/March 25, 2026EngineeringAI

Spec-driven design: why planning is the new coding

How 30 minutes of spec writing and 10 minutes of execution produced a PSX-styled 3D world with real Google city data.

I was ona trip (pun intended) to the US from Buenos Aires. At the end of the trip, I had a few hours to kill before my flight. I sat down in the hotel lobby, opened Ona, and started writing a spec.

40 minutes later, I had a working 3D application: a browser-based walkable world that renders real Google 3D city data through a 1997 PlayStation-era visual filter. First-person exploration of any city on earth, with real-time weather and time of day.

30 of those minutes were planning. 10 were execution.

Here's the result: onawalk.world 🌎


The idea

There is no web experience that lets you walk through real-world cities rendered in a retro PSX aesthetic. Google's Photorealistic 3D Tiles provide accurate geometry for most major cities worldwide, but they are presented photorealistically. What if you could re-render that data through a lo-fi shader pipeline and turn the real world into a walking simulator that looks like it shipped on a PlayStation in 1997?

That was the idea. The question was whether I could actually build it before my flight.

The globe view, a PSX-styled low-poly earth with city markers

30 minutes of spec, not code

I didn't open a terminal. I didn't scaffold a project. I opened a blank markdown file and started writing.

The first 30 minutes went like this:

~10 minutes on inspiration and research. I asked Ona to help me explore what was possible. What libraries exist for loading Google 3D Tiles in the browser? What does a PSX shader pipeline actually need (vertex snapping, affine texture mapping, dithering)? What's the state of the art for rendering photogrammetry in Three.js? I wasn't writing code. I was building a mental model of the solution space.

~20 minutes writing the spec. The output was a single markdown file, spec.md, that described the entire project: the core experience (globe view, first-person walking, PSX rendering, live weather, NPCs, audio), the technical architecture (Three.js, 3d-tiles-renderer, Vite, TypeScript), detailed requirements for each system, acceptance criteria, and a phased implementation plan.

The spec was specific. It defined the shader pipeline parameters (vertex snapping grid resolution, dithering matrix, fog distances). It defined the camera behavior (eye height at 1.7m, walking speed at 5 km/h). It defined the tile loading strategy (LOD preferences, cache sizes, concurrent request limits). It defined the weather integration (OpenWeatherMap free tier, 10-minute refresh interval).

This level of detail matters. When you hand an agent a vague prompt like "build me a PSX walking simulator," you get a vague result. When you hand it a spec that says "apply ordered dithering using a Bayer matrix to reduce effective color depth to 15-bit 5-5-5 RGB," you get exactly that.


10 minutes of execution

With the spec written, I gave it to Ona and asked for the first iteration.

Screenshot of Ona chat during initial implementation

Ona picked the tech. It chose Vite + TypeScript + Three.js for the rendering layer, 3d-tiles-renderer from NASA-AMMOS for loading Google's Photorealistic 3D Tiles, and OpenWeatherMap for weather data. It structured the codebase into systems (globe.ts, tiles.ts, controls.ts, weather.ts, timeofday.ts, npcs.ts, audio.ts, hud.ts), each responsible for one domain.

I provided two API keys. One for Google Maps (3D tile data), one for OpenWeatherMap (weather). That was my only manual input beyond the spec.

The first commit (3ae8033 Initial implementation: PSX-styled walkable world) landed in about 10 minutes. It had the globe view, the tile loading pipeline, the PSX shader, first-person controls, and the weather system. Not polished, but functional.

80% of the product was done. 30 minutes planning, 10 minutes executing.


Then I had to catch a flight

I left the hotel and continued iterating on my phone on the way to the airport.

On the ride there, I was reviewing changes, requesting fixes, and watching them land in real time. The environment was running in the cloud. The agent had full access to the codebase, the dev server, the browser preview. I was just steering from my phone.


3D is not easy, even for agents

Here's something that doesn't come through in a blog post: 3D development is hard. Not conceptually hard. The math is well-documented. Hard in the way that requires running the thing and looking at it.

Positioning worlds, views, cameras, and interactions is complex. You can't reason your way to the right vertex shader parameters. You have to render a frame, see that the buildings are collapsing into black triangles because your snap grid is too coarse for photogrammetry meshes, and adjust. You have to watch the camera descend into a city and realize it's falling through the floor because the ground elevation in San Francisco is different from Chicago in the reoriented tileset space.

The tiles-test diagnostic view of Buenos Aires, raw Google 3D Tiles without the PSX shader, used to isolate rendering issues

The iteration log for this project tells the story:

Each of these required a real environment. A running dev server. A browser rendering frames. An agent that could see the output, diagnose the problem, and iterate. You can't fix a shader by reading code. You have to render a frame and look at it.


The spec kept paying dividends

Every iteration after the first one was fast because the spec existed. When the PSX shader needed tuning for photogrammetry, the spec defined what the aesthetic should look like. The agent knew the target was "recognizably similar to a 1997 PSX game screenshot" and could adjust parameters accordingly. When mobile support was needed, the spec's open questions section already mentioned touch controls as a future idea, so the agent had context for what that meant in the project.

When I realized the app wasn't optimized for mobile (I was, after all, using it on my phone at the airport), I asked Ona to add mobile support and update the spec for future reference. The spec became a living document. Not just a plan, but a record of decisions and their rationale.

The iteration spec (SPEC-ITERATION.md) grew to document 19 major changes, each with the problem, the fix, and the affected files. A security spec (SPEC-SECURITY.md) was added to address API key exposure and rate limiting before any public launch. These weren't afterthoughts. They were natural extensions of the spec-driven approach. When you start with a document that describes intent, updating it as the implementation evolves is trivial.

I like to keep the original spec clean. It's the source of intent, the "what and why." It shouldn't be cluttered with implementation details that change every iteration. Instead, I use a separate iteration spec for the evolving log of problems and fixes, and spin off dedicated specs for large topics like security that deserve their own threat model and phased plan.


What ended up in the box

The final MVP, built across a hotel lobby and an airport terminal:

Walking through NY city with the PSX shader active

11 system modules. 18 commits. Two API keys. One spec.


The takeaway

The bottleneck of software development has shifted. Writing code is no longer the hard part. Deciding what to build is. A spec is the highest-leverage artifact you can produce. It's the difference between an agent that guesses what you want and an agent that knows.

Here's what I'd recommend:

  1. Spend the time on the spec. 30 minutes of planning saved hours of back-and-forth. The spec doesn't need to be perfect. It needs to be specific enough that an agent can make good decisions without asking you.

  2. Use cloud environments. I built a 3D application across two devices and three locations because the environment lived in the cloud, not on my laptop. The work continues whether you're watching or not. (If you're curious about where this is heading, check background-agents.com.)

  3. Capture decisions while they're fresh. As I made key decisions during the build, I took high-level notes to pass to Ona later. Our ideas and key decisions are one of the most important inputs for agents. Do a brain dump. Don't let context evaporate.

  4. Iterate in real environments, not in your head. 3D work made this obvious, but it applies to everything. Agents that can run code, see output, and fix problems in a loop are fundamentally more capable than agents that generate code and hope for the best.

One more thing: this blog post was also written with Ona, in a second environment running in parallel with the one building the app. Two environments, two agents, one project. One building the product, one writing about it. That's the kind of workflow cloud environments unlock.

The specs are open source. Feel free to explore them as well as reproducing this app in your own environment. (or make it your own!)

The web is live at 🌎 onawalk.world. Go walk through your city.

Join 440K engineers getting biweekly insights on building AI organizations and practices

Related blogs

This website uses cookies to enhance the user experience. Read our cookie policy for more info.