A deterministic planet generator that runs entirely on the sphere: plate tectonics with real Euler-pole motion, hydraulic erosion, a water-volume ocean, latitude-and-altitude climate, Whittaker biomes, and a political atlas — all from a single seed and a handful of genes. Open, dependency-free, and pullable as an API.
Every world is generated from an integer seed plus an optional genome — about six global scalars and a set of tectonic plates. The plates are the spine: ~90% of a world's identity lives in their positions and motions; the rest is a few knobs. The same seed and genome always produce the same planet, on any machine.
Nothing is hand-painted. The terrain, coastlines, mountain belts, rivers, climate zones, and biomes are all emergent from a physical-ish simulation. The mino.mobi “atlas” (civilizations, countries, cities, roads) is a separate projection laid on top of whatever world the engine produced.
Each gene can be left to derive from the seed or pinned to a value (in the ⚙ genome panel, or via the API). Genes are orthogonal: the RNG stream always draws the seed-derived value first, so changing one gene leaves the others — and the seed's character — intact.
| Gene | Range | What it does |
|---|---|---|
planetRadius | 0.3 – 3.0 R⊕ | Two coupled effects: plate count ∝ area (r1.3) and relief ∝ 1/gravity (r−0.55). A small world has few plates but dramatic, tall terrain (Olympus Mons); a big world has many plates but flat terrain (gravity caps mountains). |
age | 1 – 20 epochs | Geological time. Plates drift about their Euler poles by speed × age; a multi-epoch pass keeps the strongest convergence each cell ever saw, so orogenic belts widen and develop with age. Older worlds have continents far from their origin. |
plateCount | 3 – 60 | Number of tectonic plates. More plates → more boundaries → more fragmented, complex coastlines. |
oceanFraction | 0.20 – 0.90 | Fraction of plates that are oceanic crust (deep basins) vs continental. Shapes where the deep ocean basins are. |
waterFrac | 0.02 – 0.40 | The volume of water poured over the topography. Sea level is solved so the water settles into the basins — coverage is emergent, not imposed. |
axialTilt | 0° – 45° | Obliquity → seasonality. Drives the depth of winter by latitude and continentality, which feeds the biome classifier (more tilt → bigger ice/taiga belts). |
rotationRate | −2.5 – 2.5 ×Ω⊕ | Planetary spin, signed. |Ω| sets how many atmospheric circulation cells fit per hemisphere (slow → 1–2 giant cells, Earth → 3, fast → up to 6 narrow jets) and how zonal the winds are; it also sets day length (1/|Ω|). The sign is the spin direction — negative is retrograde, which flips the Coriolis deflection and reverses every prevailing wind. |
solar | 0.5 – 1.8 × | Stellar luminosity. Shifts the whole temperature field → an ice world (dim) ↔ a desert world (bright). |
Everything happens on the unit sphere — no map projection during generation, so there's no distortion or seam in the physics.
v = ω × p. Boundaries are domain-warped by 3-D noise so they're fractal and jagged, not smooth Voronoi arcs.age epochs the plates drift; convergence at the moving boundaries accumulates as orogeny — continent–continent collisions raise ranges, continent–ocean subduction raises coastal arcs + offshore trenches, ocean–ocean divergence makes mid-ocean ridges, and rifts pull apart. Belts widen as boundaries sweep.planetRadius) and compressed through an Earth-like hypsometry so most land is lowland and mountains are the exception.Σ areaᵢ · max(0, h − elevᵢ) = V for the level h, weighted by true spherical cell area. Deep basins hold water at depth, so continents stay dry instead of flooding to a quota.rotationRate and the deflection sign by its sign (retrograde reverses them). Temperature comes from latitude + altitude lapse + solar. Moisture is then advected: ocean humidity is carried downwind and rains out, so windward coasts are wet and lee sides / deep interiors fall into rain shadow; this is layered over the circulation's wet (rising) and dry (sinking, subtropical) bands. Seasonality from axial tilt × latitude × continentality.The mode bar separates projection (Orb / Mercator) from the content layer, so the layers below ride on either the globe or the map:
Civ and Tectonic are map-designed, so selecting them snaps to Mercator. Fossils and Paleo ride on either the globe or the map.
The mino.mobi sites are not part of the engine — they are projected onto whatever world was generated. Land is scored for habitability (biome + elevation); spherical k-means partitions the habitable land into nine civilizations (the theme-wings), each matched to a region; every civilization is then subdivided into sovereign countries by clustering its cities (most hold one city, the largest two or three); cities place by habitability + spacing + founding age; and a road network is the least-cost path from each country's capital over land.
The map carries two kinds of name. City names come from the atlas — they are the real mino.mobi sites, projected on. Every geological feature (the highest peak, the deepest trough, the volcanoes, the ore deposits, the dig sites) is named by the engine, deterministically from the world seed — same world, same names, for ever.
A feature name is a specific root + a generic term that fits the feature — Mount Kruth, Thauld Deep, Dambra Caldera, Naish Lode, Vaelele Bonebeds. The root is built from syllables — an onset, a nucleus (vowel), and an optional coda — and the generic is drawn from a per-kind set:
| Feature | Generic terms |
|---|---|
| Peak | Mount · Pike of · Cairn · … Tor / Horn / Fell / Crag / Scaur / Spire |
| Trough | … Deep / Trench / Abyss / Trough / Fault / Sink / Gulf |
| Volcano | Mount … · … Fell / Caldera / Pyre / Forge / Smokes / Ashmount |
| Ore deposit | … Lode / Field / Diggings / Reach / Vein / Workings / Mine / Strike |
| Dig site | … Beds / Quarry / Pits / Bonebeds / Marl / Hollow / Cutting |
The point of the system is linguistic coherence: the syllable palette is one of several language families (Varn — harsh, northern; Lyr — liquid, upland; Mor — round, lowland; Kael — bright, southern; Esh — sibilant, coastal), and the family is chosen per tectonic plate. So every feature on one landmass shares a tongue — a mountain and a mine on the same continent rhyme — and the language borders fall along the plate sutures, exactly where Earth's real linguistic divides tend to sit (the Caucasus, the Himalaya, the Alps). Names aren't decoration here; they're another reading of the tectonics.
Pull a complete, deterministic world as JSON. CORS-open, edge-cached, no key. The same (seed + parameters + n) always returns the same world.
GET https://mino.mobi/api/world?seed=7&n=1800&radius=0.7&age=8&solar=1.1
| Param | Default | Meaning |
|---|---|---|
seed | 1 | Integer world seed. |
n | 1500 | Target cell count (500–2200). The browser engine runs far higher; the API is capped by server CPU. |
radius | — | Planet radius in R⊕ (0.3–3.0). Omit to derive. |
age | — | Geological epochs (1–20). |
plates | — | Plate count (3–60). |
ocean | — | Oceanic-crust % (20–90). |
water | — | Water-volume % (2–40). |
tilt | — | Axial tilt in degrees (0–45). |
rotation | — | Planetary spin, signed (−2.5–2.5 ×Ω⊕; negative = retrograde). |
solar | — | Stellar luminosity (0.5–1.8). |
{
"api": "mappa.world/v1",
"meta": { "seed": 7, "n": 1468, "plateCount": 20, "oceanFraction": 0.58,
"waterFrac": 0.24, "seaCoverage": 0.55, "axialTiltDeg": 9,
"solar": 1.15, "planetRadius": 0.6, "age": 9, "ageSpan": 0.9 },
"biomes": [ { "id": "tundra", "name": "tundra", "color": [150,12,60] }, … ],
"n": 1468,
"points": [ [lon, lat], … ], // degrees, one per cell
"elev": [ … ], // shore = 0, + land / − sea
"water": [ … ], // 0 land · 1 ocean · 2 lake
"biome": [ … ], // index into `biomes`
"rivers": [ [lon,lat, lon,lat, flow], … ], // downstream segments
"plates": [ { "lon","lat","oceanic","speed" }, … ]
}
The arrays are parallel and one entry per cell. biome[i] indexes the biomes legend; each colour is [hue, saturation%, lightness%]. To render: place each cell at its points[i] and colour by biome, or feed the points to your own Voronoi/triangulation for a polygon map.
# a small, dramatic, ancient dwarf planet
/api/world?seed=42&radius=0.5&age=12
# a bright, drowned ocean world
/api/world?seed=99&solar=1.3&water=30&ocean=80
# fetch + read the genome
curl -s "https://mino.mobi/api/world?seed=7" | jq .meta
Note: the API runs the reference (JavaScript) engine; the browser viewer runs the Rust/WASM engine at higher resolution. Both are internally deterministic, but a given seed renders at a different cell count between them, so they are not pixel-identical — the API is its own self-consistent world source.
mappa/engine.js is the dependency-free reference (and the API + fallback). mappa/engine-rs/ is the same pipeline in Rust, compiled to WASM with wasm-pack, used by the browser at ~16k cells. The viewer loads the WASM if present and falls back to JS otherwise, so the site never breaks.mulberry32 PRNG and integer-hash value noise. Same seed ⇒ same draws.triangles = 2·vertices − 4) on every world — the invariant that certifies a correct sphere triangulation.mappa is a stylized model, not a research simulator — each mechanic is a deliberately simplified take on a real body of work. These are the ideas it draws on, if you want to dig past the cartoon.
delaunator kernel).