Files
2026-09-25 17:02:24 +03:00

44 KiB
Raw Permalink Blame History

World Orogen

A browser-based procedural planet generator that creates realistic terrestrial planets with tectonic plate simulation, elevation modeling, and interactive editing. Uses native ES modules with no build step required.

Live Site Three.js No Build

Philosophy

World Orogen is concept art for planets. It's built for the moment early in a project when you need a world that looks real — believable tectonics, organic coastlines, climate patterns that feel right — but you don't need a geophysical simulation to get there. The science isn't decoration: plate collision models inspired by real tectonics, pressure-driven wind patterns, and Köppen classification are what make the output feel convincing at a glance. If a climate scientist squints and finds inaccuracies, that's fine — but the scientific foundation is what earns the first glance. Plausibility, not precision.

The core value is creative velocity. Generate a planet in seconds, tweak plates and terrain until it matches your vision, then export high-resolution maps into whatever comes next — Gaea, Wonderdraft, Photoshop, a game engine, a novel outline. Orogen is designed to be the fastest path from a blank page to a world worth building on — the first tool in your worldbuilding pipeline, not the last.

Guiding Principles

  1. Artistic appeal — Visually interesting, scientifically informed output. Aesthetics come first.
  2. Ease of use and efficiency — Approachable interface, fast generation. Don't sacrifice usability for realism.
  3. Scientific plausibility — Grounded in real planetary science. Believable, not necessarily physically accurate.

All three are considered together; ties are broken in the order above.

