3D isn't as hard as you think: shipping a 40-year-old gaming memory in two days

Experiments 2026-08-14 · Satsuma Creative · 9 min read

I always assumed 3D games were the domain of big teams. Last week I remembered an old Apple II game and decided to test just how far web 3D can go. Two days later it was live: physics-based dueling, dismemberment and blood, 12 levels, an equipment shop, playable on mobile. The genuinely hard parts had nothing to do with 3D.

It started with a memory.

Forty years ago there was a game on the Apple II: two warriors dueling from a top-down view. Left and right keys rotated your body to swing the sword, up and down moved you forward and back, and the faster you spun, the harder you hit. I forgot the game's name long ago, but I never forgot the feel of that swing.

Last week I wanted to test one thing: how far can web 3D actually go today? That memory became the assignment.

Two days later, the game was live. Physics-based dueling, dismemberment and blood, 12 levels of enemies each with their own personality, an equipment shop with cloud saves, playable on any phone straight from the browser, with The Blue Danube as its soundtrack. It's called Samurai Waltz.

This post isn't about "look how good I am" — quite the opposite. It's about how this no longer requires being good. The technical barrier to 3D games collapsed while I wasn't paying attention. But some parts of the process were genuinely hard, and none of those had anything to do with 3D.

First, the method: this was an AI collaboration experiment (like the previous two posts in this series). I set the brief, playtested, made judgment calls, and gave final sign-off; the code, research, and asset hunting were done by Claude. Every "we" below means exactly that.

1. The three barriers to 3D — all three are gone

My impression that "3D is hard" really broke down into three things: the engine is hard to write, the assets are hard to make, and the math is hard to understand. Let's audit each one.

The engine: free for the taking. Rendering uses Three.js — an open-source library that handles the dirty work of drawing 3D models onto a web page, installed with a single command. Physics uses Rapier — it handles "what happens when things collide": a sword bouncing off a shield, or sending an arm flying, is all its math.

