# How to build a playable browser game with AI

Canonical: https://uvilno.com/guides/how-to-build-a-playable-browser-game-with-ai
Updated: 2026-10-27

Specify a real game loop, responsive controls, fair rules, and browser-local progress. Measure performance and test playability before sharing.

Written by the Uvilno team. Examples illustrate workflows; confirm service availability before launch.

## Describe a playable loop rather than a genre label

A game brief needs a repeated action, feedback, a challenge, and a reason to try again. ‘Make an arcade game’ leaves all four unresolved. Describe what the player does in the first few seconds: move toward a parcel, avoid debris, return to a station, and earn points. Then define the pressure that makes the choice interesting. It might be limited time, a gradually busier arena, or a tradeoff between a safe route and a valuable pickup.

Keep the first project small enough to test completely. One arena, one movement system, and a handful of meaningful obstacles can produce a better game than a request for a sprawling world with incomplete systems. Define success and failure in visible terms. If the player loses health, explain when damage can occur and whether a short recovery period prevents instant repeated hits. Rules that are obvious to you still need to become part of the brief.

Example brief:

Collect one parcel at a time and deliver it to the station for ten points. A debris collision removes one shield and gives the ship a brief visible recovery period. The round ends after three lost shields. Restart resets the arena and score while preserving the local best score.

## Make the opening screen useful for playing

The first viewport should show the game and a clear way to begin or resume. Do not spend most of the screen on a marketing headline while placing the arena below the fold. A short instruction beside the start action is enough for a simple game. Place the score, pause, and restart controls where the player can find them without covering the active area. On a phone, reserve room for touch controls and the browser's own interface.

Choose whether the game starts automatically or waits for an explicit action, then test that behavior on a fresh page load. Sound should begin only after an appropriate user interaction and should have an obvious mute control. A long tutorial is rarely necessary for a small prototype; introducing the core action through the opening situation can teach more effectively. Keep instructions available after play starts so someone who misses the first message can recover.

## Specify controls, timing, and collision behavior

Name keyboard controls and describe touch behavior separately. A ship steered by arrow keys needs a phone equivalent that does not depend on hover. Decide whether movement is direct, accelerated, or momentum-based; these produce different games even with identical graphics. Ask for consistent behavior across display refresh rates. Movement based only on frame counts can run at different speeds on different screens, so timing should reflect elapsed time with sensible limits after a long pause.

Collision rules should match what the player sees. A large invisible hit area feels unfair, while an extremely small one can make danger meaningless. Describe the approximate shape, damage feedback, and recovery behavior. Pause when the game loses visibility if that suits the design, and avoid a huge simulation jump when returning to the tab. A restart should reset timers, enemies, temporary effects, and held-input state rather than leaving remnants of the previous round.

- Keyboard and touch can both complete the main action.
- Controls do not scroll the page during active play.
- Pause freezes the simulation and resume behaves predictably.
- Restart clears the whole round state.
- Collision feedback explains why health or score changed.

## Keep temporary game state separate from saved progress

A round contains rapidly changing state: player position, active projectiles, enemy timers, and score. Persistent progress contains slower-changing preferences or achievements, such as the best score and sound setting. Specify which data survives reload. Saving the entire simulation on every animation frame is unnecessary for a small game and can introduce stutter. A bounded save at meaningful moments is easier to reason about and easier to recover if storage is unavailable.

Browser-local progress belongs to that browser and origin. It is not an online account, a cloud save, or an anti-cheat leaderboard. Label it honestly. Validate saved data and fall back to a clean state when it is missing or malformed. A local currency or upgrade system should stay separate from real payment, Uvilno usage, and source unlocks. If you later need competitive scores across devices, plan a trusted backend and abuse controls rather than uploading unverified browser scores as if they were authoritative.

Decide where each kind of game data belongs

