Guide 1 of 3
How to make a browser game with AI
A working process, not a prompt list: scoping something you can finish, picking a stack, the prompting patterns that hold up on game code, and the debugging loop that gets you to playable.
On this page8 sections
The hard part of making a game with AI help has never been getting code out of the model. You can have a playable prototype in twenty minutes. The hard part is that a game is a thousand small taste decisions stacked on top of each other, and a tool that writes code fast makes it very easy to stack them badly and very fast.
This guide is the process that survives that. It assumes you can read JavaScript and open a terminal, and it assumes you want to finish something this month rather than start something impressive.
Scope it so you can finish
Almost every abandoned project on this site died of scope, not of difficulty. The way out is to define the game as one verb and one twist, and to write both down before you open an editor.
The verb is what the player does with their hands, forty times a minute: jump, place a tile, aim, drag, type a word, choose a card. The twist is the one thing about your version that is not the default. That is the whole design document.
- You place tiles, and every tile you place removes one from a shared pool your opponent draws from.
- You run right and jump, but the level is a recording of your last three attempts, playing back around you.
- You guess a word, and each wrong guess permanently deletes that letter from the game for everyone, today.
Now write the cut list. Not features you will add later, but features you are actively refusing. For a weekend game that is usually: no accounts, no save system beyond localStorage, no settings menu, no tutorial, no more than one enemy type, no music. Give that list to your assistant at the start of the project and repeat it whenever it offers you a feature; models are relentlessly helpful and will happily build you a settings screen you did not ask for.
Pick a stack
This decision matters more than which assistant you use, because it sets your bundle size, your load time, and how much of the game you are writing yourself. There is no best answer; there is a right answer for the game you just described.
| Compare | Vanilla canvasNo engine, just the 2D context | Phaser2D game framework | Three.jsWebGL 3D |
|---|---|---|---|
| Payload | ~0 KB. Your game is the only payload. | ~300–400 KB before your code or art. | ~150 KB core, but models, textures and a loader add up fast. |
| What you get | Drawing primitives and an input event or two. That is the entire API surface. | Scenes, arcade and matter physics, sprite atlases, tweens, input, audio, a tilemap loader. A real framework. | Scene graph, cameras, lights, materials, model loading, post-processing. |
| What you still write | The loop, collision, state machine, asset loading, audio, scaling for DPI. All of it, but all of it is small. | Game logic and level data. The plumbing is done and mostly done well. | Everything game-shaped: physics, controls, collision, UI. It is a renderer, not a game engine. |
| How AI does with it | Best. Models have seen enormous amounts of plain canvas code and there is no API version drift to get wrong. | Good, with a catch. Assistants routinely mix Phaser 2 and 3 idioms. Pin the version in your first prompt and paste the scene skeleton you want. | Mixed. Fine for scene setup and shaders, weak on the parts it cannot see. Anything about how the camera feels needs you. |
| Where it hurts | Around the point you need a physics engine, a tilemap importer or a particle system, you are writing an engine badly. | 3D, and any game where 400 KB of framework is a meaningful fraction of your load budget. | Low-end phones. A scene that runs at 60fps on a laptop can land at 20 on a three-year-old Android. |
| Pick it when | One screen, one mechanic, and you care about the game loading before the tab finishes animating. | A platformer, a top-down game, anything with tiles, physics or more than three scenes. | The game genuinely needs a third dimension, not because 3D looks more impressive in a screenshot. |
The three stacks that cover almost every browser game. Numbers are minified and gzipped, measured on real projects rather than taken from a homepage.
No engine, just the 2D context
- Payload
- ~0 KB. Your game is the only payload.
- What you get
- Drawing primitives and an input event or two. That is the entire API surface.
- What you still write
- The loop, collision, state machine, asset loading, audio, scaling for DPI. All of it, but all of it is small.
- How AI does with it
- Best. Models have seen enormous amounts of plain canvas code and there is no API version drift to get wrong.
- Where it hurts
- Around the point you need a physics engine, a tilemap importer or a particle system, you are writing an engine badly.
Pick it when: One screen, one mechanic, and you care about the game loading before the tab finishes animating.
2D game framework
- Payload
- ~300–400 KB before your code or art.
- What you get
- Scenes, arcade and matter physics, sprite atlases, tweens, input, audio, a tilemap loader. A real framework.
- What you still write
- Game logic and level data. The plumbing is done and mostly done well.
- How AI does with it
- Good, with a catch. Assistants routinely mix Phaser 2 and 3 idioms. Pin the version in your first prompt and paste the scene skeleton you want.
- Where it hurts
- 3D, and any game where 400 KB of framework is a meaningful fraction of your load budget.
Pick it when: A platformer, a top-down game, anything with tiles, physics or more than three scenes.
WebGL 3D
- Payload
- ~150 KB core, but models, textures and a loader add up fast.
- What you get
- Scene graph, cameras, lights, materials, model loading, post-processing.
- What you still write
- Everything game-shaped: physics, controls, collision, UI. It is a renderer, not a game engine.
- How AI does with it
- Mixed. Fine for scene setup and shaders, weak on the parts it cannot see. Anything about how the camera feels needs you.
- Where it hurts
- Low-end phones. A scene that runs at 60fps on a laptop can land at 20 on a three-year-old Android.
Pick it when: The game genuinely needs a third dimension, not because 3D looks more impressive in a screenshot.
Two things that are not on the table. React is a fine choice for card games, idle games and anything that is mostly UI, and a poor one for anything with a per-frame render loop. And Godot or Unity exports reach the browser but arrive with a payload measured in megabytes, which changes the launch maths completely. If you are going that way, read the publishing guide first, because load time is the whole ballgame.
Browse games built on vanilla canvas and games built on Phaser before you decide. The bundle size difference is visible from the front page: the canvas games are the ones that are already playable by the time you look up.
Prompting patterns that hold up
Specific prompts age badly, so here are the four patterns that have not changed regardless of which model is in front.
Ask for the skeleton before the behaviour
First promptDo not ask for a game. Ask for the shape of one, agree on it, then fill it in. The difference in how the next six hours go is enormous.
“Give me the file structure and the empty game loop for a 2D canvas game with a fixed timestep, a state machine for menu / playing / dead, and an input module. No gameplay yet. Explain what each file owns in one line.”
Describe the feel with numbers
Every gameplay prompt“Make the jump feel better” produces a coin flip. Physical quantities produce the thing you meant.
“Jump apex at 2.2 tiles, rise 0.28s, fall 1.6× faster than the rise, 6 frames of coyote time, 8 frames of input buffering, cut the jump short if the button releases before apex.” That is a spec, and it is also, roughly, why Celeste feels good.
One system per message
ThroughoutSpawning, then scoring, then juice. Never all three. A message that touches three files produces a diff you will not read, and unread diffs are how a working game quietly stops working. Say which file may change and hold the model to it.
Make it explain before it edits
When stuckWhen a bug survives two attempts, stop asking for fixes. “Do not change any code. List the three most likely causes of this behaviour and tell me what I would see in the console for each.” Half the time the act of enumerating finds it, and the other half you learn what to look for.
The debugging loop
This is where projects are actually won. The loop is four steps and the discipline is refusing to skip step one.
- Play the build. Every change. Not “read the diff and assume”. Play it, for thirty seconds, with your hands. Games have a failure mode code review cannot catch: it runs perfectly and it is not fun.
- Paste the real error. The full stack trace, the line that threw, and what you did to cause it. Describing an error in prose loses the exact information that would have solved it.
- Commit when it runs. Not when it is finished, but when it runs.
git commit -am "enemies spawn, still no collision"is a perfectly good commit. You want a trail of working states to fall back to. - Revert instead of arguing. If two attempts at a fix have both made it worse, the third will too.
git checkout .and describe the goal differently from a clean slate.
Add an on-screen debug overlay in the first hour: frame time, entity count, current state, and whatever number your mechanic hinges on. It costs ten lines, it makes every future bug a factual conversation, and you can paste a screenshot of it into a prompt.
Assets and audio
Build the entire game on coloured rectangles. Seriously. A rectangle that moves well is a better game than a beautiful sprite that does not, and you will find out which you have much sooner. Art last is not a shortcut, it is a filter.
When you do replace the primitives: a limited palette will do more for how your game looks than any single asset. Four colours consistently applied reads as a style; sixteen colours reads as a placeholder. Kenney and the OpenGameArt CC0 collections cover most needs, and both are perfectly acceptable on a launched game as long as you credit them.
Audio is the highest-leverage thing you are skipping. A 3KB blip on a successful action changes how a game feels more than a week of art. Generate effects with a tool like jsfxr, keep them under a dozen, and mix them quietly. The most common audio bug in a launched browser game is that it is far too loud on the first click. Mute by default is defensible for music. It is not defensible for the sound that tells you a hit landed.
Mobile and performance
A meaningful share of the people who open your game will do it on a phone, on a connection that is not your home wifi. Two budgets keep you honest.
The load budget. First playable frame in under three seconds on a mid-range phone over 4G. That is roughly 500 KB of total transfer for a game with no streaming. Every megabyte past that costs you players in a way you will never see, because they leave before anything records that they arrived.
The frame budget. 16 milliseconds. Test on the worst device you own, not the best. Three things blow it in almost every browser game: allocating objects inside the game loop (pool them), drawing off-screen entities (cull them), and rebuilding a canvas gradient or shadow every frame (cache it).
Then the mobile-specific list, which nobody remembers first time:
- Touch targets of at least 44 CSS pixels, and controls positioned away from where a thumb rests.
touch-action: noneon the canvas, or every swipe scrolls the page instead of moving your character.- Handle the resize that happens when the browser chrome hides mid-game. Use
visualViewport, notwindow.innerHeight. - Scale for device pixel ratio, then cap it at 2. Rendering a canvas at 3× on a phone is how you turn a simple game into a slideshow.
- Pause on
visibilitychange. A backgrounded tab that keeps simulating drains a battery and produces a wild catch-up frame when it returns.
If your game genuinely cannot work on a touchscreen, that is fine. Say so in the listing and tag it accordingly. Players are far more annoyed by a game that claims to be mobile-friendly and is not than by one that is honest about needing a keyboard.
Shipping it
A game that only runs on localhost is not finished, it is paused. The next guide covers hosting properly (where to put it, what a custom domain buys you, and what to do about embedding), but the short version is that a static host and a real URL take about fifteen minutes and cost nothing.
Before you call it done, the five-minute check that catches most of it:
- Open it in a private window with no cache and no localStorage.
- Play it once on a phone, once on a trackpad, once with a keyboard.
- Die, restart, and confirm the restart is instant. It is never instant the first time.
- Turn the volume up to a normal level and check nothing is deafening.
- Have one person who has never seen it play it while you say nothing.
That last one is worth more than every other item combined, and it is the one everybody skips. Watch where their hands stop moving.
Then put it somewhere. Games in arcade, puzzle and experimental are the ones a weekend project most often lands in, and a launch there costs you nothing but an evening of being present in a reviews.