The easiest way to make a game with AI is to have a coding agent write a small browser game with HTML canvas or Phaser, play every change in the browser right away, and tune the “feel” yourself, because that’s the part the agent can’t judge. For bigger 2D or 3D projects, Godot is a good next step. When you’re done, you can put the game on itch.io and share it within minutes.
This post takes a first game from an empty folder to a published page: which tool I pick and why, the first prompt I give the agent, the game loop, art and sound (including licences), tuning game feel, playtesting and itch.io.
Why games are a great fit for vibe coding
Games are one of the most fun and instructive things to build with vibe coding. Results are instant: change a number and the character jumps higher. A small game is only a few files, so the agent can keep all of it in context.
There’s one trap, though. “It runs” and “it’s fun to play” are very far apart. The agent can check whether the code works; it can’t check whether the game is fun. That part is yours.
Which tool: canvas, Phaser, Godot or Unity
| Tool | Language | Good for | Working with an agent |
|---|---|---|---|
| HTML canvas | JavaScript | Very simple games, learning | Very easy; everything can live in one file |
| Phaser | JavaScript / TypeScript | 2D browser games | Easy; physics, scenes and animation built in, lots of examples |
| Godot | GDScript (or C#) | Bigger 2D, 3D, desktop and web export | Good; scenes are .tscn text files |
| Unity | C# | Large 3D, mobile, consoles | Good for code, weak for scenes |
For a first game I recommend Phaser. Plain canvas works too, but having the agent write collision, sprite animation and input handling from scratch takes time; Phaser gives you those. And everything is a text file running in a browser, so there’s no editor the agent can’t see.
Move to Godot when the game grows: many scenes, complex level design, 3D or a desktop build. Godot’s scene files (.tscn) and resources (.tres) are readable text, so the agent can edit them. Still, I lay out scenes in the editor myself and leave the GDScript to the agent; a small mistake in a hand-edited scene file can stop the editor from opening it.
Unity is powerful but the most awkward option to drive with an agent. The agent writes C# scripts comfortably; scenes, prefabs and inspector settings live in the editor. If you already know Unity, use it; for a first game it’s not my pick.
Step 1: Setup
What you need:
- Node.js and a package manager
- A coding agent: Claude Code, Codex, Gemini CLI, opencode or similar
- Git, so you can always get back to “it worked yesterday”
Start a project with Vite and add Phaser:
npm create vite@latest cactus-run -- --template vanilla-ts
cd cactus-run
npm install
npm install phaser
git init && git add -A && git commit -m "initial scaffold"
npm run dev
npm run dev prints a local address; open it to see the game, and the page reloads as the agent edits files.
Step 2: The first prompt
The first prompt matters a lot for games, because “make a game” gets you the game the agent imagines. Keep the scope small and concrete:
This is a Vite + TypeScript project with Phaser installed. We're
building a simple endless runner.
Game:
- The player runs left to right and jumps with space or a tap.
- Cacti come in from the right; touching one ends the game.
- Score increases over time and shows in the top right.
- On game over, show "Press space to restart".
Rules:
- Use coloured rectangles instead of art for now.
- Put every tunable number (gravity, jump velocity, game speed,
cactus spacing) in a single object in src/config.ts.
- Use Arcade physics.
- The game is 800x400 and scales to fit the screen.
- npx tsc --noEmit must pass.
- When done, explain the file structure and the values in config.ts.
The most valuable rule here is config.ts. You’ll tune the feel by playing with the numbers in that file; if they’re scattered through the code, every tweak means a trip back to the agent.
The “rectangles instead of art” rule matters too. Get the gameplay right first, then make it pretty. A beautiful prototype that isn’t fun is the worst outcome.
Step 3: Understand the game loop
At the heart of every game is a loop: read input, update the world, draw the screen, repeat, dozens of times a second. Phaser runs this for you and calls your scene’s update(time, delta) every frame. With plain canvas you write it yourself:
let last = performance.now()
function loop(now) {
const dt = (now - last) / 1000 // seconds since the last frame
last = now
update(dt)
draw()
requestAnimationFrame(loop)
}
requestAnimationFrame(loop)
The one concept to know is dt: move things based on elapsed time, not per frame. Agents sometimes write x += 5, and then the game runs faster on a high-refresh-rate screen. If you don’t see dt in the movement code, ask the agent about it.
Step 4: Play, iterate, commit
The loop:
- Play for a minute.
- Describe what you felt, concretely: “The jump hangs in the air too long; dodging cacti is too easy.”
- Let the agent change it, then play again.
- Commit every version that feels good.
Paste browser console errors (F12) into the agent verbatim. For visual problems, send a screenshot.
One warning: don’t grow the game logic in one big request. “Add power-ups, a boss fight and a level system” tangles all three together. One mechanic at a time.
Step 5: Game feel
What makes a game feel good is usually not big features but small details. Agents won’t add these unprompted, but they implement them well when asked:
- Coyote time: allow a jump for a brief moment after running off a ledge.
- Jump buffering: remember a jump pressed just before landing.
- Variable jump height: cut the upward speed when the button is released.
- Screen shake and hit stop: freeze for a few frames on impact.
- Tweens: the score popping, an enemy wobbling as it disappears.
- Sound: a short jump sound changes the feel more than anything on screen.
This is the kind of prompt I use:
Improve the jump feel:
- Add 100 ms of coyote time and a 100 ms jump buffer.
- If space is released early, halve the upward velocity.
- On collision, add an 80 ms hit stop and a light screen shake.
Put all durations in config.ts. Don't change any other behaviour.
Then play with the numbers in config.ts yourself. This part can’t be handed off to an AI; you only feel a few milliseconds of difference while playing.
Step 6: Art, sound and licences
Once the gameplay is good, swap the rectangles for real art. The one thing to be careful about is licensing.
Ready-made packs:
- Many packs from sources like Kenney are CC0, usable without even attribution.
- On OpenGameArt every file has its own licence (CC0, CC‑BY, CC‑BY‑SA, GPL…). CC‑BY requires attribution; CC‑BY‑SA may require you to share derivative work under the same licence. Read each file’s licence.
- Paid and free asset packs on itch.io each come with their own licence; check whether commercial use is allowed.
Keep a CREDITS.md or an in-game credits screen listing every asset’s source and licence.
AI-generated art is fast and tempting, but a few caveats:
- The copyright status of AI-generated content varies by country and some questions are still unsettled.
- Every image tool has its own terms of use; check commercial use.
- Some game stores ask you to disclose AI-generated content.
- It’s technically fiddly too: style consistency, sprite sheet layout and matching animation frames often need manual cleanup.
My approach: openly licensed packs for the prototype; for release, art I made myself or whose licence I know for sure.
There is asset work the agent does well: loading a sprite sheet into Phaser, defining animations, wiring up sound files. Give it the file names and frame size instead of letting it guess.
Step 7: Playtesting
The person who built the game is its worst tester; they already know what to do. The same goes for the agent. What to do:
- Hand the game to someone and explain nothing. Watch quietly where they get stuck.
- Take notes: where they died, where they got bored, what they misunderstood.
- Turn those notes into tasks for the agent: “Players always hit the first cactus; no cacti in the first 5 seconds.”
Small pieces of game logic (scoring, collision rules) can be checked with unit tests; ask the agent to write them. The feel you can only test by playing.
Step 8: Publishing on itch.io
Putting a browser game on itch.io takes a few minutes:
npm run build
cd dist && zip -r ../cactus-run.zip . && cd ..
Then create a new project on itch.io, set its kind to HTML, upload the zip and mark it as playable in the browser. Set the viewport size (800×400, for example) and the fullscreen button. The zip needs index.html at its root; with Vite you may need base: './' in vite.config.ts for relative paths, which the agent can check for you.
In Godot, install the Web export template, export to HTML5 and upload the same way. If you’ll be updating often, itch.io’s butler command-line tool automates uploads.
What agents commonly get wrong in games
- They can’t see the game. The agent writes code but doesn’t know what’s on screen. Screenshots or a description of what you see are essential.
- Magic numbers. Values get scattered through the code. Repeat the
config.tsrule with every new mechanic. - Frame-dependent movement. Without
dt, the game runs at different speeds on different screens. - Outdated APIs. Phaser and Godot changed APIs between major versions, and the agent may write code for the old one. Tell it the version: “We’re on Godot 4, don’t write Godot 3 syntax.”
- Everything in one file. As the game grows, ask it to split scenes, entities and settings into separate files.
- Ignoring performance. With hundreds of bullets or enemies the game slows down. Ask for object pooling.
Security
A game looks harmless, but the same rules apply:
- If you add a leaderboard or a multiplayer backend, keep keys in
.envand add.envto.gitignore. - Everything in a browser game can be read by the player; secret keys never go in client code.
- Don’t paste API keys into the chat; tell the agent which environment variable to read.
- Read the commands the agent runs before approving them, especially package installs and deletes.
- Don’t trust scores sent from the client; cheating an online leaderboard is easy.
Doing it with AgentVera
All of this works with a terminal and a browser. On game projects I like running a few agents side by side and seeing the result in the same window, which is why I use AgentVera:
- Separate experiments in separate worktrees. One agent works on jump feel in one git worktree while another adds a new enemy type in a second; drop the experiment you don’t like. The Git panel shows the branches.
- The agent browser. With the agent browser, the agent can open the game through Playwright and take screenshots while you watch the tab live. That partly solves “the agent can’t see the game”; it doesn’t solve feel.
- Terminal and editor.
npm run devstays open in one pane and you editconfig.tsyourself in the editor. - Review and tokens. Code review checks each turn before you merge, and token use is visible per pane.
AgentVera isn’t a game engine; it doesn’t replace the Godot editor or itch.io.
Quick checklist
- The first game is small: one mechanic, one screen
- Tunable numbers live in
config.ts - Movement uses
dt - Gameplay with rectangles first, art second
- Every asset’s source and licence written down
- At least one person played it without explanation
- The itch.io zip has
index.htmlat its root
Wrapping up
Making a game with AI is one of the most enjoyable uses of vibe coding. Start small with Phaser in the browser, keep the numbers in one file, get the gameplay right with rectangles, tune the feel with your own hands and watch the licences. The agent writes the code; you’re the one who makes it fun. To run experiments with several agents, see parallel coding agents; for choosing a tool, see the best AI coding CLI tools.