AI game prompts that produce a playable game first try
A prompt that works is not a better description of your idea. It is a shorter description plus eight constraints, and the constraints are what stop you spending five passes undoing the model's guesses.
Jump to a section
The prompts on this page are complete. Copy one, send it as a single message to Claude, ChatGPT or Gemini, and you should get a working browser game in one file. Below them is a repair kit: one prompt for each of the faults a first build reliably ships with.
If you only take one thing, take the technical requirements block. Appending it to any game prompt pre-empts about half the second-pass work, and it is the same twelve lines every time.
Why most game prompts disappoint#
The usual first attempt is something like make a fun space shooter with cool powerups and great graphics. It returns something, and the something is not what you pictured. That is not the model failing. It is a prompt that described a feeling rather than a game.
Words like fun, cool and great carry no information a program can be built from, so the model fills the gaps with the statistically average choice. You then spend four passes replacing average choices with yours, which is slower than having stated them once.
| Instead of | Write | What it prevents |
|---|---|---|
| a fun space shooter | the player's ship is fixed at the bottom and moves left and right only | a twin-stick game when you wanted a fixed shooter |
| cool powerups | three powerups: spread shot for 8s, shield for one hit, double points for 10s | one powerup, or twelve, or none |
| great graphics | everything drawn with canvas shapes, no images, six-colour palette | a blank screen from references to sprite files that do not exist |
| it gets harder | enemy speed and spawn rate each rise 10% every 15 seconds | a game that is identical at minute ten |
| make it mobile friendly | drag anywhere to move, plus a fire button in the bottom right | a desktop game with a viewport meta tag |
| add sound | Web Audio oscillators, no audio files, resumed on first input | silent audio and a console warning |
Every row on the right is shorter to read than the paragraph it replaces. Specific is not the same as long.
The eight parts of a prompt that works#
The order matters slightly. Putting the container first stops the model reaching for a framework before it has read anything else, and putting persistence last means it is not forgotten in a long message.
The fill-in template#
Replace the bracketed parts. Everything else stays as it is, every time.
Build a complete browser game as ONE self-contained .html file.
No frameworks, no build step, no external files, no image or audio URLs.
CSS in a <style> tag, JavaScript in a <script> tag.
GAME: [one sentence: what the player does over and over]
CORE LOOP: [two or three sentences describing a single round from start to
end, in the order the player experiences it]
WIN / LOSE: [how a round ends badly, and how it ends well. If it is an
endless score chase, say so, and say what the player is chasing]
CONTROLS:
- Desktop: [name the actual keys]
- Touch: [name the actual gesture, and where any on-screen button sits]
SCREEN: [dimensions and how they scale] Show [what is on the HUD and where].
ART: Everything drawn with canvas shapes and colour. No external images.
[what each thing looks like, in one clause each]
Use a fixed palette of [n] colours defined once at the top.
DIFFICULTY: [what increases, by how much, how often, and any cap]
PERSISTENCE: [what is saved] in localStorage under the key "[game].[thing]".
TECHNICAL REQUIREMENTS:
- requestAnimationFrame with delta time in seconds, clamped to 0.05. Every
speed, timer, cooldown and spawn interval must be per-second, not per-frame.
- Size the canvas backing store to CSS size times devicePixelRatio (capped at
2) and use ctx.setTransform(dpr, 0, 0, dpr, 0, 0), not ctx.scale.
- CSS: canvas { touch-action: none; user-select: none; }
- Pause when document.hidden, and reset the frame clock on return.
- A title screen, a game-over screen, and restart without reloading the page.
Reset every variable that a run changes, including difficulty.
- Any audio via Web Audio oscillators, created or resumed inside the first
user interaction. No audio files.
- All tunable numbers in one CONFIG object at the top of the script.
Return the complete file and nothing else.
The technical requirements block is the reusable half. It is the same for every 2D game you will ever ask for, so keep it somewhere you can paste from.
The technical requirements block on its own#
If you already have a prompt you like, append this to it. Each line exists because leaving it out produces a specific, predictable fault.
TECHNICAL REQUIREMENTS:
- requestAnimationFrame with delta time in seconds, clamped to 0.05. Every
speed, timer, cooldown and spawn interval must be per-second, not per-frame.
- Size the canvas backing store to CSS size times devicePixelRatio (capped at
2) and use ctx.setTransform(dpr, 0, 0, dpr, 0, 0), not ctx.scale.
- CSS: canvas { touch-action: none; user-select: none; }
- Pause when document.hidden is true, and reset the frame clock on return.
- A title screen, a game-over screen, and restart without reloading the page.
Reset every variable that a run changes, including difficulty.
- Wrap every localStorage call in try/catch; it throws in private windows.
- Any audio via Web Audio oscillators, created or resumed inside the first
user interaction. No audio files.
- All tunable numbers in one CONFIG object at the top of the script.
Line two is the one that most changes the result. Frame-rate-dependent movement is the most common fault in AI-written games and it is invisible on the machine you tested on.
One object holding every speed, size, interval and colour turns tuning from a conversation into an edit. You stop asking the model to make enemies slower and start changing a number, which is instant and cannot break anything else in the file.
Ten complete game prompts#
Each one is a single message. Append the technical requirements block above to any of them. They are deliberately different shapes, so the one closest to your idea is a better starting point than the template.
1. Brick breaker#
Build a complete browser game as ONE self-contained .html file. Canvas 2D,
no libraries, no external files.
GAME: Bounce a ball off a paddle to clear a wall of bricks.
CORE LOOP: The paddle moves along the bottom. The ball bounces off walls,
bricks and the paddle. Clearing every brick ends the level and starts a
harder one. Missing the ball costs a life.
WIN / LOSE: Three lives. Ten levels; clearing all ten wins.
CONTROLS: Mouse or finger position sets the paddle position directly, so
the paddle follows without lag. Arrow keys as a fallback. Space launches.
SCREEN: 900x640, scaled to fit. Score top left, level centre, lives top right.
ART: Canvas shapes only. Bricks coloured by row from a six-colour palette.
The ball leaves a short fading trail.
BALL PHYSICS: Where the ball hits the paddle changes its horizontal angle,
so the edges steer it. Cap the bounce angle so it can never travel almost
horizontally and stall. Ball speed increases 4% per paddle hit, capped at
double the starting speed, and resets each level.
POWERUPS: 15% of bricks drop one when destroyed. Three types: wider paddle
for 12s, multi-ball splitting into three, and a slow-ball effect for 8s.
DIFFICULTY: Each level adds a brick row, raises starting ball speed 8%, and
from level 4 some bricks take two hits and are drawn cracked after the first.
PERSISTENCE: High score in localStorage under "breakout.best".
The angle cap is the important line. Without it a ball eventually ends up travelling nearly horizontally and the game stalls for thirty seconds, which is the classic brick breaker bug.
2. Sliding number puzzle#
Build a complete browser game as ONE self-contained .html file. Canvas 2D
or DOM, no libraries, no external files.
GAME: Slide numbered tiles on a 4x4 grid; equal tiles merge and double.
CORE LOOP: Every move slides all tiles as far as they can go in that
direction. Equal adjacent tiles merge into one of double the value. After
each move a new tile (90% a 2, 10% a 4) appears in a random empty cell.
WIN / LOSE: Reaching 2048 wins, with an option to keep playing. The game
ends when the grid is full and no merge is possible.
CONTROLS: Arrow keys or WASD. On touch, swipe in four directions with a
minimum 30px threshold so a tap is never read as a swipe.
SCREEN: Square board, centred, scaling to fit. Score and best above it.
ART: Rounded tiles, each value its own colour, dark text on light tiles and
light text on dark ones. No images.
RULES THAT ARE EASY TO GET WRONG:
- A tile that has merged this move cannot merge again in the same move.
- A move that changes nothing must not spawn a new tile and must not count.
- Merged values add to the score; nothing else does.
ANIMATION: Tiles slide to their new positions over about 120ms and merged
tiles pop briefly. Never redraw the board instantly with no transition.
PERSISTENCE: Best score in localStorage under "slide.best".
The three rules listed as easy to get wrong are the entire game. Buggy versions almost always break one of them, most often the double-merge.
3. Level-based platformer#
Build a complete browser game as ONE self-contained .html file. Canvas 2D,
no libraries, no external files.
GAME: Run and jump through five short levels to reach the flag.
CORE LOOP: The player runs, jumps between platforms, avoids two enemy types,
collects coins, and touches the flag to finish the level.
WIN / LOSE: Falling off the bottom or touching an enemy restarts the current
level. No lives; instant restart. Finishing level five wins. Track total time.
CONTROLS: Arrows or WASD to move, space or up to jump. Hold jump for a
higher jump. On touch, left and right buttons on the left and a jump button
on the right.
SCREEN: 960x540 with the camera following the player horizontally, clamped
to the level bounds. Level number, coins and elapsed time on the HUD.
LEVELS: Define levels as arrays of strings, one character per tile, with a
legend at the top of the file. This makes them editable by hand.
PLATFORMER FEEL, all required:
- Coyote time: jumping is allowed for 100ms after walking off an edge.
- Jump buffering: a jump pressed up to 120ms before landing still fires.
- Variable jump height: releasing early cuts upward velocity in half.
- Gravity is stronger while falling than while rising.
- Resolve horizontal and vertical collision separately, X then Y, so the
player never catches on the seam between two floor tiles.
ART: Canvas shapes. Tiles are flat rectangles with a lighter top edge.
PERSISTENCE: Best total time in localStorage under "platformer.best".
The five feel rules are why some platformers feel generous and others feel broken. They are rarely in a first build unless named, and they are the difference between the whole game feeling good or not.
4. Vertical space shooter#
Build a complete browser game as ONE self-contained .html file. Canvas 2D,
no libraries, no external files.
GAME: Fly a ship up a scrolling starfield, shooting waves of enemies.
CORE LOOP: The ship moves in all directions in the lower half of the screen
and fires upward automatically. Enemies arrive in patterned waves and fire
back. A boss arrives every fifth wave.
WIN / LOSE: Three lives, one lost per hit, with 1.5 seconds of flashing
invulnerability after each. Endless waves; the score is the goal.
CONTROLS: Arrows or WASD. On touch, drag anywhere to move; firing is
automatic on both. Shift or a second touch for a screen-clearing bomb, three
per life.
SCREEN: 640x900 portrait, letterboxed on wide screens. Score top left, lives
and bombs top right.
ART: Canvas shapes. Ship is a triangle, enemies are angular polygons, bullets
are short bright capsules. Three parallax starfield layers at different speeds
and brightnesses.
WAVES: Define waves as data, not code: a list of {enemyType, count, pattern,
delay}. Patterns are at least: a straight line down, a sine weave, and an arc
that sweeps across.
POWERUPS: Dropped by every tenth enemy: spread shot for 10s, rapid fire for
10s, an extra bomb.
DIFFICULTY: Every wave raises enemy speed 5% and enemy bullet speed 3%,
capped at double the start.
JUICE: Screen shake on player damage and boss hits, particle bursts on every
kill, 60ms hit stop when the player is hit.
PERSISTENCE: High score in localStorage under "shooter.best".
Asking for waves as data rather than code is what makes this one editable afterwards. You tune the game by adding rows to a list instead of describing a new wave to the model.
5. Idle clicker#
Build a complete browser game as ONE self-contained .html file. DOM-based
is fine here. No libraries, no external files.
GAME: Click to earn, then buy generators that earn for you.
CORE LOOP: Click a large button to gain 1 unit. Spend units on six generator
types that produce units per second automatically. Each purchase raises that
generator's cost by 15%, compounding.
WIN / LOSE: Neither. It is a progression game. Ten milestone achievements
mark progress, the last requiring roughly two hours of play.
CONTROLS: Click or tap. Holding the main button auto-clicks ten times per
second after 400ms.
SCREEN: A single column, working on a phone without horizontal scrolling.
Balance and per-second rate always visible at the top.
ART: No images. Coloured blocks, an emoji per generator, and a progress bar
per upgrade showing affordability.
NUMBERS: Use exponential-friendly formatting (1.00K, 1.00M, 1.00B, then
scientific past 1e15). Never print raw floats.
OFFLINE PROGRESS: On load, credit earnings for time elapsed since the last
save, at 50% rate, capped at 8 hours. Show what was earned in a dismissable
panel. Store the timestamp with the save.
UPGRADES: Each generator has three upgrades that double its output, unlocked
at 10, 50 and 200 owned.
PERSISTENCE: Save the whole game state to localStorage every 10 seconds and
on page hide, under "idle.save". Handle a missing or corrupt save by starting
fresh rather than throwing.
Offline progress and the corrupt-save fallback are the two things that turn a clicker demo into something people return to. Both are almost never in a first build.
6. One-button flyer#
Build a complete browser game as ONE self-contained .html file. Canvas 2D,
no libraries, no external files.
GAME: Tap to flap upward through gaps in oncoming obstacles.
CORE LOOP: The bird falls constantly. Each input gives it an upward impulse.
Pairs of pipes scroll in from the right with a gap to fly through. One point
per gap passed.
WIN / LOSE: Touching a pipe, the ground or the ceiling ends the run.
Endless; the score is the goal.
CONTROLS: One input only. Space, click, or tap anywhere. Nothing else.
SCREEN: 480x720 portrait, letterboxed. Score large and centred at the top.
ART: Canvas shapes. The bird rotates toward its velocity, nose up while
rising and steeply down while falling. Two parallax background layers and a
scrolling ground strip.
FEEL, all required:
- The first input starts the run; the bird hovers still on the title screen.
- A 300ms pause on death, with a flash and a hard shake, before the game-over
screen. The player must see what they hit.
- Gap position varies smoothly rather than jumping randomly, so consecutive
pipes are never impossible together.
- The gap narrows by 2px per point, to a floor of 120px.
PERSISTENCE: Best score in localStorage under "flyer.best". Show a "new best"
badge on the game-over screen when it is beaten.
The smoothly varying gap position is what stops the game generating impossible sequences. Purely random gaps produce runs that end unfairly, and players read that as the game being broken.
7. Falling blocks#
Build a complete browser game as ONE self-contained .html file. Canvas 2D,
no libraries, no external files.
GAME: Rotate and place falling tetromino pieces to complete horizontal lines.
CORE LOOP: A piece falls on a 10x20 grid. The player moves and rotates it
until it lands, then the next piece appears. Full rows clear and everything
above drops.
WIN / LOSE: The game ends when a new piece cannot be placed. Endless
otherwise.
CONTROLS: Left and right to move, up to rotate clockwise, Z to rotate
anticlockwise, down for soft drop, space for hard drop, C to hold. On touch:
swipe left and right to move, tap to rotate, swipe down to hard drop.
SCREEN: The well centred, next-piece and hold panels beside it, score, level
and lines below. Portrait-friendly.
ART: Canvas shapes. The seven standard piece colours. A faint grid, and a
ghost outline showing where the current piece will land.
RULES THAT MUST BE RIGHT:
- All seven pieces, each with its standard four rotation states.
- Wall kicks: if a rotation would overlap a wall or a block, try shifting one
cell left, then right, then up, before rejecting the rotation.
- A random bag of all seven pieces shuffled, not independent random picks, so
the player never waits twenty pieces for a line piece.
- Lock delay of 500ms after landing, reset by a successful move or rotation,
capped at 15 resets.
- Scoring: 100, 300, 500, 800 for one to four lines, multiplied by level.
DIFFICULTY: Level rises every 10 lines; fall speed increases each level.
PERSISTENCE: High score, top level and total lines in localStorage under
"blocks.best".
The random bag and wall kicks are what separate this from a version that feels arbitrary. Independent random pieces produce droughts that players experience as unfairness.
8. Word game#
Build a complete browser game as ONE self-contained .html file. DOM-based
is fine. No libraries, no external files, no dictionary API.
GAME: Make as many words as possible from seven letters before time runs out.
CORE LOOP: Seven letters are shown. The player types or taps letters to form
a word and submits. Valid words score by length and clear the input. Invalid
words shake and clear.
WIN / LOSE: Three minutes. The score is the goal. Show every word found at
the end, and the ones that were available but missed.
CONTROLS: Type directly, with Enter to submit and Backspace to delete. Tap
letters as an alternative. A shuffle button reorders the display.
SCREEN: Letters in a row or ring, the current word above, found words in a
scrolling list beside or below. Works on a phone.
WORD LIST: Embed a list of about 2000 common English words of 3 to 7 letters
directly in the file as an array. Do not call any API. Generate letter sets
by picking a 7-letter word from the list and shuffling it, so at least one
long word is always possible.
SCORING: 3 letters = 100, 4 = 400, 5 = 800, 6 = 1400, 7 = 2200, plus a 500
bonus for using all seven letters.
RULES: A letter may be used only as many times as it appears in the set.
Words already found score nothing and say so.
PERSISTENCE: Best score in localStorage under "words.best".
Generating the letter set by shuffling a real seven-letter word is the trick that guarantees the round is solvable. Random letters produce sets with no long word and the round feels broken.
9. Top-down racer#
Build a complete browser game as ONE self-contained .html file. Canvas 2D,
no libraries, no external files.
GAME: Drive three laps of a closed circuit against four AI cars.
CORE LOOP: Accelerate, brake and steer around a track seen from above. The
camera follows the car and rotates with it. Cutting the track is penalised.
WIN / LOSE: Three laps. Finishing first wins; the finishing position and lap
times are shown either way.
CONTROLS: Up or W accelerates, down or S brakes and reverses, left and right
steer. On touch, a pedal button on the right and a steering slider on the
left.
SCREEN: 960x600, camera following and rotating with the car. Lap counter,
position, current lap time and best lap on the HUD.
TRACK: Defined as an array of centre-line points with a width, so the shape
is editable. Draw the surface, a kerb, and a start line from that data.
DRIVING MODEL: Not a physics engine. Forward velocity with acceleration and
drag, steering that scales with speed so the car barely turns when stopped,
and lateral grip that lets the back step out under hard cornering. Off the
track surface, grip and top speed drop by 45%.
AI: Four cars following the centre line with a lookahead point, each with
slightly different top speed and cornering, and simple avoidance of cars
directly ahead. They must be beatable but not trivial.
PERSISTENCE: Best lap and best race time in localStorage under "racer.best".
Steering that scales with speed is the single line that makes a top-down car feel like a car instead of a sliding rectangle.
10. Roguelike dungeon crawl#
Build a complete browser game as ONE self-contained .html file. Canvas 2D,
no libraries, no external files.
GAME: Descend through procedurally generated dungeon floors, fighting and
collecting, until you die.
CORE LOOP: Turn-based grid movement. Moving into a monster attacks it.
Monsters move when the player moves. Find the stairs to descend. Death ends
the run and everything restarts.
WIN / LOSE: Reaching floor 10 wins. Zero health ends the run. Show the floor
reached, monsters killed and gold collected.
CONTROLS: Arrows or WASD to move and attack. On touch, tap an adjacent tile
to move there, or use an on-screen four-way pad. Space or a button to wait
one turn.
SCREEN: A grid of about 40x24 tiles, camera centred on the player. Health,
floor, gold and a three-line message log on the HUD.
GENERATION: Rooms placed without overlapping, connected by L-shaped
corridors. Every floor must be fully connected; verify by flood fill from
the start and regenerate if any room is unreachable.
CONTENT: Three monster types with different health, damage and speed. Health
potions, gold, and a weapon upgrade found roughly once every two floors.
Monster count and strength scale with floor depth.
VISIBILITY: Simple field of view. Tiles the player has seen stay dimly drawn;
tiles currently visible are drawn fully; unseen tiles are black.
ART: Canvas shapes and single letters for entities, in the classic style. No
images.
PERSISTENCE: Deepest floor reached in localStorage under "rogue.best".
The flood-fill check is the line that matters. Without it some floors generate with the stairs walled off, and a player who cannot finish a floor reads that as broken rather than unlucky.
🎮Games made with AI, and the prompts behind them
Every page here shows the prompt, the model and the token count that produced the game.The repair kit#
Once the first build exists, these are the follow-ups. Send one at a time, and play between each. Fixing several at once means a regression cannot be attributed to a change. When the fault is something you can see, paste a screenshot with the prompt: there is a guide to taking a useful one.
It does not work on a phone#
The game does not work on a phone. Add touch support:
- Use pointer events (pointerdown, pointermove, pointerup, pointercancel),
not separate mouse and touch handlers.
- Add CSS: canvas { touch-action: none; user-select: none; }
Without touch-action: none, dragging scrolls the page instead of playing.
- [describe the gesture: e.g. drag anywhere to move horizontally]
- Draw on-screen buttons only when a touch input has been detected, so
desktop players never see them.
- Make every tap target at least 44 by 44 CSS pixels.
- Add <meta name="viewport" content="width=device-width, initial-scale=1,
viewport-fit=cover"> and make sure the canvas fits without page scrolling.
Return only the changed parts, with enough surrounding context to place them.
It runs at the wrong speed on other machines#
Movement is tied to frame rate, so the game runs at a different speed on
displays that are not 60Hz. Convert the whole game to delta time:
- Compute dt in seconds from requestAnimationFrame's timestamp, and clamp it
with Math.min(dt, 0.05).
- Multiply EVERY speed, acceleration, timer, cooldown, spawn interval and
animation duration by dt. Do not convert only the obvious movement and
leave the timers counting frames.
- Express the constants in units per second and say so in a comment, so
"speed: 180" reads as 180 pixels per second.
- Any exponential damping such as v *= 0.9 must become
v *= Math.pow(0.9, dt * 60), or it is also frame-rate dependent.
- On visibilitychange back to visible, reset the frame clock before the next
frame so there is never one enormous step.
List every constant you converted and its new per-second value.
The last instruction is worth including. Asking for the list is how you find the three timers it silently skipped.
The canvas is soft#
The canvas is blurry on high-density screens. Fix the backing store:
- In a resize() function, read the canvas's CSS size with
getBoundingClientRect(), set canvas.width and canvas.height to that size
multiplied by Math.min(devicePixelRatio, 2), and then call
ctx.setTransform(dpr, 0, 0, dpr, 0, 0).
- Use setTransform, NOT ctx.scale. scale() multiplies onto the existing
transform, so calling resize() a second time doubles everything.
- Keep all game coordinates in CSS pixels; only the transform changes.
- Call resize() once at start and on every window resize and orientation
change.
You cannot restart#
Add proper game states:
- A single mode variable: 'title' | 'playing' | 'paused' | 'dead'.
- A title screen naming the controls, and a game-over screen showing the
score, the best score, and how to play again.
- Restart with one key or tap, without reloading the page.
- A reset() function that restores EVERY variable a run changes: score,
lives, elapsed time, difficulty, spawn rate, all entity arrays, all
timers and cooldowns.
- Guard the update function so nothing simulates unless mode is 'playing'.
Then confirm: after losing and restarting, does the second run begin at the
same difficulty as the first? List anything that carried over.
The final question is the point. Difficulty carrying over into run two is the most common bug introduced by adding a restart.
There is no sound#
Add sound effects using the Web Audio API only. No audio files or URLs.
- Create the AudioContext lazily, inside the first click, tap or keypress,
and call resume() on it there. Browsers block audio before a user gesture,
so creating it on page load produces silence.
- Write one small helper that plays a tone: frequency, duration, waveform
and volume envelope with a short attack and exponential release. Then build
every effect from it.
- Effects needed: [list them, e.g. shoot, hit, explode, pickup, game over]
- Keep the master gain low, around 0.15, and add a mute toggle that persists
in localStorage.
- Never play more than about six voices at once; drop the oldest.
The score disappears#
Persist the best score:
- Save and load from localStorage under a namespaced key, "[game].best",
not a bare key like "best".
- Wrap every read and write in try/catch. localStorage throws in private
windows and when a browser is set to block site data, and an unguarded
read stops the game from starting at all.
- If the stored value is missing or not a number, fall back to 0 rather than
producing NaN.
- Show a "new best" indicator on the game-over screen when it is beaten.
It keeps running in a background tab#
The game keeps simulating in a background tab, which drains battery and
produces one enormous step on return.
- On visibilitychange, when document.hidden is true, cancel the animation
frame and stop updating.
- When it becomes visible again, reset the frame clock to the current time
BEFORE requesting the next frame, then resume.
- If the game was mid-play, resume into a paused state with a "tap to
continue" overlay rather than straight back into play. Returning to a game
already in motion loses the player a life.
It is the same at minute five#
The game does not get harder. Add a real curve:
- Define it as data in CONFIG, not scattered through the code: what
increases, by what percentage, how often, and its cap.
- [name the two or three things that should scale, e.g. spawn rate, enemy
speed, projectile speed]
- Introduce one new element at a fixed time, around 45 seconds, so there is
a change in kind and not only in degree.
- Cap everything, so the game becomes hard rather than impossible.
- Reset all of it in reset().
Then tell me what minute one, minute three and minute five each feel like
under these numbers.
That closing question makes the model reason about pacing rather than just multiplying numbers, and it usually catches a curve that goes vertical at ninety seconds.
Two prompts for the second hour#
Once the faults are fixed, these two are what turn a working game into one people finish.
The game works correctly. Now add game feel. Change no rules:
1. Acceleration and friction on player movement instead of instant velocity.
Use frame-rate-independent damping.
2. Screen shake on impacts, scaled to the impact, decaying over ~200ms.
Apply it before drawing the world and restore before drawing the HUD, so
the HUD never shakes.
3. A burst of 8 to 12 particles wherever something is destroyed.
4. Hit stop: freeze the simulation for 60ms on a significant hit.
5. The score counts up to its new value over ~300ms rather than jumping.
6. A brief flash on anything that takes damage.
7. Ease every UI transition; nothing appears or disappears instantly.
Keep all new numbers in CONFIG. Return the complete file.
Final pass before publishing. Do not change gameplay:
- Make sure the whole game is readable on a 360px-wide phone screen: font
sizes, HUD spacing, tap targets.
- Add a short "how to play" panel on the title screen: three lines maximum,
showing controls for both keyboard and touch.
- Add a mute toggle that persists, and a pause key.
- Make sure no console errors or warnings appear during a full round,
including at game over and on restart.
- Check every string for typos and make the game-over screen state the score
plainly.
- Add a <title> and a meta description to the head.
Then list anything you noticed that is still rough but that I did not ask
about.
The last line is the most useful sentence in the whole kit. Models will name real problems when asked directly, and they will not volunteer them otherwise.
What not to ask for#
- External images, sprites or audio files. Given permission, a model will reference files that do not exist and you get a blank screen with no error. Say no external files explicitly.
- A framework, on a first build. A CDN link is a dependency that can fail to load, and a half-remembered API version produces a file that throws nothing and renders nothing.
- Multiplayer, in the first prompt. Networking multiplies the surface area for subtle bugs, and none of them are visible when you test alone.
- Everything at once. A prompt asking for a game plus sound plus particles plus five levels plus a shop returns a shallow version of all five. Build the game, then add one layer per pass.
- "Make it fun." There is nothing to act on. Say what should change: pacing, difficulty, feedback on hits, or variety of situations.
- A full rewrite when something breaks. You lose every fix already landed. Ask for the one broken function instead.
Does the model matter?#
Less than people expect on the first build, and more than people expect by the tenth message. Single-file browser games are well represented in every frontier model's training data, so the first result is rarely where they differ.
The differences show up in the second hour. Holding a four-hundred-line file across a dozen edits, returning a patch rather than a silent rewrite, and not quietly reverting a fix from three messages ago. That is what decides how long the work takes, and no first-pass comparison can show it.
Rather than trust a claim about it, the made-with pages list the real games each model produced here, with the prompt and token count for each. Play a few and judge for yourself.
🔥Survival and endless games to compare against
A good target for a first build: one screen, one input, one escalating threat.Common questions#
What is a good prompt to make a game with AI?
One that specifies eight things. The output is a single self-contained HTML file. The core loop, in one sentence. Both the win and the lose condition. The exact controls, for keyboard and for touch. The screen size and what is on the HUD. The art budget, meaning canvas shapes and no external images. What gets harder, and how fast. And what is saved. Anything left out is chosen for you, and roughly half of those choices need a round trip to undo.
Why does my AI-generated game not work on mobile?
Usually two things. There are no pointer event handlers at all, because the desktop version worked and nothing signalled the gap. And the CSS is missing touch-action: none on the canvas, without which the browser treats every drag as a page scroll and your game never receives it. Both are in the touch repair prompt above.
How long should a game prompt be?
About 300 to 500 words for a complete first build. Shorter and the model fills gaps with average choices. Much longer and you are usually describing several games at once, which returns a shallow version of each. Specific is not the same as long: 'the ship is fixed at the bottom and moves left and right only' is shorter than 'a fun space shooter' is vague.
Should I use one long prompt or several short ones?
One long prompt for the first build, then one short prompt per change. The first build benefits from complete context, because the model is making structural decisions. After that, a message that changes one thing means any regression is attributable to the change you just made.
Do these prompts work with ChatGPT, Claude and Gemini?
Yes. They are plain specifications with no model-specific syntax, and building a single-file browser game is a task every current frontier model handles. Differences show up in long iteration rather than in the first response.
The model gave me code that does not run. What now?
Open the browser console and paste the exact error text, including the line number, back into the chat. Add one sentence saying what you expected and what happened. That is nearly always enough. Describing it as 'it does not work' costs an extra round trip while the model guesses.
Can I use these prompts to make a game to sell?
Generally yes, though the terms of the specific tool you used govern it, so read them. The harder problem is that a game built in an afternoon competes with every other game built in an afternoon, so distribution matters more than the licence does.
Where to go next#
The method behind these prompts, including the brief and the iteration loop, is in how to make a game with AI. The code the repair prompts produce is explained in the 2D guide, and the 3D guide covers three.js.
When one of these turns into something worth playing, put it on Agent Games. Your prompt goes on the page with it, which is how the next person finds a prompt that works.
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