obOB STUDIO
← Back to blog
Dev Log

What I Learned Shipping 14 Projects in One Year

6 min read

I didn't plan to ship 14 projects

It just kind of happened. I finished Oliver's Planes and thought, "That was fun, let me make a racing game." Then, "What if I added multiplayer?" Then, "I should build a gravity simulator." Before I knew it, I had 14 things live on the internet: Oliver's Racers, Oliver's Planes, my hide-and-seek game (and its 2D edition), Garden Gnomes multiplayer, Cosmic Gravity Sandbox, Apex Grand Auctions, Grand Prix Live Tracker, Apex Dynamics Configurator, Right Now Somewhere, AI Pulse, Hypercar Showdown, Guess the Price, Axiom Studios, and CodeLingo.

Ship ugly, then polish

My first instinct with every project is to make it perfect before anyone sees it. Pixel-perfect UI, smooth animations, edge cases handled.

Oliver's Racers v1 had placeholder boxes for cars, no sound, and one track. I showed it to a friend anyway. His feedback ("the steering feels weird") pointed me to a physics bug I would have spent days debugging in isolation. That one conversation saved me a week.

Now my process is: get the core mechanic working, make it playable (even if ugly), show it to someone. I've killed zero projects since adopting this approach, because by the time I start polishing, I already know the idea works.

Scope is everything

Cosmic Gravity Sandbox took me 4 days. My hide-and-seek game took me 3 weeks. The difference wasn't complexity. Both are technically interesting. The difference was scope.

The gravity sandbox has a tight scope: place bodies, simulate gravity, watch trails. That's it. I could hold the entire project in my head.

My hide-and-seek game started as "something simple" and scope-crept into 5 stages, AI seekers, online multiplayer, a practice mode, a 2D fallback edition, and touch controls. Each addition was individually reasonable. Together, they tripled the development time.

Decide your scope before you write a line of code, write it down, and resist the urge to add "one more thing." Or at least be honest with yourself when you're expanding scope, so you can adjust your timeline.

One reusable backend saves months

The single smartest architectural decision I made was building the multiplayer backend to be game-agnostic. When I added multiplayer to Garden Gnomes, I built a WebSocket relay that passes JSON between room members. The server doesn't know what game is being played. It doesn't validate game-specific payloads. It just relays messages.

When my hide-and-seek game needed multiplayer, I changed zero backend code. When Oliver's Racers needed it, same thing. Three games, one backend, no backend deployments after the first one.

If I'd built a Garden Gnomes-specific backend, I would have needed to build two more. That's three separate Lambda deployments, three DynamoDB tables, three sets of connection management logic. Instead, I have one of each, and adding multiplayer to a new game is about 2 hours of client-side work.

The browser is underrated

Building for the browser gave me:

  • No app store review, no download. Share a link.
  • Every device with a browser can run my projects.
  • The number one reason people try my games is that there's nothing to install.

The trade-off (WASM file sizes, WebGL limitations) is real but manageable. For the kinds of projects I build, the browser is the right call.

Perfectionism is the enemy

I spent 3 days tweaking the glow effect on the Cosmic Gravity Sandbox trails. Three days. For a visual flourish that most users probably don't consciously notice.

Meanwhile, the UI for creating a room in Garden Gnomes was confusing and I hadn't touched it because "it works." Guess which one generated more user complaints?

Perfectionism pulls you toward the parts of the project you enjoy working on (usually the technically interesting bits) and away from the parts that actually matter to users (usually the boring UX stuff). I'm still fighting this instinct. I don't think it ever fully goes away.

Every project teaches something the next one uses

This is the compounding effect that made the later projects so much faster:

  • Oliver's Planes taught me Godot's web export, PWA setup, and procedural mesh generation.
  • Oliver's Racers reused the mesh generation and added multiplayer, which taught me WebSocket architecture.
  • My hide-and-seek game reused the entire multiplayer backend and taught me Godot's 3D character controller.
  • Garden Gnomes taught me about hooking into third-party games (CreateJS display list walking).
  • Cosmic Gravity Sandbox taught me Canvas 2D performance optimisation and the glow trail technique.
  • Grand Prix Live Tracker taught me real-time API polling with graceful fallbacks.
  • Apex Grand Auctions taught me complex game state management and procedural 3D-on-2D rendering.
  • Right Now Somewhere taught me timezone math (which is horrifying) and client-side sun position calculation.
  • CodeLingo taught me sandboxed code execution via Web Workers.

Each project left behind reusable code and patterns. By project 10, I was moving twice as fast as project 1. Not because I got smarter, but because I'd already solved half the problems before.

The unsexy truth

Most of my time isn't spent on the cool stuff. Physics engines, 3D rendering, multiplayer networking. Most of my time is spent on:

  • Making touch controls not suck
  • Testing on phones I don't own (thank you, BrowserStack)
  • Writing loading screens for 39 MB WASM files
  • Debugging CSS on Safari
  • Making sure the back button works in an SPA

The interesting problems take 20% of the time. The other 80% is papercuts, edge cases, and testing.

What's next

I don't have a master plan. I never did. I'll keep building things that interest me.

ob

Written by Oliver

I build browser games and simulations on my own, everything here runs in a tab, with no installer and no account. The biggest is Oliver's Racers: procedural circuits in Godot 4, online multiplayer relayed by a Raspberry Pi in my room, and an Android build. Almost nothing here is imported artwork; the cars, trees and grandstands are built out of boxes and cylinders in code at load time.

More about me · See the projects