Features

  • Fibonacci sphere meshing with Voronoi cell tessellation via Delaunay triangulation
  • Tectonic plate simulation — farthest-point seed placement with top-3 jitter, round-robin flood fill with directional growth bias, growth-rate governor, compactness penalty to prevent spindly shapes, multi-pass boundary smoothing, and fragment reconnection
  • Ocean/land assignment — farthest-point continent seeding, round-robin growth with separation guarantees, trapped sea absorption, targeting ~30% land coverage
  • Collision detection — convergent, divergent, and transform boundary classification with density-based subduction modeling; dual-layer super plate system groups same-type plates into ~20 tectonic units for broad orogenic belts blended 50/50 with fine-grained individual plate orogeny
  • Elevation generation — three distance fields (mountain/ocean/coastline) combined via harmonic-mean formula, stress-driven uplift, asymmetric mountain profiles, continental shelf/slope/abyss profiles, foreland basins, plateau formation, and rift valleys with graben profiles
  • Ocean floor features — mid-ocean ridges at divergent boundaries, deep trenches at subduction zones, fracture zones at transform boundaries, back-arc basins behind subduction zones
  • Island arcs — volcanic island chains at ocean-ocean convergent boundaries with ridged noise shaping
  • Hotspot volcanism — dual-component mantle plume model (broad thermal swell + volcanic peak) with drift-trail island chains, domain-warped shape distortion, drift-direction elongation, summit calderas on active domes, radial rift-zone ridges, age-dependent volcanic texture, and per-hotspot variation in strength/decay/spacing
  • Terrain post-processing — noise-based domain warping (FBM simplex noise with greedy mesh walk) to deform the elevation field for organic coastlines and mountain ridges, independently controllable bilateral smoothing to blend harsh BFS distance-field boundaries, glacial erosion that carves fjords, U-shaped valleys, and lake basins at high latitudes and altitudes via latitude-driven ice flow with drainage accumulation, priority-flood pit resolution with canyon carving (Barnes et al. algorithm that ensures every land cell drains to the ocean, carving dramatic canyons through mountain saddle points rather than filling basins), iterative implicit stream power hydraulic erosion (Braun-Willett style) that carves self-reinforcing river valleys with automatic sediment deposition in flat receivers, thermal erosion that softens ridges via talus-angle material transport, ridge sharpening that accentuates mountain ridgelines, and always-on soil creep (Laplacian diffusion) that rounds off hillslopes
  • Coastal roughening — fractal noise with active/passive margin differentiation, domain warping for bays/headlands, and offshore island scattering
  • 3D globe rendering with atmosphere rim shader, translucent water sphere, terrain displacement, and starfield
  • Equirectangular map projection with antimeridian wrapping
  • Interactive editing — Ctrl-click plates to mark them for reshaping (multi-select with visual tinting), then click Rebuild to apply all changes at once. Ctrl-click again to undo a pending selection. Press Escape to cancel all pending edits
  • Seasonal wind simulation — pressure-driven wind patterns with a longitude-varying ITCZ that tracks the thermal equator (~5° over ocean, up to 15-20° over continents), Gaussian pressure bands (subtropical highs, subpolar lows, polar highs), land/sea thermal contrast for monsoon-like pressure reversals, elevation barometric effects, and Coriolis-deflected geostrophic wind with natural cross-equatorial flow reversal. Computed for both summer and winter seasons.
  • Ocean surface currents — rule-based geographic gyre simulation driven by wind belts (trade winds, westerlies, polar easterlies) with a longitude-varying ITCZ equatorial countercurrent. Continental shelves are classified as western or eastern boundaries via coast-normal BFS, producing subtropical gyres (CW in NH, CCW in SH) with western boundary intensification (Gulf Stream, Kuroshio effect) and weaker eastern boundary return flow. Detects circumpolar channels for unobstructed eastward currents (Antarctic Circumpolar Current). Currents are colored by heat transport: red = warm poleward flow, blue = cold equatorward flow, black = zonal (neutral). Computed for both summer and winter seasons.
  • Precipitation — blended dual-model approach: a complex moisture advection simulation is combined 50-50 with a fast heuristic zonal model. The advection model simulates wind-driven moisture transport from coasts with six mechanisms: ITCZ convective uplift, frontal convergence, orographic rain/shadow, lee cyclogenesis, polar-front precipitation, and subtropical high suppression. The heuristic model provides smooth latitude-based patterns (ITCZ wet belt, subtropical dry belt, mid-latitude recovery, polar dryness) modulated by continentality and orographic effects. Blending the two reduces splotchiness while preserving terrain-informed detail and strengthening subtropical desert formation (~20–35°). Visualized on a brown (dry) → green (moderate) → blue (wet) color ramp. Computed for both summer and winter seasons.
  • Map type switcher — first-class Terrain / Satellite / Climate / Heightmap tabs with color legends for each view
  • On-demand climate — optional deferred climate computation; skip climate during generation for faster terrain iteration, compute it on demand when needed
  • Detailed visualization — twenty-six selectable inspection layers organized by category (Geology, Atmosphere, Ocean, Climate, Elevation) for viewing each component in isolation. Wind/pressure layers show directional wind arrows, ocean current layers show current arrows colored by heat transport, on both globe and map views. Precipitation layers use a brown→green→blue ramp showing dry to wet regions.
  • Heightmap import — bring your own equirectangular B&W heightmap (Earth, Mars, hand-drawn maps) onto a 3D globe. Black pixels become ocean, brighter pixels become higher land. The import page (/import) runs full climate simulation (wind, precipitation, temperature, Köppen) on your imported terrain, with optional terrain sculpting (smoothing, erosion, ridge sharpening). Supported formats: PNG, JPEG, WebP.
  • Painted map import — paint a flat map where every colour is a class (a rate of rock uplift and an erodibility, never a height) and a legend JSON says what the colours mean; the import page's Painted Map source solves the stream-power equation dh/dt = U − K·A^m·S on the sphere mesh (Braun-Willett implicit scheme, priority-flood drainage, hillslope diffusion) until the land is in balance with its uplift, so rivers, divides and valley hierarchy come out of the physics. Classes carry massif blocks (a plain with hill masses standing out of it, cut at a quantile of the whole planet), coastal-plain ramps, a planet-wide rock field that multiplies erodibility, and a regional swell; the drawn coastline is roughened with fractal noise before the solve. Six extra inspect layers and export types: class map, uplift rate, erodibility, drainage (rivers), slope and drainage basins. The legend format is shared with the Salty terrain generator's terrain plan / terrain bake.
  • Map export — download high-resolution equirectangular PNGs (color terrain, satellite biome, climate/Köppen, B&W heightmap, land-only heightmap, or B&W land mask) at configurable widths up to 65536px with tiled rendering. Export All downloads Satellite, Climate, Heightmap, and Land Mask in one click, auto-computing climate if needed.
  • Unreal landscape export — render a window of the planet straight into the tile set Unreal Engine's landscape importer wants: a 16-bit greyscale height per tile at 255·N+1 vertices (one Landscape actor each), an 8-bit weightmap per paint layer beside it, and a Region.json describing the grid. Unlike the map exports, this one carries a scale: you give the planet's circumference and the export records metres-per-pixel, the window in degrees, and the projection, so nothing downstream has to guess. Files are written into a folder you pick (Chrome/Edge, File System Access API). See Unreal landscape export below.

Quick Start

Serve the project with any local HTTP server (required for ES modules):

# Python
python3 -m http.server 8000

# Or Node.js
npx serve .

Then open http://localhost:8000 in your browser. No dependencies to install, no build step.

Click Build New World to create a new random planet. The button changes color and label based on what you've adjusted:

  • Build New World (blue) — generates a fresh planet with a new random seed
  • Rebuild (amber) — re-renders the current planet at a new detail/roughness level without changing continent shapes
  • Regenerate (red) — creates new tectonic plates when the Plates or Continents slider has changed

Navigation

