From one sentence
This went in. This came out.
>/lattice a game where you place stalls and open gates to pull the crowd to your bakery before the market closes
Grok's agent, in an empty directory, with the packages from npm and no access to this repository. Nobody here designed it, named a file or fixed a bug — the source is unedited, and these are not gallery exhibits: nothing in them was held to a line rule and nothing was tidied.
Two more, the same way
>/lattice a game where you hang chimes along a mountain path and tune each one, so the wind plays them in order as walkers pass
Chime Path
Claude · 1,341 lines over 6 modulesfive HUD nodes ship under the contrast floor, and the agent that drove a browser still missed them
>/lattice a game where you plant an orchard and each evening choose to harvest or let it grow, and it keeps growing while the tab is closed
Evenfall Orchard
Codex · 73 lines in one moduleone phase of its day is 84% one near-black color, which its author never saw
All three, their transcripts, what was verified by hand and the defects left in:
from-one-sentence/. The
9 packages they installed are the ones on npm, at the version their lockfiles pin.
The gallery
Eighteen worlds, running right now.
Under each one is the sentence it would be asked for. Above it is that world, live in your
browser — a directory under examples/, under 200 lines of logic, seeded from its own URL.
You have asked your browser for reduced motion, so nothing on this page starts by itself. Every tile below is built and painted once, and stays on that frame until you press Run.
CLOSED-FORM CROWDS
a busy piazza with hundreds of people crossing it, all walking somewhere
Crowd
0 bytes of state per walkerDAY CYCLE
a small island where I can watch a whole day go by in a minute
Island
a 90-second dayLIVE TERRAIN
a valley where I can push the ground up with my cursor and everything on it resettles
Clay
2,200 props over a live height fieldDEPTH SORTINGBuilt by Codex
a harbor at dusk with tall masts and cranes, and a long jetty out over the water
Harbor
197 objects, one depth orderFLOW FIELDBuilt by Codex
a crowded hall where I can close a gate and watch everyone find another way round
Wayfinding
640 walkers, one rebuildPLACEMENTBuilt by Codex
a yard where I drop a workshop down and it tells me when it will not fit
Builder
1,444 yard tiles, 66 obstaclesLIGHT POOLS
a cave lit only by scattered lanterns, with the pools of light overlapping
Caverns
704 light poolsNO GROUNDBuilt by Codex
stations turning in space with stars behind them and no ground anywhere
Orbit
214 sorted objects, no groundSEEDED REPLAYBuilt by Claude
a marsh I can record, wind back, and prove came out the same
Replay
1,081 ticks re-run in 1.5 msELEVATION PICKING
stepped terraces on a hillside where I can click on any level and hit the one I meant
Terraces
the naive pick misses by 1,400 px at the ridgeSYNTHESIS, DRAWNBuilt by Grok
a hall of pipes I can play, where I can see the sound being made
Instrument
60 recipes, 0 bytes of audioENDLESS WORLD
a world I can keep panning across forever that never loads anything
Endless
256 chunks resident, a flat 128 KiBEROSION
a desert canyon cut by a river, with a slider that rewinds a million years
Canyon
one erosion step, 112x112 grid, 0.30 msIDLE ECONOMYBuilt by Grok
a little brick works that keeps earning while I am away
Idle
28,285 s credited in one stepDERIVED SOLIDS
a city block at night from above, with traffic in the streets and lit windows
City block
36 buildings, 120 carsSAVE MIGRATIONBuilt by Claude
an old save file opened by five newer versions of the same game
Migration
750 saves on the ladderSYNTHESIZED SOUND
a puzzle in a ruin where every gate hums a chord and I answer it by ear
Resonance
6 ms attack on a struck stringSAVE AND LOAD
a small village game where I walk around, talk to people, take things and save
Errand
a ~60-byte save envelopeThe fan-out
Eight exhibits, three vendors, one written spec.
Eight of the worlds above were built by agents from three different companies, each given one row of the gallery brief, the standard it is held to, and the tools — and none of them allowed to read another exhibit's source, because an agent that can copy its neighbour tests the neighbour rather than the writing. Seven of the eight passed every row of the looking harness unaided.
- CodexHarborWayfindingBuilderOrbit
- ClaudeReplayMigration
- GrokInstrumentIdle
The exception was Replay, on legibility: a bare · separator is its own text
node, and one narrow glyph in a five-pixel box reports a luminance range of 0.003 at a contrast of 7.2. It was
not hard to read. It was too small to measure.
Each of the eight changed on the way in and its
README says how. What all eight of them found missing in the brief is
collected in what
eight strangers found in this document.
Why
Why the agent gets it right.
Ask a general coding agent for a game and it invents a sprite sheet, an asset path and a physics constant, and hands you something that compiles and is broken. None of those three exists here.
- No asset files, so no asset paths. A solid is one color with its faces derived; a sound is synthesized from a declaration. Nothing to draw, nothing to load, nothing to license — and nothing to name wrongly. A recolor is a runtime value.
- Deterministic by rule, not by discipline.
Math.random(),Date.now()andperformance.now()are lint errors inside a package. Same seed, same world, on every machine — so a bug is reproducible from a link, and a fix can be shown to have worked. - Nothing owns your
main. No engine, no editor, no loader, no scene format and no build step past a bundler. There is no framework shape to get wrong because there is no framework.
The traps, written down
An agent can read a .d.ts. What it cannot read is the set of failures that are individually
surprising and jointly the difference between a working game and a plausible-looking broken one. Three of them,
and the rest at /llms.txt:
- An animated color is an allocator. a color that moves continuously misses the ramp cache every frame and takes every other caller’s entry down with it. Snap it to eight levels; keep position and timing continuous.
- Tile lookup floors, never rounds. and once ground has elevation the projection stops being invertible, so a tap has to be resolved against the terrain. The naive version misses by 1,400 px at the top of a hill.
readonlyis not a barrier. TypeScript ignores propertyreadonlywhen checking assignability, so a frozen vector flows into a parameter that writes to it. The failure is aTypeErroron the one frame that path runs.
The whole kit, without the prose
| at | what it holds |
|---|---|
/llms.txt | the kit as plain text: the rules, all nine packages with entry points and invariants, every exhibit with its source path, the traps, and a program that compiles. |
/api.json | the same as JSON, plus every measured figure with the command behind it, the cross-package contracts, and what is and is not stable. |
/kit.json | the repository's own .lattice/kit.json, verbatim — the file the build fails over if a package exports a symbol it does not list. |
Those three are live right now, and an agent pointed at them needs nothing else from this page. The plugin above is what saves you from having to point it.
The nine underneath
core depends on nothing and every other package depends only on the ones below it. All nine are
83.02 kB gzipped and a game imports four or five.
| package | layer | what it is for | gzip |
|---|---|---|---|
@latticekit/core | 0 | Deterministic primitives. Seeded randomness, noise, math, easing, typed events, pools, formatting. | 7.40 kB |
@latticekit/audio | 1 | Sound without assets: WebAudio synthesis from declarative sound definitions, with voice limiting, buses and a music sequencer. | 7.76 kB |
@latticekit/iso | 1 | Isometric space: the projection, the camera, depth sorting, tile maps, footprints, hit-testing, and grid pathfinding. | 11.47 kB |
@latticekit/loop | 1 | Time. A wall-clock game loop with fixed-step simulation and interpolated rendering, plus scheduling, tweens and frame statistics. | 6.57 kB |
@latticekit/persist | 1 | Saves that survive: versioned state, an explicit migration chain, pluggable storage, debounced writes and integrity checks. | 5.79 kB |
@latticekit/sim | 1 | Idle-economy mathematics in closed form: cost curves, the flow integrator, offline accrual, and capacity gating. | 7.58 kB |
@latticekit/draw | 2 | The rendering layer: a Surface interface with a Canvas2D backend, color derivation, and the isometric solid kit that makes procedural art read as designed. | 12.33 kB |
@latticekit/input | 2 | Normalized input: pointer, touch and keyboard into one per-tick sample stream, plus gestures, an action map, a camera controller, and the recorded log a replay is driven from. | 15.39 kB |
@latticekit/ui | 3 | DOM overlay primitives — a declarative element builder, panels, toasts, number rolls, and thumbnails rendered from the draw kit. Deliberately not a framework. | 8.72 kB |
What
One command, 12 skills, 9 libraries under them.
The libraries are the tech. The product is the plugin: the part that knows which of them to reach for, in what order, and what not to do.
| what you get | what it does |
|---|---|
/lattice | the parent skill, and the whole entry point. Everything after it is the game — no flags, no subcommands, no questions with a right answer it could have worked out. It picks the shape, scaffolds, installs, wires, gets to a running screen, then opens it in a browser and looks at it. |
| eleven specialists | starting art world economy input sound saving hud determinism performance traps — organized by what somebody is trying to do, never by package. Nobody sits down to use @latticekit/iso; they sit down to put a building where someone tapped. |
| 9 libraries | core audio iso loop persist sim draw input ui — 83.02 kB gzipped for all of them, no dependencies, and a game imports four or five. They are what the skills drive. |
Written down in docs/SKILLS.md, which also holds the bar this is held to and the one test that decides whether it shipped: somebody who has never seen this repository installs the plugin, types one sentence about a game, touches nothing else, and ends up looking at that game in a browser. Three of those runs are at the top of this page. What is untested is a stranger doing it, on a machine that is not ours.
Getting started
Getting started.
A whole Lattice program in 10 lines, and the world it draws, running out of that same file.
import { createCamera } from '@latticekit/iso';
import { BASE_SLOTS, beginFrame, createCanvas2dSurface, createPalette, endFrame, isoBox } from '@latticekit/draw';
import { browserFrames, createLoop } from '@latticekit/loop';
const surface = createCanvas2dSurface(document.body.appendChild(document.createElement('canvas')));
const camera = createCamera(innerWidth, innerHeight, { zoom: 0.62 }), palette = createPalette(BASE_SLOTS);
createLoop({ clock: { now: () => performance.now() }, frames: browserFrames(), render: (_alpha, t) => {
const pen = beginFrame({ surface, camera, palette, t, clear: 'sky' }); // erase, then paint the sky
// Back to front is just the loop order in a 2:1 projection, so this city needs no depth sort.
for (let gy = -7; gy < 7; gy++) for (let gx = -7; gx < 7; gx++) isoBox(pen, gx, gy, 1, 1, { color: 'metal', h: 2 + 5 * Math.sin(t + (gx + gy) * 0.4) ** 2 });
endFrame(pen);
} }).start();
10 code lines by
the gallery's own line rule, typechecked against the built packages before
this page is generated. It is a real file:
site/example/hello.ts, and
this is it running on a page of its own. Everything past this — terrain, a depth
sort, pathfinding, sound, saves — is what the skills know and you do not have to.