How to make a space game with AI
A space game is a ship, a black canvas and one decision about friction. Get the friction wrong and no amount of work on the rest of it will make the ship pleasant to aim.
Jump to a section
The brief is short. A triangle seen from above, a black canvas, rotation on the left and right keys, a thruster on the up key, and drifting rocks to avoid. Every model writes it. The part you have to specify yourself is how the ship slows down, because in real space it does not.
Space has no friction, and a game with no friction is tiring to play. A ship you let go of holds the same speed forever, so every change of heading needs a second burn to cancel the first. Add a little drag. It is wrong, and it is what makes the game work.
Four steps to a ship you can aim#
Then let go of the thruster. What the ship does next is the question the rest of this page answers.
If the only way to slow down is to point backwards and burn, there is no drag in the build yet.
Then lower it until the ship has weight again. The value you want sits between annoying and sluggish.
Three layers of dots will make it look like a space game. They cannot make a bad ship enjoyable.
Build a space game as ONE self-contained .html file, seen from above.
No frameworks, no image files, no 3D.
SHIP: a triangle in the middle of the canvas. Left and right rotate it.
Up fires the thruster, which adds speed along whichever way the nose is
facing. There is no brake key.
MOVEMENT: hold velocity as a pair of numbers that survives between
frames, so releasing the thruster does not stop the ship. Then apply two
corrections that are not physically honest and that make the game
playable. First, a drag that bleeds a fraction of the velocity away each
second, written so the result is the same whatever the frame rate.
Second, a hard ceiling on the length of the velocity, applied to the
pair together and not to each number on its own.
WRAPPING: treat the canvas as a loop in both directions. Anything
leaving the right edge returns on the left, and the same top to bottom.
While an object straddles an edge, draw it TWICE, once where it is and
once offset by a whole screen width or height, so it is never cut in
half. Distance tests wrap as well: compare against the shorter of the
direct gap and the gap round the edge.
BACKGROUND: three layers of stars. Work out their positions once at
start-up and keep them, rather than picking new ones each frame. Each
layer slides against the ship's motion at its own rate, the dim distant
layer slowest, the bright near layer fastest. The stars wrap too.
SOMETHING TO DO: rocks that drift and wrap, a collision that ends the
run, and a score counted from how long the player lasted.
PHONE: tapping the left or right half rotates, and the thruster stays on
by itself.
Express all motion as an amount per second, multiplied by the seconds
that elapsed since the previous frame, and never let that elapsed figure
go above 0.05. The stylesheet must include canvas { touch-action: none;
}. Collect DRAG, MAX_SPEED, THRUST, TURN_RATE and the three parallax
rates into one CONFIG object at the top, with a comment on each.
DRAG and MAX_SPEED are the two you will change most, and you should expect to change them several times. Leave the sentence about drawing an object twice in place. Without it the edges of the screen look broken, and the fault is easy to mistake for a bug in the wrapping arithmetic.
Frictionless space is accurate and unplayable#
Ask for realistic space movement and you get it. Thrust adds to velocity, velocity carries on untouched, and nothing in the world ever takes any of it back. That is correct. It is also the version of the game nobody finishes.
The problem is not the speed, it is the aiming. To point somewhere new, the player has to kill the speed they already have. That means turning to face the way they came and burning for roughly as long as they burned before. Every small correction becomes two deliberate manoeuvres.
Drag is the fix and it is a lie. Each frame, take a fraction of the velocity away. Let go of the thruster and the ship coasts, slows, and eventually stops. Space does not do that. Players read it as the ship having weight, which is a far more useful illusion than accuracy.
- Make the drag frame rate independent. Multiplying velocity by a fixed fraction every frame bites harder on a fast machine, because it happens more often. Raise the fraction to the power of the elapsed seconds instead, and the same curve comes out at any frame rate.
- Cap the velocity length, not each axis. Limiting the horizontal and vertical speeds separately lets a diagonal run faster than a straight one. Measure the length of the pair and scale both down together when it goes over.
- Keep the cap well above the comfortable cruising speed. It is there to stop the player leaving the screen faster than they can turn, not to govern normal flying. If you feel the cap during ordinary play, it is too low.
- Resist the temptation to add a brake key. A brake is drag you have to ask for, and it makes the player do the work that the drag value already does quietly. If the ship needs a brake, your drag is too low.
| Number | What it controls | What a wrong value feels like |
|---|---|---|
| Thrust | Speed gained per second of burn | Too low and the ship feels anchored to the spot |
| Drag | Share of the speed lost each second | Too high and flying feels like wading |
| Max speed | The ceiling on the velocity length | Too high and you cross the screen before you turn |
| Turn rate | Degrees of rotation per second | Too low and a rock arrives before you have faced it |
Four numbers, and the first three argue with each other. Change one, fly a lap, then decide. Raising the thrust and the drag at the same time usually ends up feeling like neither.
Wrapping edges, and the ship drawn twice#
A screen that wraps is the right shape for a space game. There is no wall to hit and no corner to hide in, and the arena stays the size of the canvas. The arithmetic is one subtraction. The part that gets missed is the drawing.
A ship whose centre is still on screen but whose nose has crossed the right edge should appear in both places at once. Draw it once and the nose is simply gone, and then the whole ship jumps to the far side the moment its centre crosses. Players notice that instantly.
Distances have to wrap as well, and this one hides for longer. A rock just inside the left edge is close to a ship just inside the right edge, even though subtracting their positions says they are a whole screen apart. Compare against both gaps and keep the shorter.
Ask for one helper that wraps a position and one that measures a wrapped distance, then have everything use them. Rocks, bullets, particles and stars all live under the same two rules, and a single object that forgets them is a visible glitch.
A starfield in layers, which is depth for free#
A black canvas with nothing on it gives the player no sense of moving at all. The ship sits in the middle, the speed readout changes, and nothing else does. Stars fix that, and stars at two or three different speeds fix it properly.
Parallax is the oldest trick in flat games and still the cheapest. Near things slide past quickly, far things barely move. Three layers is enough: faint small dots that drift, mid-grey dots at a middling rate, and a few bright ones that move almost as fast as the ship.
- Decide the positions once. Picking random star positions inside the draw call makes the whole sky flicker. Build each layer at start-up and keep it. If you want a different sky each run, rebuild it on the restart and not on the frame.
- Move the layers against the ship. The ship stays centred and the background slides the other way, at a fraction of the ship's speed. Each layer gets its own fraction, and the fractions are what you tune.
- Keep the near layer quiet. Bright fast stars read as snow, or worse as rain, and they fight with anything you need the player to see. A handful of them is more convincing than a field.
- Wrap each layer separately. Take the layer's scroll offset modulo the screen size and draw from there. Because the stars are points, they need no second draw, which makes them the easiest wrapping in the game.
Once the layers are in, a little thruster exhaust behind the ship buys more feel than anything else of the same size. A few short-lived dots thrown out of the back, drifting and fading as they go, and suddenly the ship has a direction.
🚀Space games written by AI
Common questions#
Can AI make a space game?
Yes, and a top down one is a short prompt. The ship, the rocks, the wrapping and the stars all arrive working. The judgement you supply is how much drag to put in, which is the one thing no model will choose well without being told.
Should space movement have friction?
In a game, yes. Real vacuum has none, and a ship with none is exhausting to aim, because stopping takes as much effort as starting. A small drag plus a ceiling on speed keeps the drifting feel while letting a player point the ship and have it go there.
Why does my ship vanish at the edge of the screen?
It is only being drawn at its real position. While an object straddles an edge, it has to be drawn a second time, offset by a whole screen width or height. Otherwise the part that has crossed over is missing until the centre crosses too.
Why is my ship faster diagonally?
The speed limit is being applied to the horizontal and vertical parts separately, so both can sit at the maximum at once. Measure the length of the velocity as a pair and scale both parts down together when that length goes over the cap.
Why do my stars flicker?
Their positions are being chosen inside the drawing code, so every frame gets a fresh sky. Work out each layer once when the game starts and keep those positions for the whole run, moving only the scroll offset.
How do I make a wrapped collision work?
Write one function that returns the distance between two points on a wrapping screen, taking the shorter of the direct gap and the gap round the edge, and use it everywhere. Raw subtraction will report two objects as far apart while they sit side by side across an edge.
Where to go next#
When the drag is right and you keep flying one more lap, put it up. The page it gets records which model wrote it and the prompt you used, and a leaderboard turns a survival timer into a reason for somebody else to try. Fly a few of the space games already here first and pay attention to how heavy each ship feels.
The method for getting from a broken first build to a working one is in how to make a game with AI. If you want the ship to shoot, the shooter guide covers bullet pools and hit boxes, which are a separate problem from movement. For bouncing, gravity and joints, read the physics guide, and the drawing side of a flat canvas is in the 2D guide.
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