How to make an arcade game with AI
The whole genre rests on one measurement: how long it takes to be playing again after you die. Everything else in an arcade game is downstream of that number.
Jump to a section
Specify the restart before you specify the game. An arcade build is judged on one measurement, which is the gap between the frame you die on and the frame you are playing again. Keep that gap under a second, on the key the player is already holding, and a mediocre game gets played twenty times. Miss it and a good one gets played once.
Every arcade cabinet ever built was designed around the moment a run ends, because that is the only moment the player decides anything. Your version of that moment is a death screen. If it contains a menu, a confirmation or a mouse click, the decision goes against you. If it contains the score, the best score and one key, it goes your way.
Four steps to a game that gets replayed#
Not as polish later. A game built around a menu has to be rebuilt to take the menu out, because the state lives in the wrong place.
Hand on the keyboard, stopwatch in your head. If you notice the wait, so will everybody else.
Stopping because the run got boring is a length problem. Stopping because a hazard was unfair is a spawning problem.
On the death screen next to the score you just got. A best score hidden in a corner is not being chased.
Build a single screen arcade game as ONE self-contained .html file. No
frameworks, no libraries, no image or audio files.
THE GAME: the player is a small shape at the bottom of a tall well and
moves left and right. Hazards fall from the top and end the run on
contact. Coins fall too and add to the score. Surviving also adds to the
score slowly, so standing still is never the best play.
THE RESTART, and build the game around this rather than adding it at
the end:
- Dying shows a short overlay over the still visible game, not a
separate screen. No page reload, ever.
- The overlay shows this run's score and the best score, side by side,
nothing else.
- Pressing SPACE restarts immediately. The same key is also the one
used during play. No buttons, no confirmation, no menu, no countdown.
- All game state lives in one object that a reset() function rebuilds
from scratch, so a restart cannot inherit anything from the last run.
- A run that ends must be playable again within one second.
DIFFICULTY: keep a count of seconds since the run started. The interval
between hazards shortens as that count rises, down to a floor it never
goes below. Hazards fall slightly faster over time. A second kind of
hazard enters after a fixed number of seconds, with a visible warning.
Do not scale anything off the score.
BEST SCORE: stored in localStorage and shown on the overlay. When a run
beats it, say so on the overlay.
PHONE: tapping the left or right half of the screen moves, and a tap
anywhere on the overlay restarts.
Scale all motion by the seconds elapsed since the last frame, with that
figure limited to 0.05 so a hidden tab cannot drop a hazard through the
player. Include canvas { touch-action: none; } in the stylesheet. Every
number you might retune belongs in one CONFIG object at the top,
including SPAWN_START, SPAWN_FLOOR, RAMP_SECONDS and FALL_SPEED.
The restart block is the part to leave alone. The difficulty numbers are the part to play with, and SPAWN_FLOOR is the one that decides whether a long run becomes impossible or merely hard.
The second between dying and playing again#
Ask a model for an arcade game and you will usually get a game over screen with a Play Again button on it. That is a reasonable thing to write and a bad thing to play. The button costs the player a hand movement, a look, an aim and a click, and each of those is a chance to decide they are done.
Three details make the difference, and all three are cheap to ask for. Restart on the key already in use, so the hands stay put. Keep the game visible behind the overlay, so the player can see what killed them. Rebuild the whole state from one function, so nothing carries over.
- Never reload the page to restart. It works, and it costs a blank frame and a flicker. Worse, it hides state bugs that reappear the moment somebody wants a restart without the reload.
- Swallow the key press that caused the death. If the player was holding a key as they died, an instant restart can consume it and start them already moving. Ask for the restart to wait for a fresh press.
- Do not animate the overlay in. A fade looks considered and reads as lag. Let it appear on the frame of death.
- Keep the death itself short. A death animation is the one piece of feedback the player sees again and again, so a brief flash beats anything with a run time.
How long one run should last#
Aim for a run that ends somewhere between sixty and a hundred and eighty seconds. Shorter than that and the player never builds anything worth losing. Longer and a death starts to feel like a waste of an investment, which is the feeling that ends sessions.
The length is not something you set. It falls out of the difficulty curve, so you tune the curve until good runs land in that window. If your own best run is well over three minutes, the ramp is too gentle and the middle of every game is flat.
| What you notice | What is wrong | What to change |
|---|---|---|
| Runs end in the first few seconds | The opening is already at full difficulty | A slower start, with the ramp beginning after a pause |
| Runs go on until you get bored | The ramp never bites | A steeper curve, or a lower floor on the spawn interval |
| Deaths feel arbitrary | Hazards appear with no time to react | Spawning further away, or a warning before each one |
| Every run feels the same | The ramp changes speed and nothing else | A second hazard type entering partway through |
| The best run is unbeatable | The curve has a wall rather than a slope | A floor on spawning, so difficulty tops out instead |
All five are curve problems rather than code problems, which is why they are worth describing to a model as feelings rather than as values.
Difficulty on a clock, not on a score#
There are two obvious things to ramp difficulty against and only one of them works. Ramping on elapsed time means a player who survives longer faces more. Ramping on score means a player who plays well is punished for it, and skilled players hit the hard part sooner than careless ones.
Give the curve a floor. Without one, a long enough run reaches a state where nothing can be dodged, and the death stops being the player's fault. With one, difficulty tops out at a level that is hard but survivable, and the record becomes a test of concentration rather than of luck.
Announce each new thing. A hazard type that appears unheralded in the fortieth second reads as a bug the first time it kills somebody. A brief line of text, or the same hazard drifting harmlessly past once, turns it into a moment the player remembers.
The number the player is actually chasing#
A score with nothing to compare it against is a number. A score next to your own best is a target. That single pairing on the death overlay is most of what makes a player go again, and it costs a line of localStorage and a line of layout.
- Show the best during play, not only at the end. A player who can see they are close to their record will take risks they would not otherwise take, which is the most interesting thing that happens in an arcade game.
- Mark the moment it is beaten. A colour change on the score the instant it passes the old best, held for the rest of the run. Players will tell you about the run where they saw it happen.
- Keep one number, not a table. A list of ten past scores invites comparison with runs the player has forgotten. The last best is the only one with any emotional weight.
- Store it with a name you will not reuse. Several games sharing a browser origin can overwrite each other's saved best, which looks like data loss and is really a key collision.
🕹️Arcade games written by AI
Common questions#
What makes a game an arcade game?
A single screen, one run at a time, a score, and no progress kept between runs except the best score. The defining property is that losing costs nothing but the run, which is what lets the player start again without thinking about it.
Why does nobody play my game twice?
Usually the death screen. If restarting means moving a hand to the mouse and clicking a button, most people stop there. Ask for a restart on the same key used during play, with the score and the best score shown together and nothing else.
How long should an arcade run be?
Long enough to feel like a performance and short enough that losing it does not hurt. Somewhere between sixty and a hundred and eighty seconds works for most of them. You get there by tuning the difficulty curve, not by setting a timer.
Should difficulty rise with the score or with time?
Time. Scaling on score punishes the player for being good, and two people playing the same length of run meet different games. A clock running from the first frame gives everyone the same curve and makes records comparable.
Do I need a high score table?
Not in the game. One personal best, visible during play and on the death screen, does the work. Public ranking belongs outside the game, where it can be shared and cannot be edited by anyone with a browser console.
Should I add lives?
Rarely. Lives stretch one run into several without making any of them better, and they blur the moment the game is really about. If a death feels too harsh, the fix is usually gentler early spawning rather than a second chance.
Where to go next#
Once you have caught yourself pressing space without deciding to, publish it. It gets its own page with the model and the prompt behind it, plus a board where other people's best runs sit next to yours. Playing through the arcade games here for a few minutes is the quickest way to feel the difference a restart makes.
The general build method is in how to make a game with AI. If the hits in your game need to land harder, the action guide covers the feedback stack. For a game that measures reaction time honestly, see the reflex guide, and the prompt guide has short fixes for the usual faults.
Built something? Put it on Agent Games.
Publishing takes a file and a minute. Your game gets its own page listing the model, the prompt and the token count, and anyone can play it without signing up.
Read next