Every game on this site is HTML, CSS and JavaScript. No framework, no game engine, no plugin, no download. Five browser APIs do all of the work, and understanding what each one contributes explains why these games start in a fraction of a second.

1. Canvas: the drawing surface

The <canvas> element gives a script a bitmap and a set of 2D drawing operations. Everything you see in a game here — characters, hazards, backgrounds, particles, HUD text drawn in-world — is drawn into that bitmap, sixty times a second.

The canvas has two sizes that must be managed separately: its CSS size, which determines how large it appears, and its buffer size, which determines how many pixels it contains. The buffer is set to the CSS size multiplied by the device pixel ratio, capped at 2 — rendering at 3× on a modern phone costs nine times the fill for an imperceptible gain on a moving image.

Games then work in a fixed logical coordinate space. This site fixes the logical height at 600 units and derives the width from the real aspect ratio, so a 16:10 screen gives a 960 × 600 world and a 3:4 phone gives 450 × 600. Gameplay tuning transfers across every device.

2. requestAnimationFrame: the loop

requestAnimationFrame schedules a callback before the next repaint. It is the correct way to drive a game loop for three reasons: it matches the display refresh rate, it does not fire faster than the screen can show, and it stops entirely when the tab is hidden.

That third property matters for battery. A game using a timer-based loop keeps running in a background tab; one using requestAnimationFrame does not.

Delta time

Each frame computes the elapsed time since the previous one and multiplies all movement by it. That makes the game frame-rate independent — a character moving at 300 units per second covers the same ground at 30 fps and 144 fps.

One detail matters enormously: delta must be clamped. A 400-millisecond frame, from a garbage collection pause or a thermal throttle, would advance the simulation by 400 milliseconds in one step and can teleport a character through a wall. This site clamps to 50 milliseconds.

3. Web Audio: synthesised sound

Every sound on this site is generated at run time. An oscillator, a gain node shaped into an envelope, and a connection to the output is enough for the entire arcade vocabulary: a collect chirp whose pitch rises with your combo, a combo step-up chime, an impact, a game-over descent.

That means no audio files are downloaded, nothing is sampled from anywhere, and the whole sound design is original by construction.

Browsers require a user gesture before audio can play, so the context is created and resumed on the first tap or key press inside a game. That is also why there is never any autoplay.

4. Pointer Events: unified input

The Pointer Events API unifies mouse, touch and stylus into one event model. One code path instead of three, and it removes an entire class of bugs where a game works with a mouse and subtly fails with a finger.

Four details make it work properly: touch-action: none on the play area so drags are not interpreted as scrolling, setPointerCapture so a drag leaving the canvas keeps delivering events, handling pointercancel as well as pointerup so a system interruption does not leave a button stuck down, and suppressing the context menu so a long press does not open one over the game.

5. LocalStorage: records

Scores, favourites, play history and preferences are kept in LocalStorage — browser storage scoped to the site's origin that is never attached to network requests.

Every access is wrapped in a try/catch, including the initial availability probe, because in some browsers with site data disabled, merely reading window.localStorage throws. A game that reads it unguarded during initialisation fails to start at all.

When storage is unavailable the games degrade to in-memory operation: everything plays perfectly and nothing is remembered. That is the correct failure mode.

What is deliberately not used

  • No game engine. A framework would add hundreds of kilobytes to deliver features these games do not need.
  • No image files. All artwork is drawn from canvas primitives and standard system emoji.
  • No audio files. Everything is synthesised.
  • No WebGL. The 2D context is more than sufficient for this style and works on more devices.
  • No build step in the output. The published site is plain files a browser can read directly.

The cumulative result is that the entire arcade — thirty games, the engine, all the styles — downloads in well under a megabyte, and an individual game is playable almost immediately after the page loads.

The Page Visibility API

A sixth API worth mentioning. visibilitychange fires when the tab is hidden or shown, and every game here listens for it: hiding the tab pauses the run and suspends the audio context.

That is both a battery consideration and a fairness one. A player who switches tabs mid-run should not return to a game over.

Try it yourself: Food Catcher

Catch falling food in a wide basket, dodge anything burnt and chase the doubled 'wanted' item.

Play Food Catcher

Key takeaways

  • Canvas provides the drawing surface; set the buffer to CSS size × device pixel ratio, capped at 2.
  • Work in a fixed logical coordinate space so tuning transfers across devices and orientations.
  • requestAnimationFrame matches the refresh rate and stops in background tabs; always clamp delta time.
  • Web Audio synthesises every sound at run time, so no audio files are needed and nothing is sampled.
  • Pointer Events unify mouse, touch and stylus into one path — with touch-action, pointer capture and cancel handling.
  • Wrap every LocalStorage access including the probe, and degrade to in-memory rather than failing.
  • The whole arcade downloads in under a megabyte because there are no engines, images or audio files.

References

  1. MDN Web Docs — Canvas API — developer.mozilla.org
  2. MDN Web Docs — Window.requestAnimationFrame() — developer.mozilla.org
  3. MDN Web Docs — Page Visibility API — developer.mozilla.org

Frequently Asked Questions

What technology are browser food games built with?

HTML5 canvas for rendering, requestAnimationFrame for the loop, Web Audio for synthesised sound, Pointer Events for unified input and LocalStorage for records. No framework, plugin or download.

Why cap the device pixel ratio at 2?

Because rendering at 3× costs nine times the fill rate of 1× for a gain almost nobody can perceive on a moving image. Capping typically halves the cost with no visible difference.

What happens if a frame takes too long?

It must be clamped. An unclamped 400-millisecond frame advances the simulation in one step and can teleport a character through a wall. This site clamps delta time to 50 milliseconds.

Why does sound only start after I tap?

Browsers require a user gesture before audio can play, which is why the audio context is created and resumed on your first tap or key press. It also means there is never any autoplay.

Do these games work offline?

Once the page has loaded, yes — everything runs locally with no network requests during play. A fresh visit still needs the initial page load.