| Data | Typical lifetime | Honest description |
| --- | --- | --- |
| Position and active enemies | Current round | Resets on restart |
| Sound preference | Same browser | Local setting |
| Best score | Same browser | Local personal best |
| Competitive leaderboard | Trusted online service | Requires additional infrastructure and validation |

## Treat 60 fps as a measured target

Smooth play is a useful goal, but a fixed frame-rate promise is not credible across every phone, browser, battery state, and display. Ask the builder to target responsive play and then measure the result on representative devices. At a 60 Hz display, a frame has roughly 16.7 milliseconds, but not all of that time is available for your game logic. Expensive effects, excessive object creation, and large canvases can make a visually small game surprisingly costly.

Use the browser's performance tools to inspect slow moments, especially after several minutes of play. Look for an increasing number of particles, event handlers, or animation loops after restart. Prefer bounded effect counts and reuse where appropriate. The browser's requestAnimationFrame scheduling is useful for visual updates, but it is not a guarantee of a particular frame rate. Reduce decorative cost before changing the core control response; a game that feels immediate is more valuable than one with extra glow and intermittent input lag.

- [MDN: requestAnimationFrame timing](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame)

## Make the rules readable and the effects optional

Players need to distinguish the ship, hazards, pickups, and destination at a glance. Use shape, motion, and labels where appropriate instead of color alone. Keep score text readable against the actual game background. Provide visible keyboard focus on surrounding controls. For a canvas game, ordinary HTML instructions and status text can explain controls and state even when the arena itself is drawn as pixels. Do not rely on a sound cue as the only warning.

Respect reduced-motion preferences by reducing decorative shake, flashes, trails, and transitions. Reduced motion does not necessarily mean stopping the gameplay simulation; decide what is essential to the game and what is ornamental. Provide pause independently. Avoid rapid flashing and make important effects understandable without a bright burst. Touch targets need room around them, and controls should remain reachable without requiring a gesture that conflicts with the browser's navigation. These choices improve playability even for players without a stated accessibility need.

## Play through failures, restarts, and longer sessions

A game is not verified because the arena appears and the player moves. Complete the loop: collect, score, take damage, lose, restart, pause, resume, and reload. Test what happens at the edges of the arena and when two events occur almost together. Hold multiple controls, release a key outside the window, rotate a phone, and switch away from the tab. These small interruptions often reveal bugs that a short demonstration misses.

Ask another person to play without an explanation. Watch where they hesitate and whether they understand why a collision occurred. Record the exact state and action when something fails. For a performance concern, note the device, browser, approximate session length, and whether it happens after repeated restarts. Make one focused correction at a time so you can tell whether it solved the problem or changed the feel of the game in an unintended way.

Example brief:

Keep the current artwork and scoring. After pausing and switching tabs, the first resumed frame sometimes moves the ship across the arena. Fix elapsed-time handling and clear held input on blur. Preserve normal movement speed, then test pause, resume, restart, and a long inactive tab.

## Share the tested version and preserve its dependencies

Use a saved completed version for sharing. A public preview should let a visitor understand that they are playing the game, not purchasing a product or joining an imaginary multiplayer service. If a feature remains unbuilt, remove its button. A local best-score list should say local. Keep asset rights and sound licenses with the project, and avoid copying characters, music, or distinctive artwork that you do not have permission to use.

When ready to export, unlock the project through the normal source entitlement and keep the archive intact. Test the game on its final host, including relative asset paths, audio behavior, touch controls, and local storage. Moving origins means the previous local progress may not follow. Retain the working archive before making a larger revision. A small, complete game with clear controls and reliable restart behavior is a stronger release than a long feature list with unfinished menus.

## Common questions

### Can Uvilno guarantee every game runs at 60 fps?

No. Treat 60 fps as a measured target. Performance depends on the generated game, device, browser, display, and effects. Playtest and profile representative devices.

### Is a local high score an online leaderboard?

No. Browser-local progress belongs to that browser and origin. Competitive online scores need a trusted service and validation beyond storing a value in the page.
