DEV Community

Ant Games
Ant Games

Posted on Edited on

One HTML page, no network requests: how our browser games ship

We build a free browser-game site, Ant Games (disclosure: this is our own project). Every game on it follows a short contract that sounds restrictive and turned out to be a useful design constraint: one HTML page, no network requests, no asset files, and everything the player sees or hears is generated by code. This post describes what that means in practice, using facts from our own repository.

The contract

From the production guide every game on the site is built to:

  • One self-contained page. dist/index.html holds everything. It makes no network request of any kind: no CDN, no web font, no analytics, no fetch. It runs from a double-click (file://).
  • No asset files beside the page. Models, textures, sprites, icons, sound effects and music are generated by code. Fonts are system font stacks.
  • TypeScript, strict. Sources are bundled with esbuild into the single page. The only runtime dependency allowed is three, and only for a 3D game.
  • A deterministic, headless simulation. Game logic lives apart from rendering: fixed timestep, all randomness from a seeded generator, no DOM, no clock, no Math.random(). The same seed and inputs give the same game in the browser and in Node.
  • No alert, confirm or prompt, and saves are versioned JSON under a per-game localStorage prefix; a save that does not parse is replaced, never trusted.
  • Languages: The site and every game page are in English and Chinese; Equal Heroes Arena is fully in Chinese, and the others are in English for now.

And on the business side: no ads, no purchases, no sign-up, nothing imitating selling.

Why a single file

A page with no outside requests can't break because a CDN moved, can't leak the player's visit to a third party, and can be archived, emailed or opened offline. It also forces honesty about size: our built SALLY PORT page is 822,010 bytes and HAIRS BREADTH's is 734,817 bytes, with all code, graphics and audio inside.

Graphics: WebGL2

JETSUN, a side-scrolling shoot-'em-up in full 3D, uses three.js on WebGL2 with an HDR render target, MSAA, bloom, a custom post pass and ACES tone mapping, with procedural lofted models and detail maps. Its game.json says it plainly: "Every model, texture, effect, sound and note of music is generated in code." Other games bring their own renderer rather than a library; the guide's rule is to borrow machinery (WebGL helpers, batching, bloom chain, input, save plumbing) but never a game's identity.

Where code is bad at something, such as rigs and baked light, the project allows Blender as an offline tool. Its output is baked into the page as data, so the single-file, no-requests rule still holds.

Audio: synthesised, not sampled

Every effect is synthesised, and music comes from a step sequencer rather than audio files. SALLY PORT, a gate-defence game with 50 levels and 50 bosses, lists "62 sound effects and no asset files" and a distinct music track for each of its five places. Each game has separate volumes and mute.

A deterministic simulation pays for itself

Because the simulation is seeded and headless, the same code runs in Node for tests and bot balance runs, and a seeded daily run comes almost for free: HAIRS BREADTH, a three-lane runner through a jungle temple, ships The Escape (five zones, with an ending), Endless and a seeded Daily Run.

What we would tell you

Constraints that look like limits (no network, no files, no clock) mostly turned into free testability and portability. The cost is real: everything, from sound to models, becomes code you maintain.

You can try the result at antgames.ai, where games are free, without ads or purchases.

Top comments (0)