Build a Fight Game in Two Hours

This is the whole point of this site, in one page. You'll build a complete game — a long scrolling road to a fortress gate, with three very different guards posted along it, each beaten in a duel, in the style of the classic Karateka — and along the way you'll meet every part a game needs: a player, getting hurt, fighting back, enemies with plans of their own, a score, a goal, and an ending. Two hours, honestly. Here's the finished thing:

The duel at dusk — a flying kick meets Lord Kage before the fortress skyline

The whole game is one file, and it's written in the order you'd build it — the numbered steps below match numbered comments in the source panel above. Read them side by side. When something makes you curious, change it and press RUN ▶.

Step 1 · Borrow the machine

Nobody builds a screen from scratch. The engine gives you the boring-but-hard parts as ready-made pieces: a loop (the game's heartbeat — fifty beats a second), a screen, a keyboard, a player that already knows how to walk and fall, a world to stand in, and a scoreboard. You import them at the top of the file like borrowing tools from a shed. Your game is everything else — and as you'll see, "everything else" is smaller than you think.

We also borrow the fighter drawing from another game on this site (Chan Can Kick). Good parts get reused. That's the whole idea of the engine.

Step 2 · A road, not a room

A room is rows of text. Really. A # means solid ground, a . means air, and a little legend says what each letter looks like and does. And a scrolling level is just rooms sewn together: ours is three of them, seamed left-to-right by one line (stitchRooms), making a 960-pixel road the camera follows you down. At the far end stands a gate — which will matter enormously in step 8.

Step 3 · A fighter you can feel

How your player feels — how fast they run, how much they slide, how high they jump — is a list of about ten numbers. The engine calls this list a profile. Change a number, change the feel: that's the entire physics system from your side. Ours is planted and precise, because this is a fight, not a race.

One line deserves a pause: jumpKeys: ['up'] means only the up arrow jumps — which frees the fire button to be a fist. Old C64 games did exactly this.

What the player looks like is a separate thing — one drawing function, swappable. Feel and look never tangle.

Step 4 · Getting hurt — and not dying about it

Here is the engine's best idea. When something deadly touches your player, the engine doesn't kill them. It asks. It announces a contact — "something hit you, here's what" — and your game decides what that means. Our answer: lose one of three hearts, stumble back, blink untouchably for a second… and cancel the hit. Only when the last heart is gone do we let it stand, and then the engine takes over: the death animation, the reset, all of it.

Health systems, shields, armour, mercy — every one of them is just a different answer to that same question.

Step 5 · Three guards, three plans

An enemy is anything with an update (its plan) and a draw (its looks). Our Duelist's plan is a loop you could act out: stand at your post → notice the challenger → close in → raise fists → strike → recover → repeat. One word — its state — records where in the plan it is, and everything else (the drawing, the damage rules) just reads that word.

But an identical enemy three times is one enemy with extra steps. Ours differ where it matters. Brun the Door (a Viking, borrowed from the character roster) winds up forever and hits like a door — walk out of it. Whisper (a Ninja) jabs fast and hops back out of your reach — chase him. Lord Kage (a Samurai) guards the gate personally and strikes twice per opening — survive the first cut and the second is already coming. Same skeleton, three personalities — and each personality is a handful of lines in one small function, plus a row of numbers.

Two details make every duel fair: the raised weapon is always your warning (good games telegraph), and each guard has health of his own, staggering at every blow and staying down at the last.

Step 6 · Fighting back

Combat is a moveset — a little table the engine runs for you. Each move in the table says three things: when it fires (its stance — standing still is the punch, moving is the kick), how long it lasts (its envelope, in ticks), and what shape its reach is (a small rectangle in front of you, mostly). Press fire and the engine picks the right move for your stance, runs its timing, and tests its rectangle against the world.

Your game writes none of that. Your game answers one question: what does a landed hit mean? That answer is a listener — the engine announces attack-hit with whoever got hit attached, and this game replies "he takes a hit; if he falls, pay his points." All the combat in every game on this site — Chan's flying kick, Myrtle's roar — is a table plus that one listener.

Step 7 · The scoreboard

The engine's Rules part is the bookkeeper. You tell it what happened — "a guard fell, worth whatever his card says" (Brun pays 200, Lord Kage 600) — and it keeps score. It can also run countdown clocks and hold a list of goals ("collect all the chests", "reach the vault") and tell you when they're all met; this game keeps it to the score on purpose, but Storm the Gates uses the clock and The Manor uses the goals, and it's the same bookkeeper in all three.

Step 8 · The ending — both of them

Games need two endings and you must build both.

The good one lives at the gate: it's the engine's Exit, and stepping through it makes the world announce complete — cue the victory banner. Exits can also make demands ("not until you've collected five chests") but ours is simpler: the guards ARE the demand, because a guard won't be run past. Duels are the door.

The bad one you already built in step 4 — it's what happens when the last heart goes.

That's it. That's a game: a place, a body, hurt, a fist, an enemy, a score, a goal, two endings.

Make it yours

Everything above is in the source panel — live. Some first experiments, in rising order of ambition: give yourself five hearts; make the third guard's reach terrifying; add a fourth guard; make the gate demand a collected key (place an item, give the exit requires: { count: 1 }); swap the fighter for any of the twenty-something characters in the roster. When you outgrow one file, the Map Editor builds whole worlds without code, and tutorials 1–10 explain every engine part this page waved at.