(A quick gloss: Rapier is a physics engine written in Rust and compiled to WebAssembly — a format that lets browsers run code at near-native speed. Which means physics simulation that only elite studios could build 20 years ago now runs in your phone's browser, for free.)

Total cost of both: zero dollars, zero licensing negotiations, zero waiting.

Assets: free for the taking — and better than expected. The game's 9 characters, 8 weapons, 8 shields, plus barrels, pillars, and torches all come from KayKit — a free asset pack by a Dutch creator, licensed CC0, meaning free for commercial use, no attribution, no asking. The 14 sound effect files, 164KB in total, come from Kenney, also CC0.

The soundtrack is the actual Blue Danube: Johann Strauss II died in 1899, so the piece has long been in the public domain. We found a recording performed by the United States Marine Band — works of the US federal government aren't protected by copyright — and cut a 122-second loop. A famous piece from 1867, licensed for zero dollars.

The biggest surprise in the asset hunt was an easter egg: KayKit's character models already have the head, torso, arms, and legs as separate meshes. When we went to build the dismemberment system, we discovered the parts came pre-cut. Dismemberment was essentially free.

The math: outsourced to the engine. The most complex math we wrote in the entire project was "the distance from a line segment to the center of a circle" — middle-school level. Rotation matrices, quaternions, collision solvers — all the legendary gatekeeping topics stayed inside the engine and never surfaced.

2. Day one: from two cylinders to severed arms

The first prototype was two cylinders whacking each other with sticks. Gray and ugly, but the core feel emerged that first afternoon: left-right rotation, inertia, and that whip-crack moment when the swing lands.

Then came the layering: cylinders became KayKit knights, sticks became greatswords, arms became real physics parts (the shoulder is a rotating joint, so the weapon lags behind the body and whips out at the end of the swing), and on death the joint breaks, sending the arm flying off with the weapon still in hand. Each layer took just a few hours.

Three pitfalls are worth recording, because they show how physics games differ from ordinary programming —The physics engine is more honest than you are

Pitfall one: you can't hit someone at point-blank range. We initially used collision events to determine damage: sword touches person, deduct health. But when two fighters press up close, the sword stays in constant contact — the "touch" event fires only once, and no amount of swinging counts afterward. The fix was to measure directly every frame: how close is the blade to the body, and how fast is it moving right now.

Pitfall two: at the instant of impact, velocity is zero. Damage should depend on the sword's speed, but the physics engine absorbs the velocity at the exact moment of collision — by the time you read it, the sword has already stopped, so you always read zero. You have to copy down the velocity before the physics step runs, then look at that copy after the impact.

Pitfall three: perfect symmetry is a trap. Two warriors spawning face to face, sword tip to sword tip, forms a perfect physical equilibrium: the AI pushes forward, tip against tip, drives its opponent all the way to the wall — then the forces cancel out and they lock up forever. The fix is deeply unromantic: make the spawn points slightly off-center on purpose.

These three pitfalls took more time than everything 3D on the screen combined.

3. The genuinely hard part: players will always be smarter than you

Day two's theme wasn't technology — it was design. Because by the end of day one, the game had a guaranteed win: spinning in place.

Spin up to top speed and ram into the enemy; the AI can't react, and one pass kills. We named this move "the Top." A game with a guaranteed win is no game at all, so it had to be dismantled — and it took us three versions to succeed.

Version one added a stamina bar: spinning fast burns stamina, and when it runs out you're exhausted. Test result: the Top still cleared the level in 18 seconds, because mid-speed spinning burned no stamina yet remained lethal.

Version two made mid-speed spinning cost stamina too, and taught the AI to back off and wait when it sees the opponent spinning. Test result: the Top cleared in 25 seconds with zero damage taken. Physically, the AI's retreat speed can't outrun the sword's spin radius, so every engagement guaranteed it a free hit — pure giveaway.

Version three found the real key:spin force decays linearly with stamina. The lower your stamina, the weaker your swing; when exhaustion ends you're no longer a fully-charged blender but a weakened fighter. Combined with the AI's full behavior set — it dodges when you spin, pounces when you're exhausted, and pulls back early as you recover — the test result: 45 seconds of pure spinning could only fight to a near-draw, 84 to 82.

The Top was demoted from a guaranteed win to a tactic that requires resource management. Those three iterations cost roughly three times the effort of the entire 3D rendering portion.

Later we gave the 12 levels of enemies 6 personalities — one that smothers you at close range, one that turtles behind a shield waiting for your mistake, one that hovers forever one centimeter beyond your blade's reach, one that gets more reckless as its health drops, and one that uses the Top against you. Each personality is just a parameter table plus a few conditionals — no advanced AI techniques whatsoever. But all of the game's depth comes from here, not from the 3D.

The most convincing evidence was an accident: after launch we needed a promo video, so we scripted the player character to kill enemies for the camera — and got killed three times by our own AI. It dodged the camera, kited our script, and struck precisely in the gaps between takes. We only got the kill shots after enabling a "studio mode" (infinite stamina plus teleport). Designing an opponent that thinks is harder than rendering a thousand polygons.

4. Login, terms, privacy: just copy your own

When it was time to build the account system on day two, my heart sank a little — third-party login again, terms of service and a privacy policy again. This kind of work always takes at least a day.

Then I remembered: I did all of this last year.

We have another game, AQ, which has a complete set of three login methods (Google, Apple, guest), a program that verifies login identity, and terms of service and privacy policy texts refined word by word. We ported it all over:

Login shares AQ's account system directly — no configuration changes needed, since both games live under the same domain, with a happy side effect: one account works across both games. The identity verification program worked after a rename. The terms and privacy policy started from AQ's versions with edited content — this game has no paid features at all, so the entire refund section was deleted, and the privacy policy actually got cleaner: "We never receive your payment data, because there are no payments."

Work estimated at half a day to a full day actually took two or three hours, and most of that went into testing real questions like "can a guest login's save file be recovered across devices" rather than reinventing wheels.

The lesson here for a one-person company matters more than the time saved:From your second product onward, your biggest asset library is your own previous product. Login, payments, legal texts, deployment pipelines — the things unrelated to your core business but required by every product. Get them right once, and every time after is a copy-paste.

5. The bill

Final accounting, as is tradition in this series.

Time: two days. Day one: prototype, physics, models, dismemberment. Day two: levels, shop, account system, mobile version, launch, Threads promotion.

Money: assets, zero (CC0 plus public domain); engines, zero (open source); server, existing (already running other services). New spending: zero.

Output: a complete game. 12 levels, 8 weapons, a stamina system, dismemberment, cloud saves (with anti-tampering verification), a PWA mobile version, a game content rating label, and a privacy policy — those last two took about as much time as writing the physics damage detection. There are no shortcuts in compliance.

Launch day(a few hours after posting on Threads): 69 page loads, 30 unique visitors, 4 players registered for cloud saves. Small numbers — but between "a 40-year-old memory" and "strangers playing it on their phones" stood only two days.

6. So what's actually hard

The impression that "3D is hard" is an afterimage from 20 years ago, when you needed to understand graphics theory, buy an engine license, and hire an art team. Today those three things have become: a free library, a free library, and a CC0 asset pack.

The genuinely hard things haven't changed — and they have nothing to do with 3D:

Game feel is tuned, not written. The satisfaction of the sword swing hides in the combination of a dozen-plus parameters, and every change has to be played and felt. There is no one to outsource this to.

Players will find the optimal strategy you never thought of. The lesson of the Top's three versions: you're not writing a program, you're playing chess against every future player.

Judgment can't be automated. Over these two days AI wrote nearly all the code, but "does this feel right," "is this level too hard or too easy," "should this guaranteed win be dismantled" — every one of those decisions required a human to play and then decide. Once tools drive execution costs to near zero, all that remains is judgment.

If you also carry a memory of an old game, the barrier to building it today is roughly: one weekend, and the will to start.

The game is here, free, playable on mobile:satsumacreative.tw/kw(Rated 15+ in Taiwan; contains violence and gore.) If you beat the Skeleton King, let me know — no one has seen him yet.