The region template
A region is land on a grid of 64 m tiles, built from a spec without Blender. The tiles, the shapes and the spec are documented in Tiles; this is how the code does it.
| File | What it does |
|---|---|
spec.ts | The spec's schema (RegionSpec): the size, the base level, the biome, the features (a volcano's flow), the roads, the towns (their dressing), the town the players start in, the props. The grid's numbers (TILE) come from ../tiles.json. |
heights.ts | solveHeights: the corners' levels. Each feature raises or lowers the corners it covers. The raise spreads outward a level per tile (two round a mountain). The rim and the spawn apron are pinned at 0 and a valley at its floor; lowering from them spreads the same way. What comes out never has two neighbouring corners further apart than their step. A volcano's crater is two levels under its rim, the rim a level lower where its flow breaches it. A feature cut short is an issue with its path. |
roads.ts | routeRoads: each road of the spec routed over the tiles (A* over a tile and the way it was entered), through the sockets: straight across a tile or round a quarter bend. Crossings only at right angles; joins on a road's centre line. Its heights: the land's, closed over dips for a highway or an avenue, levelled to the class's grade, its ends on the land and level with the roads it meets. A bridge wherever it runs more than 4 m over the land. |
bridges.ts | bridgeMesh: a bridge's deck under a road's run of bridge points, its railings and its piers. |
tunnels.ts | tunnelMeshes: a tunnel's roof (the hill's surface rebuilt over the road's cutting, in the biome's colours), its stone portals with their lamps and its lights inside, for a road with tunnels: "auto" held under a hill (roads.ts marks where, terrain.ts cuts the ground). |
terrain.ts | terrainSurface: the ground as one mesh, a vertex every 4 m. Each vertex is the tile's corners blended, plus a seeded bump that is nothing on the tile's edges, so a seam depends on its two corners alone. Each triangle is coloured by the biome, or painted: a ski run's snow, a volcano's rock, its flow of lava between banks of ash, a lake's beach of sand. The roads are graded in: a flat bed, then an embankment or a cutting back to the land (none under a bridge). heightAt reads the mesh's own triangles. |
ground.ts | What colour the ground is where nothing else decides it: the rich ground's tones by seeded value noise (valueNoise, richTone), a landuse area's pattern (landuseTone: fields, rows, patches, paths, plots, on the 4 m grid), a pond's bowl (dentAt). |
plots.ts | What a rich region's tiles hold: the composers (planPlots from the corners alone, so ponds are dug before the ground; dressPlot), each piece with a trim rank, the points of interest (POINTS_OF_INTEREST) spread out. |
landuse.ts | dressLanduse: the pieces of a landuse area of each kind and its place. |
water.ts | regionWater: the sheets of water and lava a region's lakes and volcanoes make, and the tiles they wet (no road, no tree there). |
dressing.ts | dressFeatures: what a region's lakes and volcanoes have about them, wherever no road runs, on a random stream of its own: a lake's beach (umbrellas, loungers, a lifeguard's tower), its jetty out from its southern waterline with two rowboats and a swan pedalo, reeds along its northern waterline; a volcano's basalt boulders, four fumaroles round its crater's lip, a lookout on its southern rim and a seismograph's hut on its flank; their places <lake>_dock, <lake>_beach, <volcano>_lookout. beaches: the sand painted along a lake's southern shore. |
towns.ts | The towns' footprints (townFootprints), what they must keep clear of (footprintIssues), the edges inside them that climb a level a tile at most (gentleTiles), the corners their terraced districts level (terraceCorners), and the sockets a road of the region ends at (townSockets). |
build.ts | buildRegion: the spec parsed, the landuse areas checked, a rich region's plots planned (its ponds dug), the heights solved and the ground meshed. Then the trees and rocks (none on the apron; in groves of the biome's flora when rich), the landuse areas' and plots' pieces (none on a road, a point of interest whole or not at all, every place on a clear spot), the ponds' water, the lakes' and volcanoes' dressing, the spawns on the apron (region-level.ts swaps them for the four the town generator lays when start names a town), the places and the map in text (regionMap). |
Deterministic: every random choice is createPrng(seed). The same spec gives the same region, mesh and props alike.
The assembler that writes a region out as a level's own kit is @foi/tools' region-level.ts (npm run level:region); a region's towns are built there by the town generator (Blender: assets/blender/levels/generate.py --relief, relief.py) on the land build.ts hands it (each town's grid-town spec, its corner levels and the seam of the region's ground round it, the roads that end at it) and merged in. Its glTF writer is gltf-write.ts. The tests: region.test.ts here, apps/tools/src/region-level.test.ts, packages/sim/src/terrain-tiles.test.ts, and test-tiles-terrain's contract in packages/world/src/levels.test.ts.