A top navigation bar connects the two pages:

  • Generate (/) — procedural planet generation with tectonic plates, erosion, and climate
  • Import (/import) — two sources, switched at the top of the panel:
    • Heightmap — import your own equirectangular B&W heightmap, view it on a 3D globe, and run climate simulation. Black (0) = ocean, brighter = higher elevation. Supports PNG, JPEG, and WebP.
    • Painted Map — import a painting whose colours are legend classes plus the legend JSON (a built-in legend and a demo painting are included), edit the classes' uplift rates, depths and erodibilities in the table, and click Solve Terrain. The report says how many pixels matched no class and whether the left and right edges agree (they are the same meridian). Optionally add Planet.json (the Salty generator's manifest), an Overlay annotation layer, or load all of them from a running terrain studio.

Painted Map controls

Control Range Default Description
Peak Height 0.5 – 6 km 4.5 km The 99.5th percentile of the solved land is put at this height. The shape is the solve's; this is only the scale (for n = 1 the steady state is linear in uplift over erodibility)
Ocean Depth 0.25 – 5 km 4 km Depth of the deepest sea class; shallower classes (shelf, surf) scale with it, and every shore ramps down over a couple of cells
Coast Detail 0 – 1 0.35 Fractal noise added to the signed distance from the painted waterline before the solve, up to three cells of shift. Islets keep at least a third of their width
Uplift Variation 0 – 0.6 0.30 A regional swell over the painted rate, so a lowland painted in one colour has basins and rises of its own
Solve Steps 50 – 600 200 How long the stream-power solve runs. About 12 s at 204K regions
Painted world circumference km 100 Distances in the legend (coastal plains, massif and rock sizes) are in the painted world's kilometres and are scaled to the Earth-sized globe by the ratio of circumferences
Massif size km 7 Block size of the planet's upland fabric — how big the hill masses standing out of a plain are
Rock province size km 8 Province size of the planet's rock field, which multiplies each class's erodibility
Seed integer 7945 Re-rolls what the painting does not fix: the massifs, the rock provinces, the swell and the coastline detail. Re-roll picks a new one

The class table's two angles

Each land class shows the typical hillslope its uplift rate makes on the Salty generator's 8 m geology grid, and what that ground reads as — plain, rolling, hill country, mountain, alpine. Hovering a value gives the divide angle, the steepest ground the rate can make, and the P90.

Read the typical column. Steady state is S = U/(K·A^m) and A is smallest at the top of a catchment, so the divide angle is the steepest place in a world and almost none of a map is divide; the median comes out at about a third of it in tangent. Reading the divide angle as the landscape is how a legend gets set two or three times too hot. A class whose divide is past the angle of repose is marked clamped — there the repose clamp shapes the ground rather than the rivers, and raising the rate makes the summits higher without making the ground steeper. The note under the table gives the rate at which that begins.

The angles come from the bake's constants, which Planet.json carries: cell size, K, m and the angle of repose. Without it the defaults are the shipped planet's (8 m, 5e-5, 0.5, 35°).

Planet.json

The Salty generator's own manifest (RawContent/World/Planet.json). Loading it brings the planet block — circumference, massif and rock province sizes, uplift variation, seed — and the pipeline constants the angles above are about, so none of it has to be retyped. It outranks a legend's own planet block, because it is the file the two-hour bake actually reads.

Overlay

A second painting the same size as the template and registered to it, whose colours are marks rather than classes: forests, settlements, roads, and stretches of coast to leave alone. It answers a different question from the class template — every colour there is geology, and there is no uplift rate for a town — so it is a separate sheet with a legend of its own.

Blank is decided by alpha, never by a colour: an unpainted pixel is transparent, so no colour is spent on emptiness and an export with a white matte behind it does not turn the world into whatever mark white is nearest. An opaque pixel further than match_distance from every mark is dropped and counted, which is the only way a colour the legend forgot ever shows.

Exactly one mark property changes anything: coast_jitter scales how far the coast roughening may move the shore inside the mark. 0 pins a hand-drawn coastline exactly as painted while the rest of the world is still roughened; above 1 chews it harder, which is what makes a fjord coast. Everything else is inert — two solves with and without a forest are the same terrain.

The sheet is drawn as a texture, not voted onto the mesh, because a road is a few pixels wide and a region here covers tens of kilometres. The Overlay Sheet toggle drapes it over whatever layer is shown, on the globe and on the map; the Overlay inspect layer and export type draw it over a dimmed class map, and hovering a marked region names the mark.

The overlay legend JSON has a marks array; each mark has a name, an rgb triple, optionally kind: "path" with width_m, coast_jitter, min_area_px and a note. The file-level match_distance and min_area_px are the defaults.

From terrain studio

