{"version":3,"sources":["biome-relief.mjs"],"sourcesContent":["// WHAT EACH BIOME'S GROUND IS SHAPED LIKE (the owner, Sep 30). Of sixteen ways to shape the ground the owner liked\n// three: the geology as it is (nearly flat), hummocks (bumps about four columns across, up to two cells) and the biome\n// previews' hills (about six columns, up to three cells), each climbed in single steps. Then: \"ensure that all biomes\n// operate within those height variations going forward … use biomes to determine what reliefs will look like …\n// not have hilly plains or completely flat dunes.\"\n//\n// So the land has a budget of a few cells over the sea (LAND_BUDGET), and each biome says how that budget is spent:\n//   geo    the share shaped by the world's geology (its uplands and lowlands, as version 4 simulates them)\n//   amp    the share shaped by the biome's own relief\n//   size   how wide that relief's features are, in columns\n//   style  'flat' (none of its own), 'hummocks', 'hills', 'swells' (long and low), 'dunes' (ridges across the wind,\n//          a gentle windward slope and a steeper lee), 'terraces' (hills flattened into steps) or 'craters' (round\n//          bowls with a raised rim, of many sizes, overlapping: craterField)\n// geo + amp is at most 1, so no biome rises past the budget. Where no biome is, the geology spends it all (the first\n// option). The generator (transient-shape.js, version 4) and Kubipedia's biome models (biome-diorama.mjs) both read this\n// table, so a model shows the ground a world has. Pure and exact (no Math.sin, pow or random): the servers' copies\n// (functions/lib, zone-server/lib) are byte-identical.\nexport const RELIEF = Object.freeze({\n  none:           Object.freeze({ geo: 1,    amp: 0,    size: 0,  style: 'flat' }),\n  duneSea:        Object.freeze({ geo: 0.15, amp: 0.85, size: 7,  style: 'dunes' }),\n  saltFlats:      Object.freeze({ geo: 0.1,  amp: 0,    size: 0,  style: 'flat' }),\n  glacier:        Object.freeze({ geo: 0.4,  amp: 0.45, size: 10, style: 'swells' }),\n  volcanicFields: Object.freeze({ geo: 0.3,  amp: 0.2,  size: 5,  style: 'hummocks' }),\n  crystalFields:  Object.freeze({ geo: 0.3,  amp: 0.55, size: 4,  style: 'hummocks' }),\n  lichenSteppe:   Object.freeze({ geo: 0.3,  amp: 0.55, size: 5,  style: 'hummocks' }),\n  woods:          Object.freeze({ geo: 0.1,  amp: 0.9,  size: 6,  style: 'hills' }),\n  bloomCarpets:   Object.freeze({ geo: 0.3,  amp: 0.4,  size: 7,  style: 'hills' }),\n  gillTowers:     Object.freeze({ geo: 0.3,  amp: 0.55, size: 4,  style: 'hummocks' }),\n  tidalGardens:   Object.freeze({ geo: 0.5,  amp: 0.3,  size: 5,  style: 'hummocks' }),\n  nightsideGlow:  Object.freeze({ geo: 0.3,  amp: 0.55, size: 5,  style: 'hummocks' }),\n  hothouseCanopy: Object.freeze({ geo: 0.1,  amp: 0.9,  size: 6,  style: 'hills' }),\n  spiritGardens:  Object.freeze({ geo: 0.1,  amp: 0.9,  size: 5,  style: 'hills' }),\n  tholinReefs:    Object.freeze({ geo: 0.3,  amp: 0.55, size: 5,  style: 'hummocks' }),\n  // The atlas's later biomes (Sep 30).\n  rimeWoods:       Object.freeze({ geo: 0.1,  amp: 0.9,  size: 6,  style: 'hills' }),\n  aridParkland:    Object.freeze({ geo: 0.3,  amp: 0.35, size: 9,  style: 'swells' }),\n  stiltrootFens:   Object.freeze({ geo: 0.1,  amp: 0.15, size: 5,  style: 'hummocks' }),\n  reedspireStands: Object.freeze({ geo: 0.2,  amp: 0.4,  size: 5,  style: 'hummocks' }),\n  glowcapStands:   Object.freeze({ geo: 0.3,  amp: 0.55, size: 4,  style: 'hummocks' }),\n  siphonTubes:     Object.freeze({ geo: 0.3,  amp: 0.55, size: 5,  style: 'hummocks' }),\n  resinLattices:   Object.freeze({ geo: 0.2,  amp: 0.7,  size: 6,  style: 'hills' }),\n  quartzDendrites: Object.freeze({ geo: 0.2,  amp: 0.7,  size: 5,  style: 'hills' }),\n  silicateShells:  Object.freeze({ geo: 0.3,  amp: 0.5,  size: 4,  style: 'hummocks' }),\n  glassVeinwood:   Object.freeze({ geo: 0.3,  amp: 0.3,  size: 5,  style: 'hummocks' }),\n  latticeColonies: Object.freeze({ geo: 0.3,  amp: 0.5,  size: 5,  style: 'hummocks' }),\n  sulfurBlooms:    Object.freeze({ geo: 0.3,  amp: 0.3,  size: 5,  style: 'hummocks' }),\n  rustSpires:      Object.freeze({ geo: 0.2,  amp: 0.7,  size: 5,  style: 'hills' }),\n  cryoFerns:       Object.freeze({ geo: 0.3,  amp: 0.55, size: 5,  style: 'hummocks' }),\n  methaneMats:     Object.freeze({ geo: 0.3,  amp: 0.2,  size: 5,  style: 'hummocks' }),\n  tholinThickets:  Object.freeze({ geo: 0.2,  amp: 0.6,  size: 6,  style: 'hills' }),\n  bubbleFens:      Object.freeze({ geo: 0.2,  amp: 0.1,  size: 5,  style: 'hummocks' }),\n  rimeFringe:      Object.freeze({ geo: 0.4,  amp: 0.45, size: 10, style: 'swells' }),\n  // The water biomes: their floor is the sea's (THE GROUND'S HEIGHTS); the land round them the geology's.\n  ocean:           Object.freeze({ geo: 1,    amp: 0,    size: 0,  style: 'flat' }),\n  lake:            Object.freeze({ geo: 0.6,  amp: 0.3,  size: 6,  style: 'hummocks' }),\n  river:           Object.freeze({ geo: 0.4,  amp: 0.5,  size: 7,  style: 'hills' }),\n  // Wave 2 of the atlas: its new living biomes.\n  puffballDomes:   Object.freeze({ geo: 0.3,  amp: 0.55, size: 5,  style: 'hummocks' }),\n  shelfTerraces:   Object.freeze({ geo: 0.2,  amp: 0.7,  size: 6,  style: 'hills' }),\n  glowmossPillars: Object.freeze({ geo: 0.3,  amp: 0.4,  size: 5,  style: 'hummocks' }),\n  glowMosaic:      Object.freeze({ geo: 0.3,  amp: 0.2,  size: 9,  style: 'swells' }),\n  prismCoral:      Object.freeze({ geo: 0.3,  amp: 0.4,  size: 4,  style: 'hummocks' }),\n  boneArches:      Object.freeze({ geo: 0.3,  amp: 0.45, size: 9,  style: 'swells' }),\n  landKelp:        Object.freeze({ geo: 0.2,  amp: 0.5,  size: 8,  style: 'swells' }),\n  veinCoral:       Object.freeze({ geo: 0.3,  amp: 0.4,  size: 5,  style: 'hummocks' }),\n  vaultedReefs:    Object.freeze({ geo: 0.3,  amp: 0.3,  size: 5,  style: 'hummocks' }),\n  glowSlime:       Object.freeze({ geo: 0.3,  amp: 0.45, size: 4,  style: 'hummocks' }),\n  fleshPods:       Object.freeze({ geo: 0.2,  amp: 0.6,  size: 6,  style: 'hills' }),\n  frostFerns:      Object.freeze({ geo: 0.3,  amp: 0.5,  size: 5,  style: 'hummocks' }),\n  crystalWarrens:  Object.freeze({ geo: 0.2,  amp: 0.7,  size: 5,  style: 'hills' }),\n  matCrags:        Object.freeze({ geo: 0.2,  amp: 0.8,  size: 5,  style: 'hills' }),\n  // Wave 3: new ground. 'terraces' are hills flattened into steps of a third of the budget, each a single step.\n  bandedScarps:    Object.freeze({ geo: 0.2,  amp: 0.8,  size: 7,  style: 'terraces' }),\n  needlePeaks:     Object.freeze({ geo: 0.3,  amp: 0.7,  size: 4,  style: 'hills' }),\n  karstTowers:     Object.freeze({ geo: 0.3,  amp: 0.4,  size: 5,  style: 'hummocks' }),\n  glassShields:    Object.freeze({ geo: 0.3,  amp: 0.4,  size: 8,  style: 'swells' }),\n  gemHollows:      Object.freeze({ geo: 0.3,  amp: 0.5,  size: 4,  style: 'hummocks' }),\n  oreOutcrops:     Object.freeze({ geo: 0.3,  amp: 0.5,  size: 5,  style: 'hummocks' }),\n  sulfurSprings:   Object.freeze({ geo: 0.2,  amp: 0.6,  size: 6,  style: 'terraces' }),\n  firnFields:      Object.freeze({ geo: 0.15, amp: 0.7,  size: 5,  style: 'dunes' }),\n  cryovolcanicPlains: Object.freeze({ geo: 0.3, amp: 0.2, size: 10, style: 'swells' }),\n  tholinTerraces:  Object.freeze({ geo: 0.2,  amp: 0.8,  size: 7,  style: 'terraces' }),\n  methaneOasis:    Object.freeze({ geo: 0.15, amp: 0.7,  size: 7,  style: 'dunes' }),\n  // Wave 4: void rifts, drift isles and the remains.\n  voidRifts:       Object.freeze({ geo: 0.3,  amp: 0.4,  size: 5,  style: 'hummocks' }),\n  driftIsles:      Object.freeze({ geo: 0.3,  amp: 0.4,  size: 9,  style: 'swells' }),\n  corMonoliths:    Object.freeze({ geo: 0.3,  amp: 0.2,  size: 10, style: 'swells' }),\n  wreckFields:     Object.freeze({ geo: 0.3,  amp: 0.3,  size: 8,  style: 'swells' }),\n  prospectorRelics: Object.freeze({ geo: 0.3, amp: 0.4,  size: 5,  style: 'hummocks' }),\n  fossilBeds:      Object.freeze({ geo: 0.3,  amp: 0.3,  size: 9,  style: 'swells' }),\n  signalArrays:    Object.freeze({ geo: 0.3,  amp: 0.15, size: 10, style: 'swells' }),\n  // Wave 5 (version 6, Oct 2): the bare ground of airless and thin-air worlds. The hills take the wind's dunes, as the\n  // owner asked (\"similar to dunes\"); the mare is flat; the regolith rolls a little; the craters are bowls whose\n  // `size` is the largest one's radius in columns (4 to 14 across, the owner's), sunk to the floor of the budget with a\n  // rim near its top: on a three-cell budget about two and a half cells from rim to floor. Smaller and more of them\n// (the owner, Oct 2: \"2-3 fit in the biome preview and more on world\"): 2.4 to 8 columns across.\n  mineralHills:    Object.freeze({ geo: 0.15, amp: 0.85, size: 7,  style: 'dunes' }),\n  mineralMare:     Object.freeze({ geo: 0.1,  amp: 0,    size: 0,  style: 'flat' }),\n  craterFields:    Object.freeze({ geo: 0.2,  amp: 0.8,  size: 4,  style: 'craters' }),\n  regolithPlains:  Object.freeze({ geo: 0.3,  amp: 0.25, size: 9,  style: 'swells' }),\n  // Wave 6 (version 12, Oct 11). Within the same budget as every other biome; what stands taller is bits (organics.mjs:\n  // basalt columns, salt spires, mesas and buttes, penitentes, mud cones, stromatolites). Slot canyons and cenotes are\n  // plains and limestone flats whose cuts are made after the band (transient-shape.js THE CUTS), not by this table.\n  mudpots:         Object.freeze({ geo: 0.3,  amp: 0.15, size: 5,  style: 'hummocks' }),\n  columns:         Object.freeze({ geo: 0.3,  amp: 0.5,  size: 6,  style: 'terraces' }),\n  halite:          Object.freeze({ geo: 0.1,  amp: 0,    size: 0,  style: 'flat' }),\n  cenotes:         Object.freeze({ geo: 0.2,  amp: 0,    size: 0,  style: 'flat' }),\n  slots:           Object.freeze({ geo: 0.3,  amp: 0.3,  size: 9,  style: 'swells' }),\n  mesas:           Object.freeze({ geo: 0.25, amp: 0.15, size: 10, style: 'swells' }),\n  ash:             Object.freeze({ geo: 0.2,  amp: 0.55, size: 6,  style: 'swells' }),\n  penitentes:      Object.freeze({ geo: 0.3,  amp: 0.2,  size: 5,  style: 'hummocks' }),\n  pitch:           Object.freeze({ geo: 0.2,  amp: 0.1,  size: 5,  style: 'hummocks' }),\n  stroma:          Object.freeze({ geo: 0.5,  amp: 0.2,  size: 5,  style: 'hummocks' }),\n  hanging:         Object.freeze({ geo: 0.2,  amp: 0.8,  size: 6,  style: 'terraces' }),\n  thorns:          Object.freeze({ geo: 0.3,  amp: 0.25, size: 9,  style: 'swells' }),\n  // version 17's settlement biomes (alien-peoples.mjs): laid by the towns once the ground is shaped, so on a world they\n  // shape nothing; this is the look of their Kubipedia models, the cleared and trodden ground round a town.\n  ...Object.fromEntries(['terraceGardens', 'herdCommons', 'thornBastions', 'hearthHollows', 'iceFisheries', 'fangRidges', 'shadeTerraces', 'caravanWells', 'reaverSlots',\n    'kilnGardens', 'tektiteFields', 'ashWarrens', 'weaverShores', 'driftFens', 'hazeReefs', 'domeCraters', 'dustQuarries', 'corsairWrecks']\n    .map((id) => [id, Object.freeze({ geo: 0.5, amp: 0.1, size: 6, style: 'terraces' })])),\n});\nexport const reliefOf = (id) => RELIEF[id] || RELIEF.none;\n\n// The land's budget over the sea, in cells: three (the previews' hills), two on the smallest worlds. The sea's floor\n// (or a dry world's basins) takes as much again below it, so the ground's band is twice this at least.\nexport const landBudget = (R) => (R >= 24 ? 3 : 2);\nexport const bandDepth = (R) => Math.max(Math.floor(R / 10), 2 * landBudget(R));\n\nconst sm = (t) => (t <= 0 ? 0 : t >= 1 ? 1 : t * t * (3 - 2 * t));\n// A relief field in 0..1 from a noise sample n in 0..1 (value noise bunches about a half; this spreads it over the\n// whole range, so a hill reaches the budget and a hollow reaches the base).\nexport const spread = (n) => sm((n - 0.22) / 0.56);\n// A dune's cross-section from its phase f in 0..1 along the wind: the windward slope over 72% of it, the lee over 28%.\nexport const duneProfile = (f) => (f < 0.72 ? f / 0.72 : (1 - f) / 0.28);\n// Terraces from a hills field g in 0..1: flat steps a third of the budget apart.\nexport const terraceOf = (g) => Math.floor(g * 3.999) / 3;\n// CRATERS (the owner, Oct 2: \"crater fields, made of minerals with circular depressions\"; bowls with rims). The relief\n// field at a column, 0..1: CRATER_PLAIN on open ground, a bowl falling to 0 at a crater's centre, its rim at 1 and\n// easing back to the plain over CRATER_APRON of its radius outside. A younger crater cuts an older one's rim, so the\n// lowest bowl at a point wins over any rim, and the highest rim over the plain.\n// Craters sit one at most in each cell of a grid CRATER_CELL radii wide, CRATER_HAS of the cells holding one, at a\n// jittered spot and a radius from CRATER_MIN of `size` up to `size`. On a world (`shell`), each centre is moved onto the\n// cube's shell the column stands on (scaled to the column's own max-norm), so every crater reaches the ground and\n// craters run over a cube's edges and corners like anything else. A flat model (Kubipedia's, shell = false) is a\n// plane through y = py: its craters are laid on that plane, one grid layer of them, so every one shows.\n// Only + - * /, sqrt, floor and integer hashing, like the rest of this file: the servers' twins answer the same.\nexport const CRATER_PLAIN = 0.42, CRATER_APRON = 0.6, CRATER_MIN = 0.3, CRATER_CELL = 2, CRATER_HAS = 0.55;\nfunction chash(ix, iy, iz, s) {\n  let h = Math.imul(ix, 0x27d4eb2d) ^ Math.imul(iy, 0x165667b1) ^ Math.imul(iz, 0x3c6ef372) ^ s;\n  h = Math.imul(h ^ (h >>> 15), 0x85ebca6b); h = Math.imul(h ^ (h >>> 13), 0xc2b2ae35); h ^= h >>> 16;\n  return (h >>> 0) / 4294967296;\n}\nconst ab = (v) => (v < 0 ? -v : v);\nexport function craterField(px, py, pz, size, seed, shell = true) {\n  if (!(size > 0)) return CRATER_PLAIN;\n  const C = size * CRATER_CELL, s = seed | 0;\n  const m = shell ? Math.max(ab(px), ab(py), ab(pz)) : 0;\n  const ix = Math.floor(px / C), iy = Math.floor(py / C), iz = Math.floor(pz / C);\n  let bowl = 2, rim = CRATER_PLAIN;\n  const dyLo = shell ? -1 : 0, dyHi = shell ? 1 : 0;\n  for (let dx = -1; dx <= 1; dx++) for (let dy = dyLo; dy <= dyHi; dy++) for (let dz = -1; dz <= 1; dz++) {\n    const cx = ix + dx, cy = iy + dy, cz = iz + dz;\n    if (chash(cx, cy, cz, s) >= CRATER_HAS) continue;\n    let ox = (cx + chash(cx, cy, cz, s ^ 0x51)) * C, oy = shell ? (cy + chash(cx, cy, cz, s ^ 0xa3)) * C : py, oz = (cz + chash(cx, cy, cz, s ^ 0xf5)) * C;\n    if (shell) { const mm = Math.max(ab(ox), ab(oy), ab(oz)); if (!(mm > 0)) continue; const k = m / mm; ox *= k; oy *= k; oz *= k; }\n    const r = size * (CRATER_MIN + (1 - CRATER_MIN) * chash(cx, cy, cz, s ^ 0x3c7));\n    const ex = px - ox, ey = py - oy, ez = pz - oz, t = Math.sqrt(ex * ex + ey * ey + ez * ez) / r;\n    if (t < 1) { const v = t * t; if (v < bowl) bowl = v; }                                   // the bowl: 0 at the centre, the rim's height at its edge\n    else if (t < 1 + CRATER_APRON) { const v = 1 - (t - 1) / CRATER_APRON * (1 - CRATER_PLAIN); if (v > rim) rim = v; }   // the rim, easing out to the plain\n  }\n  return bowl < 2 ? bowl : rim;\n}\n\n// A column's height over the land's base, in cells: geology x and the biome's field g each in 0..1, and `coast` in\n// 0..1 easing the biome's relief up from the shore so no hill stands in the surf.\nexport function reliefHeight(r, x, g, coast, budget) {\n  return budget * (r.geo * x + r.amp * g * coast);\n}\n\n// ROUND HOLES (version 12's cenotes, Oct 11): how far a point lies into the nearest of a scatter of round holes, as the\n// share of its radius from the rim (1 at the centre, 0 at the rim, below 0 outside). The holes sit as craterField's\n// craters do, one at most in each cell of a grid HOLE_CELL radii wide, HOLE_HAS of the cells holding one, at a jittered\n// spot, of radius `size` times 0.6 to 1; on a world each centre is moved onto the shell the point stands on, so a hole\n// runs over an edge like anything else. A flat model (Kubipedia's, shell = false) lays them on the plane y = py.\nexport const HOLE_CELL = 3, HOLE_HAS = 0.5;\nexport function holeField(px, py, pz, size, seed, shell = true) {\n  if (!(size > 0)) return -1;\n  const C = size * HOLE_CELL, s = seed | 0;\n  const m = shell ? Math.max(ab(px), ab(py), ab(pz)) : 0;\n  const ix = Math.floor(px / C), iy = Math.floor(py / C), iz = Math.floor(pz / C);\n  let best = -1;\n  const dyLo = shell ? -1 : 0, dyHi = shell ? 1 : 0;\n  for (let dx = -1; dx <= 1; dx++) for (let dy = dyLo; dy <= dyHi; dy++) for (let dz = -1; dz <= 1; dz++) {\n    const cx = ix + dx, cy = iy + dy, cz = iz + dz;\n    if (chash(cx, cy, cz, s ^ 0x77) >= HOLE_HAS) continue;\n    let ox = (cx + chash(cx, cy, cz, s ^ 0x15)) * C, oy = shell ? (cy + chash(cx, cy, cz, s ^ 0x2b)) * C : py, oz = (cz + chash(cx, cy, cz, s ^ 0x6d)) * C;\n    if (shell) { const mm = Math.max(ab(ox), ab(oy), ab(oz)); if (!(mm > 0)) continue; const k = m / mm; ox *= k; oy *= k; oz *= k; }\n    const r = size * (0.6 + 0.4 * chash(cx, cy, cz, s ^ 0x91));\n    const ex = px - ox, ey = py - oy, ez = pz - oz, v = 1 - Math.sqrt(ex * ex + ey * ey + ez * ez) / r;\n    if (v > best) best = v;\n  }\n  return best;\n}\n"],"mappings":"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","names":[],"file":"biome-relief.mjs"}