describe a game.
play it.

blitOS turns one sentence into a playable game at a live url, with the full source. every character, world and effect on this page is drawn from code at runtime. there is not a single image file here.

>
the game is playing itself. click or tap to take over. wasd to move, or drag.
specgame.spec.json5 entities 6 systemsskeletonloop 60hz fixed, seed 20260907okwriteentities.jsokwritesystems.jsokwritetuning.jsonokchecktypecheckokharness600 frames, inputs pressedwave 3 hp 72deployplay.blitos.xyz/knightfalllive

what comes out

one prompt, three things you keep.

a live url

the game is already running when the link opens. share it, embed it, play it on any screen.

the full source

one zip. plain html5 and canvas. open it in any editor, host it on anything, change whatever you want.

every pixel from code

sprites, levels, particles and ui are rendered by the game itself at runtime. one file, instant load, and it looks the same everywhere.

the spec goes first

a game is too big to write in one breath. so blitOS writes a small contract before any code, and every pass reads that contract instead of the previous pass.

  • spec file first. entities, systems, events and every tunable number, written before line one and carried into every generation pass.
  • fixed skeleton. a 60hz loop with a fixed timestep and a seeded rng. the same seed replays the same run, frame for frame.
  • one file per pass. nothing is ever cut mid-function. a failure is one file, retried alone.
  • typecheck and play after each file. a harness presses the inputs, runs the frames and reads the score before the next file is written.
  • tuning in one place. speeds, damage, spawn rates and drop tables live in a single data file the game reads at boot.
// game.spec.json
{
  "genre": "arcade-rpg",
  "loop": { "hz": 60, "seed": 20260907 },
  "entities": ["knight", "slime", "goblin", "brute", "orb"],
  "systems": ["input", "movement", "combat",
              "loot", "waves", "levelup"],
  "input": { "keyboard": true, "pointer": "drag" },
  "tuning": "tuning.json",
  "deliver": ["url", "zip"]
}

change it in plain words

because every number lives in one file, most changes are one field. the game redeploys to the same url with the same seed.

> make the slimes slower and give the sword more reach

// tuning.json
- "slime.speed": 44,
+ "slime.speed": 32,
- "knight.reach": 62,
+ "knight.reach": 78,

// harness  600 frames  seed 20260907
wave 4 reached at frame 2210  was 2640
hp at end 81                   was 52

three prompts

different genres, same pipeline. each of these is running right now, drawn by its own code.

> a side-scrolling runner. a girl with a ponytail, mountains at dusk, coins and spikes
> a road-crossing game with a chunky chicken, traffic lanes and a river with logs
> a neon twin-stick shooter. a ship, drifting rocks, everything made of lines