What it does
You build a Land from a short definition: how many tiles a side, how big a tile is, how high the land rises, the
share of the world that stands above the sea, a landform and a seed. The pack generates a landscape that tiles the
torus exactly, then lifts it so the fraction of land you asked for is dry. The heights are a terrain-3d heightfield
with wrap turned on, and the renderer is handed that same field, so what the player sees and what the rules test are
always one thing.
The rules ask the land what they need to know: the land height at a point, the ground or the sea's surface over water, whether a point is water, the surface normal, and how uneven a footprint is, which tells you whether there is room to build there. Because the world wraps, it also folds coordinates back onto the torus and gives the shortest offset and distance between two points, so a chasing enemy takes the short way round rather than crossing the whole map.
The land changes in play. Brush edits raise, flatten or stamp landforms, and a displacement field can be added over a disc. Earthquakes, volcanoes, craters and raised or lowered ground are shapings: plain data describing a field over time. Each step applies only the change since the last step and returns the shapings still running, so a snapshot can save one mid-heave and the land always ends exactly where the field ends, however the frames fall. Every changed region is recorded, and you hand those regions to the renderer to redraw only what moved.
Features
- A world that wraps — the land tiles at every edge, with
wrap,deltaanddistancefor coordinates, offsets and shortest distances on the torus. - Built-in landforms —
archipelago(many islands),continent(one broad mass cut by inlets),highlands(ridges, valleys and lochs),lagoon(rings of islands round shallow water) andflat, listed inLAND_SHAPES. - Your own landform — pass any function of
xandzthat repeats every world width, and it is lifted to the same share of land. - Land and sea on demand —
landFractionsets the share above the sea, with the sea's level and depth as options. - Ground queries —
heightAt,groundAt,isWater,normalAtandrelieffor footprints, which reads infinitely uneven over water. - Brush edits —
terrain-3d's raise, flatten and landform brushes at world points, plus displacement fields over a disc. - Shapings over time —
quake,volcano,raise(or a hollow, with a negative amount) andcrater, each with a centre, radius, duration, peak amount, noise seed and owner. - Redraw only what changed —
takeDirtyreturns every region changed since the last call, ready for the renderer to refresh. - Snapshots —
heightsandsetHeightssave and restore the landscape, and running shapings are plain data that save with it.
Good for
- Flying conquest games over islands that spells raise and split, in the style of Magic Carpet.
- God games where the player reshapes the land and the sea decides where walkers can go.
- Flight sandboxes that should feel open, with no edge to fly into.
- Terraforming toys, where earthquakes, volcanoes and craters are the play.
- Small wrapping planets for a racer or an explorer that should come back round to where it started.
Make it yours
A LandDef sets the world. cells (16 to 1024 tiles a side) and cell (world units a tile) give its size, height
the tallest land, seaDepth and sea the water, shape the landform, featureSize how large the big landforms are
(rounded so a whole number of them tile the world) and landFraction the share of dry land. A custom shape function
replaces the built-in landforms entirely.
Two very different worlds: a wide archipelago of 256 tiles a side, where earthquakes crack belts across the islands and volcanoes grow cones with craters; and a small lagoon of 128 tiles, rings of islands round shallow water, where spells raise and lower the land. A flat world is a third, a blank canvas for a terraforming game that brushes every hill in by hand.
A quick look
A lagoon world drawn by the terrain renderer, with a volcano growing on it:
const { Land, advanceShaping } = game.torusLand;
const land = new Land({ cells: 128, cell: 4, height: 60, landFraction: 0.4, shape: 'lagoon', seed: 7 });
game.terrain.build({ field: land.field, paint });
let shapings = [{ kind: 'volcano', x, z, radius: 24, dirX: 0, dirZ: 0, length: 0, t: 0, duration: 1.2,
amount: 20, seed: 0, owner: -1 }];
shapings = advanceShaping(shapings, land, dt);
for (const r of land.takeDirty()) game.terrain.refresh(r);
Works with
terrain-3d— the heightfield, the brush edits and the renderer that draws the land.procgen— the periodic noise behind the built-in landforms.mana-conquest— the flying conquest rules that play on this land.deform-terrain-3d— for a surface that keeps the marks something carves in it.road-data— for road and racing games rather than open land.
Good to know
- It is a heightfield: there are no caves, overhangs or tunnels.
- The world is square, at most 1024 tiles a side, which is a million heights to snapshot.
- Heights stay between a floor and a ceiling (1.5 sea depths down and 1.6 heights up), so reshaping cannot run away.
reliefsamples at tile spacing, so a footprint smaller than a tile reads only its corners.- For land that does not wrap or never changes,
terrain-3dalone is enough.