terrain studio (the Salty generator's painting tool) serves the painting it is holding, both legends and Planet.json read-only across origins. Enter its address and Load from studio brings the whole planet in one step, exactly as its next terrain plan would read it — including strokes made since the last save, because the studio holds the painting in memory. It needs a studio built on or after 2026-09-20. The studio only ever shares reads: nothing on this page can paint, save, plan or bake.

The legend JSON has a classes array; each class has a name, an rgb triple and either "sea": true with depth_m or uplift_mm_yr and k_mult, optionally massif: { floor_mm_yr, fraction }, coastal_plain_km / coastal_floor_mm_yr, lithology_mix, stroke: true (an outline colour that dissolves into its neighbours, or becomes edge_class where it touches a pole) and derived: true (a class that is never painted). An optional planet block carries circumference_km, massif_wavelength_km, lithology_wavelength_km, uplift_variation and lithology.k_multipliers. See assets/painted-legend.json. Download legend JSON writes the table's edits back into the loaded file with every other key intact.

Sharing Planets

Every generated planet produces a planet code (shown below the Build button) that encodes the random seed, all slider values, and any plate edits. An unedited planet is 21 characters; plate edits (applied via Rebuild) extend the code to include the toggled plates. Older codes (13–18 characters) from previous versions are still supported — missing sliders default to their current default values. To share a planet:

  • Copy the code with the copy button and send it to someone
  • Load a code by pasting it into the planet code field and clicking Load (or pressing Enter). The Load button turns blue when a new code is ready to apply.
  • URL sharing — the code is also stored in the URL hash (e.g. #a7f3kq9xp2b), so you can share the full URL directly. Opening a URL with a valid hash auto-loads that planet, including any plate edits.

Controls

Shape Your World

Core world parameters that control the planet's structure (changing these requires a full rebuild):

Control Range Default Description
Detail 5,000 – 2,560,000 204,000 Number of Voronoi cells on the sphere. Only affects rendering resolution — continent shapes are stable across detail levels (generated on a fixed ~20K reference grid)
Irregularity 0 – 1 0.75 Randomization of Fibonacci point positions
Plates 4 – 120 80 Number of tectonic plates
Continents 1 – 10 4 Target number of separate landmasses
Roughness 0 – 0.5 0.40 Fractal noise magnitude for terrain roughness
Continent Size Variety 0 – 1 0.35 How much continent sizes vary — 0 keeps continents similar in size, 1 allows a mix of large and small landmasses
Land Coverage 0 – 1 0.3 Percentage of the planet covered by land. Low values create ocean worlds, high values create desert worlds. Above 40% coverage, precipitation is progressively dampened to simulate reduced oceanic moisture

Terrain Sculpting

Post-processing passes that refine the terrain (collapsed by default — the defaults produce good results). These do not require a full rebuild; adjusting any slider lights up the Reapply button at the bottom of this section — click it to reapply only the sculpting passes on the current planet.

Control Range Default Description
Terrain Warp 0 – 1 0.75 Domain warping — deforms the elevation field using noise to produce organic, squiggly coastlines and mountain ridges
Smoothing 0 – 1 0.10 Blends harsh terrain boundaries from tectonic generation
Glacial Erosion 0 – 1 0.50 Ice-age sculpting — carves fjords, U-shaped valleys, and lake basins at high latitudes and altitudes via latitude-driven ice flow
Hydraulic Erosion 0 – 1 0.50 Iterative stream-power erosion — resolves endorheic basins via priority-flood canyon carving, then carves river valleys and dendritic drainage networks, with automatic sediment deposition in flat receivers
Thermal Erosion 0 – 1 0.10 Slope-driven material transport — softens ridges and creates natural talus slopes
Ridge Sharpening 0 – 1 0.50 Accentuates mountain ridgelines — pushes peaks further above their surroundings for more dramatic terrain

Climate

Global climate offsets that adjust temperature and precipitation without a full rebuild. Changing these triggers a fast climate-only recompute.

Control Range Default Description
Temperature -15 – 15 0 Global temperature offset in °C — positive makes the planet warmer, negative colder. Climate zones shift accordingly
Precipitation -1 – 1 0 Global precipitation scale — positive makes the planet wetter, negative drier. Affects desert and rainforest distribution

Auto Climate

Climate simulation (wind, ocean currents, precipitation, temperature, Köppen classification) runs automatically during generation when detail is ≤ 300K regions. Above 300K, climate is skipped for faster terrain iteration and computed on demand when switching to a climate-dependent view.

Visual Options

  • Map Type — segmented Terrain / Satellite / Climate / Heightmap tabs for quick switching between the four most common visualizations. Each tab shows a color legend:
    • Terrain — elevation color ramp from deep ocean through sea level to mountain peaks
    • Satellite — realistic biome colors based on Köppen climate classification and elevation (lush green rainforests, tan deserts, white ice caps, dark taiga, gray tundra), with ocean using the standard terrain palette. High elevations blend toward snow white based on climate-aware snow lines.
    • Climate — Köppen-Geiger classification with color swatches for all 30 climate types
    • Heightmap — black-to-white gradient on a fixed absolute scale (-5 km ocean floor to 6 km peaks), so the same physical height always maps to the same shade
  • View dropdown — switch between Globe and Map (equirectangular projection)
  • Center Longitude slider (map mode only) — shifts the map projection's central meridian to any longitude from 180°W to 180°E, scrolling the equirectangular projection so the chosen longitude is centered. Exports are unaffected (always centered on 0°).
  • Wireframe — toggle switch to show Voronoi cell edges as a wireframe overlay
  • Show Plates — toggle switch to color regions by plate (green shades = land, blue shades = ocean); also draws black super plate boundary lines showing tectonic super-groups
  • Auto-Rotate — toggle switch to spin the globe continuously
  • Grid Lines — toggle switch for latitude/longitude grid overlay on both globe and map views
  • Grid Spacing — choose the interval between grid lines: 30°, 15°, 10°, 5°, or 2.5°

Inspect Dropdown

The Inspect dropdown (in Visual Options, below the map tabs) selects a detailed visualization layer. On the import page a Painted Map group — Class Map, Uplift Rate, Erodibility, Drainage (Rivers), Slope, Drainage Basins — is enabled once a painted map is solved; the same six are export types, and Export All includes them. Options are organized into groups:

  • Main views (ungrouped at top) — Terrain, Satellite, Köppen Climate, Land Heightmap
  • Geology — Base, Tectonic, Noise, Interior, Coastal, Ocean Floor, Hotspot, Tectonic Activity, Margins, Back-Arc, Fold Ridge, Orogenic Power, Erosion Delta (blue = eroded, red = deposited)
  • Atmosphere — Pressure Summer/Winter (blue = low, red = high), Wind Speed Summer/Winter (with directional arrows on both globe and map)
  • Ocean — Currents Summer/Winter (red = warm poleward, blue = cold equatorward, black = zonal; with directional current arrows)
  • Climate — Precipitation Summer/Winter (brown = dry, green = moderate, blue = wet), Rain Shadow Summer/Winter (diverging blue = windward orographic boost, gray = neutral, red-brown = leeward rain shadow; leeward effects are seeded at downslope faces scaled by mountain height, then propagated ~1500 km downwind to show extended shadow zones like the foehn drying effect), Temperature Summer/Winter (purple-blue = cold, white = 0 C, green-yellow = warm, red = hot; fixed -45 to +45 C range), Continentality (blue = ocean, green = coast, yellow = moderate interior, orange/red = deep continental interior)
  • Elevation — Full Heightmap (full-range B&W)

Export

Click Export Map (below Visual Options) to open the export modal:

  • Type — Color Map (terrain colors), Satellite (biome colors from Köppen classification), Climate (Köppen classification colors), Heightmap (B&W full range on fixed -5 to 6 km absolute scale), Land Heightmap (B&W on fixed 0 to 6 km absolute scale, ocean is black), or Land Mask (pure B&W — white = land, black = ocean). Satellite and Climate options are disabled when climate hasn't been computed.
  • Width slider — 1024 to 65536 pixels (height is always width/2 for equirectangular). Large exports use tiled rendering to handle GPU texture limits.
  • Export — downloads the selected type as an equirectangular PNG with no grid overlay
  • Export All — downloads four maps (Satellite, Climate, Land Heightmap, Land Mask) sequentially. If climate hasn't been computed yet, it runs automatically before exporting.
  • A progress overlay shows rendering and PNG encoding status during export
  • Unreal Landscape… — opens the landscape tile exporter described below

Unreal landscape export

The map exports answer "draw the whole planet at width W". Unreal asks a different question, and the Unreal Landscape… button in the export modal answers it: what is the ground, in metres, over this rectangle of the planet, at the sample spacing the game uses?

It writes one <Level>_x<N>_y<N>_Height.png (16-bit greyscale, tiles.vertices square) and three 8-bit weightmaps per tile, plus Region.json, into a folder you choose. Every field re-plans as you type, and the readout under them says what that setting bought.

Field What it decides
Level The tiles are named after its last segment
Planet circumference The scale. A sphere carries no metres; this is what turns the window's degrees into ground, and it decides how much land a window can hold
Centre longitude / latitude Where the window sits. Keep it near the equator
Tiles across / down, Vertices a tile The grid. 255·N+1 vertices gives each tile N×N components of 255 quads — the component count is what costs, not the vertex count
Quad size Metres between vertices, in centimetres. 200 is a 2 m quad
Elevation floor / ceiling What 0 and 65535 mean. Too narrow clips (reported); too wide only costs height precision (also reported)
Sea scale Multiplies everything below sea level, so a whole-planet abyss does not force an elevation range that costs the land its precision. Land is untouched
Sample spacing How finely the planet is rendered before the tiles are cut from it. The mesh resolves a couple of hundred metres, so anything under ~25 m is already lossless

Three things about it are worth knowing.

The window is sampled once, then cut. The planet is rendered into a single float raster over the window and every tile is resampled out of that raster by its global vertex position, so a column two neighbours share is computed from the same source coordinates twice and comes out bit-identical. Nothing blends or stitches. Tiles carry a one-vertex margin while the paint layers are derived, because the layers read slope and a one-sided difference at a tile's edge is not what the neighbour computes there.

A small planet cannot hold a large flat window. The projection is equirectangular, cosine-corrected at the centre latitude, which splits the east-west error between the two edges instead of leaving it all on one. The readout prints that cost, and the panel says so plainly when the window is too big for the sphere: 936 km² on a 100 km-circumference planet is 29% of the entire globe, and reads as a window 110° on a side stretched 74.7% at its edge. That is arithmetic, not a bug — raise the circumference or use fewer rows.

It does not invent detail. The sphere mesh resolves a couple of hundred metres, so below that the ground is smooth no matter how finely it is sampled. What this export fixes is that the ground arrives in the shape Unreal wants with its scale attached; it does not make the ground finer.

An existing Region.json is never replaced — a hand-written one is mostly commentary explaining why each number is what it is, and a generated file would throw that away. When one is already in the folder the new manifest is written as Region.generated.json instead and the status line says so; rename it over the old one when you have read the difference. The tiles themselves are always overwritten.

Requires the File System Access API (Chrome or Edge on desktop); the panel says so if the browser lacks it.

Sidebar & Loading

The control panel can be collapsed and expanded with the « toggle button in the sidebar header. On small screens (≤ 768px) the sidebar becomes a bottom sheet with a drag handle — starts collapsed, showing only the handle and header. Drag up or tap the handle to expand. A fullscreen overlay with spinner, title, and progress bar appears during every generation — fully opaque on initial load, semi-transparent on subsequent builds so the previous planet is dimmed behind it. Stage labels (shaping, plates, oceans, mountains, painting) update as the pipeline progresses.

Tutorial & Help

A five-step tutorial modal introduces the tool on first visit (auto-shown via localStorage). It covers planet generation, slider controls, interactive editing, visualization, saving/sharing via planet codes, and map export. A ? help button in the top-right corner reopens the tutorial at any time. The modal can be dismissed with the close button, backdrop click, Escape key, or the "Get Started" button on the final step.

A What's New modal is shown once per release to returning users (those who have already dismissed the tutorial). It highlights new features, changes, and a heads-up that saved planet codes may produce different-looking worlds due to terrain/climate reworks. The modal uses a versioned localStorage flag (wo-whatsnew-seen) — bump the VERSION constant in initWhatsNew() to trigger it again on the next release.

Interaction

Navigation hints are shown in the sidebar panel and as a contextual tooltip when hovering the planet.

Action Desktop Mobile
Rotate globe / pan map Drag Drag (one finger)
Zoom Scroll wheel Pinch with two fingers
Highlight plate + info card Hover —
Mark plate for reshaping Ctrl-click a plate (multi-select) Tap the edit button (pencil), then tap plates
Undo pending plate Ctrl-click the same plate again Tap the same plate again
Apply pending edits Click the Rebuild button Tap the Rebuild button
Cancel all pending edits Press Escape —

Hovering over a region shows an info card with plate type, elevation, coordinates, and (when climate has been computed) temperature, precipitation, and Köppen classification. Pending plates show a colored tint (green = ocean→land, blue = land→ocean) and hover text indicates "(pending)".

Mobile Support

World Orogen is fully usable on phones and tablets:

  • Bottom-sheet sidebar — on screens 768px or narrower, the sidebar becomes a bottom sheet with a drag handle. Drag or tap the handle to expand/collapse. The globe stays visible above.
  • Pinch-to-zoom — two-finger pinch zooms the globe and map, using the same smooth lerp as desktop scroll-zoom.
  • View switcher — a dropdown in the top-right lets you switch between Terrain, Satellite, Climate, and Heightmap views without opening the bottom sheet.
  • Edit-mode toggle — a floating pencil button (bottom-right) activates plate editing. Tap it to toggle edit mode (glows green when active), then tap plates to mark them. Tap the Rebuild button to apply all changes at once.
  • Touch-friendly targets — buttons, checkboxes, and sliders are enlarged for comfortable finger input.
  • Performance — detail warning thresholds are lowered on touch devices (orange at 200K, red at 500K). Export widths above 8192px are disabled on mobile.
  • Tooltips reposition above their trigger instead of to the right, so they stay on screen.
  • Orientation changes are handled automatically.

How It Works

Pipeline

  1. Fibonacci spiral distributes N points evenly on a unit sphere with optional jitter
  2. Stereographic projection maps the sphere points to 2D
  3. Delaunator computes Delaunay triangulation in projected space
  4. Pole closure connects convex hull edges to a pole point, creating a watertight mesh
  5. Coarse plate generation on a fixed ~20,000-region reference mesh (resolution-independent), via farthest-point seed placement (with top-3 jitter for variety), round-robin flood fill with per-plate growth rates, directional bias coupled inversely to growth rate, growth-rate governor, and compactness penalty
  6. Ocean/land assignment on the coarse mesh using farthest-point continent seeding with area budgeting
  7. Plate projection maps coarse plate assignments onto the high-res mesh via nearest-neighbor adjacency walk, then smooths boundaries with resolution-scaled majority-vote passes
  8. Collision detection simulates plate drift to classify convergent/divergent/transform boundaries
  9. Stress propagation diffuses collision stress inward through continental plates via frontier BFS
  10. Elevation assignment combines distance fields, stress-driven uplift, ocean floor profiles, rift valleys, back-arc basins, hotspot volcanism, island arcs, coastal roughening, and multi-layered noise
  11. Terrain post-processing applies domain warping (controlled by Terrain Warp slider) using FBM simplex noise to deform the elevation field for organic coastlines and mountain ridges via greedy mesh walk, then bilateral smoothing (controlled by Smoothing slider) to blend BFS banding artefacts, glacial erosion (controlled by Glacial Erosion slider) carves fjords, U-shaped valleys, and lake basins at high latitudes and altitudes, priority-flood pit resolution carves canyons through mountain saddle points to ensure all land drains to the ocean, iterative implicit stream power hydraulic erosion with sediment deposition (controlled by Hydraulic Erosion slider) carves self-reinforcing river valleys, thermal erosion (controlled by Thermal Erosion slider) softens ridges via talus-angle material transport, ridge sharpening (controlled by Ridge Sharpening slider) accentuates mountain ridgelines, and always-on soil creep gently rounds off hillslopes
  12. Wind simulation computes a longitude-varying ITCZ by scanning for the thermal maximum at each longitude (accounting for land/sea heating differential and elevation lapse rate), builds pressure fields from Gaussian zonal bands centered on the ITCZ plus land/sea thermal modifiers and elevation barometric effects, then derives wind vectors from pressure gradients with latitude-dependent Coriolis deflection and surface friction. Computed for both NH summer and winter.
  13. Ocean currents uses a rule-based geographic approach: classifies ocean cells by wind belt (trades, westerlies, polar easterlies) to set base zonal flow, runs three BFS passes from coastal seeds to compute distance to western and eastern coastlines (classified by coast-normal direction), deflects currents poleward near western boundaries (warm, intensified ×2) and equatorward near eastern boundaries (cold, weaker ×0.8), detects circumpolar channels at ±60° latitude for unobstructed eastward flow, smooths with 5 Laplacian passes, and classifies heat transport by meridional flow direction. Computed for both seasons.
  14. Precipitation uses a blended dual-model approach. The complex model computes moisture advection from coasts using iterative upwind propagation driven by wind vectors, with depletion based on distance and elevation gain, plus six mechanisms: ITCZ convective uplift, frontal convergence at subpolar lows, orographic rain/rain shadow, lee cyclogenesis, polar front diffuse precipitation, and seasonal subtropical high suppression (shifts poleward in local summer to create Mediterranean dry-summer patterns). A heuristic zonal model computes smooth precipitation from ITCZ distance (with aggressive subtropical drying at 15–30°), seasonal hemisphere boost with Mediterranean subtropical suppression (up to 55% summer reduction at 25-42° latitude), continental dryness, and orographic rain shadow. The two models are blended 50-50 then normalized via 95th-percentile scaling. Computed for both seasons.
  15. Temperature computes per-cell surface temperature using the ITCZ as the thermal equator (28°C peak, warmest latitude band), with poleward cooling following a power-law curve (exponent 1.2, 13° tropical plateau, 52°C range). Modulated by seasonal hemisphere offset with latitude-dependent seasonal amplitude boost (up to ±12°C peaking at 55-75° latitude), continentality-scaled maritime factor (coast 0.50× to deep interior 1.20× seasonal swing), moisture-dependent elevation lapse rate (4.5 C/km in wet regions to 9.3 C/km in dry regions, interpolated by precipitation), ocean current warmth (16-pass diffusion onto coastal land, ±20°C effect with 0.95 continentality gate), and precipitation/cloud cover moderation. Normalized to a fixed -45 to +45 C range. Computed for both seasons.
  16. Rendering builds a Voronoi cell mesh with per-vertex colors and terrain displacement

Key Algorithms

  • Seeded PRNG — Park-Miller LCG for deterministic generation
  • 3D Simplex noise — with fBm and ridged fBm variants for terrain detail
  • Harmonic-mean distance blending — (1/a - 1/b) / (1/a + 1/b + 1/c) for smooth elevation transitions
  • Domain warping — noise-driven coordinate offsets for organic coastlines
  • Density-based subduction — tanh mapping of density differences with undulation noise
  • BFS distance fields — randomized frontier expansion from boundary seeds, used for elevation, coast distance, rift width, ridge profiles, and back-arc basins
  • Gaussian dome uplift — hotspot volcanism modeled as dual-component Gaussians (thermal swell + volcanic peak) with domain-warped shape distortion, anisotropic drift elongation, summit calderas, radial rift ridges, and age-dependent texture blending

Project Structure

index.html              Main page — HTML markup + import map + structured data
import.html             Import page — heightmap upload + climate visualization
styles.css              All CSS (shared by both pages)
robots.txt              Search engine crawler directives
sitemap.xml             Sitemap for search engine indexing
site.webmanifest        Web app manifest (metadata + theming)
llms.txt                AI/LLM-readable site description (AISEO)
humans.txt              Project credits
CNAME                   Custom domain config (orogen.studio)
404.html                Custom 404 page
preview.png             Social preview image (og:image / Twitter card)
js/
  main.js               Generator entry point — UI wiring, animation loop
  import-main.js        Import page entry point — file upload, import dispatch, painted-map legend table
  painted.js            Painted-map import — legend parsing, pixel classification, region voting, stroke dissolution, coast roughening, uplift field, Braun-Willett stream-power solve
  painted-layers.js     Colours and legends for the painted layers (class, uplift, erodibility, drainage, slope, basins, overlay)
  painted-report.js     What a legend's numbers make before a solve: the divide and typical hillslope angles per class
  painted-overlay.js    The annotation layer — mark legend parsing, pixel classification, region voting, coast_jitter per region
  painted-overlay-view.js  The overlay sheet as a texture on the globe, the map and the exports
  state.js              Shared mutable application state
  generate.js           Worker dispatcher — posts jobs, handles results
  planet-worker.js      Web Worker — runs geology pipeline off main thread
  planet-code.js        Planet code encode/decode (seed + sliders → base36)
  rng.js                Seeded PRNG (Park-Miller LCG)
  simplex-noise.js      3D Simplex noise with fBm and ridged fBm
  color-map.js          Elevation → RGB colour mapping + satellite biome colors
  sphere-mesh.js        Fibonacci sphere, Delaunay, SphereMesh dual-mesh
  plates.js             Tectonic plate generation (farthest-point seeding, round-robin flood fill, compactness constraints)
  coarse-plates.js      Resolution-independent plate pipeline — coarse reference grid, projection, boundary smoothing
  super-plates.js       Groups same-type plates into ~20 super plates for broad orogenic belts
  ocean-land.js         Ocean/land assignment with continent seeding
  elevation.js          Collisions, stress propagation, distance fields, elevation
  terrain-post.js       Domain warping, bilateral smoothing, glacial/hydraulic/thermal erosion, ridge sharpening, soil creep
  climate-util.js       Shared climate utilities — smoothing, ITCZ lookup, percentile selection
  wind.js               Seasonal wind simulation — pressure fields, ITCZ tracking, Coriolis wind
  ocean.js              Ocean surface currents — rule-based wind-belt gyres, coast BFS, circumpolar detection
  precipitation.js      Precipitation simulation — moisture advection, ITCZ/frontal/orographic effects, blended with heuristic
  heuristic-precip.js   Heuristic zonal precipitation model — smooth latitude/continentality/orographic patterns
  temperature.js        Temperature simulation — ITCZ thermal equator, lapse rate, continentality, ocean currents
  scene.js              Three.js scene, cameras, controls, lights
  planet-mesh.js        Voronoi mesh, map projection, hover highlight
  edit-mode.js          Ctrl-click plate multi-select + hover info
  detail-scale.js       Non-linear (power-curve) detail slider mapping
  png-write.js          8-bit and 16-bit greyscale PNG encoders (a canvas gives neither)
  unreal-render.js      Renders a lon/lat window of the planet into a float raster of kilometres
  unreal-export.js      Cuts that raster into Unreal landscape tiles, derives the weightmaps, writes Region.json
  unreal-ui.js          The Unreal Landscape panel, built in JS so both pages share one copy

Dependencies

Loaded via CDN import maps (no installation needed):

License

This project is licensed under the GNU General Public License v3.0 — see LICENSE for details.

Acknowledgments

Inspired by Red Blob Games' planet generation — Fibonacci sphere meshing, dual-mesh traversal, and distance-field elevation approach.

Additional inspiration and reference from: