Skip to content

packages/catalogue ​

What a creator's Claude may name when it writes a game (Technical specs §9.2): the level spec a generated level is built from, and the catalogue of everything a game document can use. Isomorphic: the platform API serves it (GET /catalogue, GET /schemas), the MCP server reads it. How a spec becomes a level and a game is in the Platform guide; the generator itself in Levels.

FileWhat
level-spec.tsLevelSpec, the zod schema of a spec, field for field what assets/blender/levels/generate.py and its grid-town template (town.py) accept: the same fields, ranges and defaults (a district's mix its theme's), unknown fields refused, a block in two districts refused. levelSpecTexts gives the districts' titles players read, for moderation. checkLevelSpec answers the spec with its defaults or its issues (paths as the generator writes them: districts[0].blocks); levelSpecJsonSchema is its JSON Schema.
sky.tsA level spec's sky, the same in every template: its climate and clock (SKY_FIELDS), and skyOfSpec, the sky a level built from a spec carries (its climate, its biome's or temperate).
city/The city template: its spec (CitySpec), its solver (buildCity: the spec resolved into the plan Blender builds, or its issues at their paths, and its map) and the thirteen styles a district is built in (styles.json, read by assets/blender/levels/city.py). See its README and The city spec.
osm/The OpenStreetMap tag snapshot (osm-tags.json, written by npm run osm:tags), the recipe of every tag (recipes.json, checked by recipes.ts: a building to generate, a hand-made archetype, a facility, an area, a district's landuse or a skip) and the buildings the generator made from them (buildings.generated.json, written by assets/blender/kits/osm.py).
buildings.tsWhat a district is built of: BUILDINGS (the hand-made archetypes and the GENERATED_BUILDINGS made from OpenStreetMap's tags), isMixKey (an archetype, a tag, or a wildcard: shop=*, family:<f>, landuse:<l>), DISTRICT_LANDUSES; BUILDING_ARCHETYPES, the 32 hand-made buildings of the downtown and civic kits with their kit, family (civic, commercial, residential, industrial, transport), footprint, height, OpenStreetMap-style tags and anchors (ANCHOR_DOCS: what each kind of anchor is), taggedArchetypes and isBuildingKey (an archetype or a tag one carries); DISTRICT_THEMES, the six satire themes of themes.json (titles, brands and nouns of their buildings' names, default mix, density, the looks they lean to, the pedestrians they suggest), which the generator reads too.
entries.tsCATALOGUE: one entry per thing a game may name, { id, kind, title, doc, example?, params? }: the grid-town template (its parameters from the schema), a district's fields, the themes, the buildings a district's mix and landmarks name, their families, tags and anchors (entries-buildings.ts), the street furniture switches, the kit pieces (kit-pieces.ts), the places a generated town names, the vehicle classes (from @foi/sim, with their seats), the common items (from @foi/sim), the mission actors (vehicles, locked or not, groups of enemies, items on the ground, containers, doors, garages, people, terminals), the phone's pieces (contacts, dialogues, apps), and the mission language's verbs, rules, events, conditions, values and actions (from @foi/missions).
kit-pieces.tsThe kit library: KIT_LIBRARY, read from kits.generated.json (written by npm run kits:export, apps/tools/src/kit-library.ts, from the shared kits' glTF binaries and sidecars; level:check fails when it drifts), every piece's kind, collider, footprint and bounds in the game's frame, triangles, tags (the sidecar's OpenStreetMap ones, else words derived from its kit, kind and id), anchors, breakable mass, what it rests on when it is not the ground (rests: a boat on the water, a cone on the road), roads and parts; kitPiece('street/bench'); pieceFacts(mesh), what the level audit knows of a piece (@foi/world's auditLevel); the kit-piece entries, one per piece with its record as piece.
catalogue.tscatalogueEntry(id), searchCatalogue(words) (ranked: the id, then the title and kind, then a kit piece's tags, then the doc; a kit piece scores half, after the building or switch a spec names) and catalogueMarkdown() (the whole catalogue for Claude, a section per kind, a kit piece a line); CATALOGUE_VERSION.

The two sides are held together by tests: level-spec.test.ts reads the Python (the buildings, their footprints, kits and heights, the default mix, the props, the fields, ranges and names) and the kits' sidecars (every building's tags, look and anchors) and runs the table of specs in src/fixtures/spec-cases.json; catalogue.test.ts checks every example against the schema it belongs to (a spec, an actor, an objective, a rule, a condition, an action) and every listed place against the places test-generated-town has; kit-pieces.test.ts checks the kit library (every piece tagged, the anchors' and parts' names resolved, the hand-made buildings' frontage holding their pieces) and its search; levels-audit.test.ts holds every bundled level to the level audit, as it is, with the kit library's facts (what a test level does on purpose named with its reason). testing.ts (@foi/catalogue/testing) draws valid specs from seeds for the generators' random gate (drawRegionSpec, drawTownSpec; apps/worker's level:fuzz). Where Blender is installed, apps/worker's integration test runs the same spec cases through generate.py's own checks and compares the answers.

A new template is a new schema joined to LevelSpec on template, its entry in entries.ts and its places; a new mission verb, event or action in @foi/missions fails catalogue.test.ts until it has its entry.