"_comment":"What each painted colour in Map3.jpg means. See README.md next to this file. Rates are rock uplift in mm/yr, and the number to think in is not the rate but the hillslope angle it fixes: at an 8 m cell and K 5e-5, tan(angle) = 2.5 x the rate, so 0.08 is 11 degrees on every divide and 0.25 is 32. Do not read internal/stats' \"plain below 0.1 mm/yr\" as terrain - it is a reporting bucket, and 0.1 mm/yr is hill country. `terrain plan` prints the angle and what it reads as for every class here.",
{"_comment_ice":"snow is display and material only - it changes no height and no pass reads it, it just stops the polar caps rendering as meadow. What makes the cap read as ice in the terrain is the detail block: an ice sheet has meltwater channels but not a dendritic bedrock gully network, so it gets almost no droplets. Uplift is low and the cap is still solved like any other land; a proper ice dome would be a stamp after the solve, the way the crater is.",
{"_comment_plain":"coastal_plain_km puts the range inland. For n=1 the uplift rate alone fixes the hillslope angle, so a uniformly painted island sits at the angle of repose right down to the water; this ramps the rate up from coastal_floor_mm_yr over the first few km so there is a plain in front of the range. It is the opt-in, explicit version of the taper D-52 removed - that one was hidden and went to zero at the waterline.",
"_comment_massif":"The massif is what makes this a landscape rather than a landmass. 0.08 mm/yr is an 11 degree hillslope, and before this block it was 11 degrees on every divide from the waterline to the summit, so the whole continent came out as continuous hill country with no flat ground anywhere on it. Now 0.08 is the rate a *hill mass* reaches and 0.012 - 1.7 degrees, a plain - is the ground between them, with a sixth of it standing up. That is the North European Plain with the Harz and the Ardennes in it, which is what a lowland is.",
{"_comment_faults":"A fault is a difference in uplift rate across a line - steep on one side, gentle on the other - which erosion then carves into a scarp. It is what puts an escarpment and a straight fifteen-kilometre valley inside a range, and neither is something the painting can draw. throw_m is the whole step across the fault over the run - how much higher the upthrown side would stand than the downthrown one if nothing eroded either, which since D-62 is the step and not a full throw on each flank, so a number written before that asks for half what it used to get. A fault is a range front several kilometres wide, not a line: the rate crosses over about a kilometre and the upthrown flank reaches six, which is what lets erosion cut valleys into it instead of printing the profile on the surface. Where several of them overlap - which at that width is most of a faulted class, and they are sub-parallel by design - the total saturates at 1.6 times the strongest single fault rather than adding up (D-63), so raising per_1000km2 past the overlap point buys texture and not height; per_1000km2 is a density over *this class*, which on this template is 549 km2 of highland, so 25 is about fourteen traces before the long ones step into segments. Drop the block to have none, which is what a plain should have.",
"_comment_clamped":"0.90 mm/yr is 66 degrees at a divide against a 35 degree angle of repose, so the repose clamp shapes this class rather than erosion does and the ground bakes out as flat polygonal facets. The ceiling is U = tan(talus)*K*cell = 0.280 mm/yr at an 8 m cell; `terrain plan` prints the angle for every class. Dropping to about 0.25 gives erosion-shaped mountains at roughly 350 m on a 20 km island instead of 695 m of talus - relief and steepness are the same knob at a fixed cell, so that is the trade.",
"_comment_massif":"A range is a belt, not a dome. Painted solid, this class used to raise every cell of an island to 32 degrees, which is why the first planet had two islands that were nothing but mountain. 0.25 is now the rate the belt reaches and 0.045 - 6.4 degrees, rolling - is its foreland, with three tenths of it standing up. It cuts the same fabric as the lowland beside it, so the hills in the neighbouring lowland are that orogen's outliers rather than an unrelated noise.",
{"_comment_desert":"A desert is not a low uplift rate - a wet lowland has one of those too - so at the geology grid it is only k_mult, which being below 1 means less water doing less work and therefore steeper, more angular ground held further from being worn down. What makes it read as desert is the detail block, at two metres: a fifth of the running water, so the dendritic gully network thins out to isolated wadis; twice the strata contrast, so mesas and ledges keep their edges because nothing is rounding them off; and several times the noise amplitude, which on flat ground is dune.",
"_comment_massif":"k_mult 0.5 doubles the angle a rate makes - tan(angle) = 2.5 x rate / k_mult - so 0.10 here is 27 degrees, not 14, and painted solid it made a plateau of mountain. 0.10 is the rate a mesa block reaches and 0.015 - 4.3 degrees - is the sand sea between them.",
{"_comment_crater":"An impact is an event, not a rate, so it is stamped onto the finished terrain after the solve rather than painted as uplift - a closed basin built out of negative uplift would be filled in by the priority-flood within a hundred steps. The shape comes from the painted blob: distance in from its own shoreline, normalised by its widest point, so rim_at and wall_at describe every crater whatever size it was drawn. The uplift rate here is only what the solve does to the flanks before the stamp lands, so it is low.",
{"_comment":"White is painted twice: the polar caps and the outline stroke around every island. The stroke owns the colour, because it is the one that has to be recognised wherever it appears; a white region touching the top or bottom row of the map is a cap and becomes ice instead. Everything else white dissolves into whichever real class is nearest.",
"_comment":"A painted tectonic layer: one colour per plate, and how that plate is moving. heading_deg is a compass bearing over the map - 0 points at the top of the image, 90 to the right, 180 to the bottom. speed_cm_yr is drift; what happens at a margin is the difference between the two plates either side of it, so two plates drifting the same way are a boundary doing nothing. spin_deg_myr turns a plate about its own centre, positive clockwise, and it is worth setting on at least one: without it every margin is the same all the way along, and with it one end collides while the other slides. Paint the plates, not the mountains - where two of these meet, the collision, the belt and its faults are worked out from the motions. Repaint the blobs freely; only the colours have to keep matching this file.",
"_comment":"What each painted colour in Map3.jpg means. See README.md next to this file. Rates are rock uplift in mm/yr, and the number to think in is not the rate but the hillslope angle it fixes: at an 8 m cell and K 5e-5, tan(angle) = 2.5 x the rate, so 0.08 is 11 degrees on every divide and 0.25 is 32. Do not read internal/stats' \"plain below 0.1 mm/yr\" as terrain - it is a reporting bucket, and 0.1 mm/yr is hill country. `terrain plan` prints the angle and what it reads as for every class here.",
{"_comment_ice":"snow is display and material only - it changes no height and no pass reads it, it just stops the polar caps rendering as meadow. What makes the cap read as ice in the terrain is the detail block: an ice sheet has meltwater channels but not a dendritic bedrock gully network, so it gets almost no droplets. Uplift is low and the cap is still solved like any other land; a proper ice dome would be a stamp after the solve, the way the crater is.",
{"_comment_plain":"coastal_plain_km puts the range inland. For n=1 the uplift rate alone fixes the hillslope angle, so a uniformly painted island sits at the angle of repose right down to the water; this ramps the rate up from coastal_floor_mm_yr over the first few km so there is a plain in front of the range. It is the opt-in, explicit version of the taper D-52 removed - that one was hidden and went to zero at the waterline.",
"_comment_massif":"The massif is what makes this a landscape rather than a landmass. 0.08 mm/yr is an 11 degree hillslope, and before this block it was 11 degrees on every divide from the waterline to the summit, so the whole continent came out as continuous hill country with no flat ground anywhere on it. Now 0.08 is the rate a *hill mass* reaches and 0.012 - 1.7 degrees, a plain - is the ground between them, with a sixth of it standing up. That is the North European Plain with the Harz and the Ardennes in it, which is what a lowland is.",
{"_comment_faults":"A fault is a difference in uplift rate across a line - steep on one side, gentle on the other - which erosion then carves into a scarp. It is what puts an escarpment and a straight fifteen-kilometre valley inside a range, and neither is something the painting can draw. throw_m is the total displacement over the whole run, so it is the height of the scarp the fault would build if nothing eroded it; per_1000km2 is a density over *this class*, which on this template is 549 km2 of highland, so 25 is about fourteen traces before the long ones step into segments. Drop the block to have none, which is what a plain should have.",
"_comment_clamped":"0.90 mm/yr is 66 degrees at a divide against a 35 degree angle of repose, so the repose clamp shapes this class rather than erosion does and the ground bakes out as flat polygonal facets. The ceiling is U = tan(talus)*K*cell = 0.280 mm/yr at an 8 m cell; `terrain plan` prints the angle for every class. Dropping to about 0.25 gives erosion-shaped mountains at roughly 350 m on a 20 km island instead of 695 m of talus - relief and steepness are the same knob at a fixed cell, so that is the trade.",
"_comment_massif":"A range is a belt, not a dome. Painted solid, this class used to raise every cell of an island to 32 degrees, which is why the first planet had two islands that were nothing but mountain. 0.25 is now the rate the belt reaches and 0.045 - 6.4 degrees, rolling - is its foreland, with three tenths of it standing up. It cuts the same fabric as the lowland beside it, so the hills in the neighbouring lowland are that orogen's outliers rather than an unrelated noise.",
{"_comment_desert":"A desert is not a low uplift rate - a wet lowland has one of those too - so at the geology grid it is only k_mult, which being below 1 means less water doing less work and therefore steeper, more angular ground held further from being worn down. What makes it read as desert is the detail block, at two metres: a fifth of the running water, so the dendritic gully network thins out to isolated wadis; twice the strata contrast, so mesas and ledges keep their edges because nothing is rounding them off; and several times the noise amplitude, which on flat ground is dune.",
"_comment_massif":"k_mult 0.5 doubles the angle a rate makes - tan(angle) = 2.5 x rate / k_mult - so 0.10 here is 27 degrees, not 14, and painted solid it made a plateau of mountain. 0.10 is the rate a mesa block reaches and 0.015 - 4.3 degrees - is the sand sea between them.",
{"_comment_crater":"An impact is an event, not a rate, so it is stamped onto the finished terrain after the solve rather than painted as uplift - a closed basin built out of negative uplift would be filled in by the priority-flood within a hundred steps. The shape comes from the painted blob: distance in from its own shoreline, normalised by its widest point, so rim_at and wall_at describe every crater whatever size it was drawn. The uplift rate here is only what the solve does to the flanks before the stamp lands, so it is low.",
{"_comment":"White is painted twice: the polar caps and the outline stroke around every island. The stroke owns the colour, because it is the one that has to be recognised wherever it appears; a white region touching the top or bottom row of the map is a cap and becomes ice instead. Everything else white dissolves into whichever real class is nearest.",
"_comment":"What each painted colour in Map5 means. See README.md next to this file. Rates are rock uplift in mm/yr, and the number to think in is not the rate but the hillslope angle it fixes: at an 8 m cell and K 5e-5, tan(angle) = 2.5 x rate / k_mult, so 0.08 is 11 degrees on every divide and 0.25 is 32. Read the *typical* column `terrain plan` prints, not the divide one - a divide is the steepest ground a rate can make and almost none of a map is divide, so 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.",
"_comment_colours":"Every rgb below is the *measured modal colour* of Map5.jpg, not a guess at it: the painting was sampled, its colours clustered, and the mode of each cluster taken. Map5.png beside it is the same painting with every pixel snapped to exactly these seven colours, which is what the classifier would do anyway and which removes the JPEG halo along every painted edge for good. The manifest points at the PNG; the JPEG is kept as the original.",
"image":"Map5.png",
"warn_distance":60,
"classes":[
{"_comment_ocean":"The open sea. depth_m is the painted sea floor, which internal/coast reads per cell as the abyss it builds a shelf and a continental slope down to; the shelf break itself is pipeline.coast.break_m and defaults to 130 m on a planet (D-64), so it is never deeper than the water it is a break in.",
{"_comment_deep":"The second, darker blue the author painted - the big offshore lobe on the right, the band through the north-west islands, and the channels between the island groups. Taken as deeper water rather than as a shallow shelf, because it is darker than the open ocean and not lighter. If a shelf was meant instead, set depth_m to about 120 and rename it; nothing else in the legend has to change. It is 9% of the world, so it will show.",
{"_comment_ice":"The polar caps, painted white at the top and bottom of the map and nowhere else - so unlike Map3's white this is a class in its own right rather than an outline stroke rescued at the poles, and it needs no stroke/edge_class pair. snow is display and material only: it changes no height and no pass reads it, it just stops the caps rendering as meadow. What makes a cap read as ice in the terrain is the detail block - an ice sheet has meltwater channels but not a dendritic bedrock gully network, so it gets almost no droplets.",
{"_comment_plain":"coastal_plain_km puts the range inland. For n=1 the uplift rate alone fixes the hillslope angle, so a uniformly painted island sits at the same angle right down to the water; this ramps the rate up from coastal_floor_mm_yr over the first kilometre so there is a plain in front of the ground behind it.",
"_comment_massif":"The massif block is what makes this a landscape rather than a landmass. 0.08 mm/yr is an 11 degree divide, and without this block it would be 11 degrees from the waterline to the summit, so the whole continent would come out as continuous hill country with no flat ground anywhere on it. 0.08 is the rate a *hill mass* reaches and 0.012 - 1.7 degrees at a divide, a plain - is the ground between them, with a sixth of it standing up. That is the North European Plain with the Harz in it, which is what a lowland is. The threshold is a quantile of the planet, never of this class, so the hills here and the ones in the highland next door are parts of one structure.",
{"_comment_faults":"A fault is a difference in uplift rate across a line - steep one side, gentle the other - which erosion then carves into a scarp. It is what puts an escarpment and a straight fifteen-kilometre valley inside a range, and neither is a shape a brush can draw. throw_m is the *step across* the fault over the run (D-62), not a full throw on each flank. A fault is a range front several kilometres wide rather than a line: the rate crosses over about a kilometre and the upthrown flank reaches six, which is what lets erosion cut valleys into it instead of printing the profile on the surface. Where several overlap - which at that width is most of a faulted class - the total saturates at 1.6x the strongest single fault rather than adding up (D-63), so raising per_1000km2 past the overlap point buys texture and not height. per_1000km2 is a density over *this class*: Map5 has about 554 km2 of highland, so 25 is roughly fourteen traces before the long ones step into segments.",
"_comment_massif":"A range is a belt, not a dome. Painted solid, 0.25 would raise every cell of these continents to a 32 degree divide, which is how a planet ends up with islands that are nothing but mountain. 0.25 is the rate the belt reaches and 0.045 - 6.4 degrees, rolling - is its foreland, with three tenths standing up.",
"_comment_ceiling":"The repose clamp takes over above U = tan(35 deg) x K x cell = 0.280 mm/yr at an 8 m cell, and past it the ground bakes out as flat polygonal facets rather than as erosion-shaped mountains. 0.25 sits just under it deliberately. Relief and steepness are the same knob at a fixed cell, so going higher buys facets, not mountains.",
{"_comment_desert":"A desert is not a low uplift rate - a wet lowland has one of those too - so at the geology grid it is only k_mult, which being below 1 means less water doing less work and therefore steeper, more angular ground held further from being worn down. What makes it read as desert is the detail block at two metres: a fifth of the running water, so the gully network thins to isolated wadis; twice the strata contrast, so mesas and ledges keep their edges; and several times the noise amplitude, which on flat ground is dune.",
"_comment_massif":"k_mult 0.5 doubles the angle a rate makes - tan(angle) = 2.5 x rate / k_mult - so 0.10 here is a 27 degree divide, not 14, and painted solid it would be a plateau of mountain. 0.10 is the rate a mesa block reaches and 0.015 - 4.3 degrees - is the sand sea between them.",
{"_comment_crater":"The two grey blobs on the seam, at the far left and far right of the painting - one crater, drawn across the meridian, which the generator treats as a single feature because X wraps. An impact is an event and not a rate, so it is stamped onto the finished terrain after the solve rather than painted as uplift: a closed basin built out of negative uplift would be filled in by the priority-flood within a hundred steps. The shape comes from the painted blob - distance in from its own shoreline, normalised by its widest point - so rim_at and wall_at describe a crater of any size. The uplift rate here is only what the solve does to the flanks before the stamp lands, so it is low.",
"_comment":"The annotation layer for Map5: a second painting, the same size as the template and registered to it, saying what is *placed on* the finished world rather than what the rock is doing. Paint it in `terrain studio` under the `overlay` tab (or press o), or let `terrain overlay` propose a first draft from a bake. See README.md next to this file, and Docs/Terrain.md.",
"_comment_blank":"Most of this sheet is nothing, and nothing is alpha rather than a colour: an unpainted pixel is transparent, so no colour has to be spent on the background 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 below is dropped and counted - `terrain plan` says how many, which is the only way a colour the legend forgot ever shows.",
"_comment_image":"There is no image yet, and that is the normal way to start: the legend says what the marks mean and the sheet stays empty until the first save from the studio, or until `terrain overlay` writes one. The manifest's planet.overlay is what points at it once it exists.",
"image":"Map5.overlay.png",
"match_distance":40,
"min_area_px":24,
"marks":[
{"_comment":"The one thing on this layer the generator reads. The waterline roughening exists because a drawn shore is a smooth curve and a real coast is fractal - which is true of a coast nobody thought about and false of one traced off a map on purpose. Paint over the shore you drew by hand and it stays exactly where you put it while the rest of the world is still roughened. Either side of the waterline is enough; a brush stroke along it covers both.",
{"_comment":"The same knob pointed the other way. A fjord or a ria coast wants more than the planet's own amplitude, not less; at 2.5 the bays are two and a half times as deep and just as wide, which is what makes them fjords rather than scallops.",
"_comment_generate":"This mark can also be generated - add \"generate\": { \"kind\": \"coast\", \"coast_km\": 2.5 } and `terrain overlay` will band every shore with it. It is left off deliberately: coast_jitter is the one overlay property a pass reads, so generating this mark changes the next bake everywhere, and that is a decision to take on purpose rather than to inherit from a default.",
"note":"Chew this shore harder than the rest of the world."},
{"_comment_inert":"Everything below is inert. No pass reads it, no height changes, and two bakes with and without it are the same terrain to the bit. What they do is travel: each one comes out as an index in the per-tile mask beside every heightmap, and as a feature in world metres in overlay.json - a centre, an area, an extent for an area; an ordered polyline for a path. That is what the engine places things from.",
"_comment_generate":"The generate block lets `terrain overlay` propose this mark from a baked world. not_classes keeps it off ground painted as ice or desert, which matters more than it sounds: height and slope cannot tell an ice cap from a meadow, and without it woodland grows across both poles. The treeline is derived from the land's own heights, because a number in metres means nothing until the world is baked.",
"name":"forest","rgb":[0,128,0],
"note":"Where trees are scattered. The mask is the volume bound.",
{"_comment_settlements":"Three tiers, listed largest first, which is the order the generator places them in. They share one spacing rule - the largest min_spacing_km any of them sets - so a village never lands inside a city. Sites are scored on the three things the terrain actually knows: drainage, flat ground and distance to the sea. Everything else about where a town is belongs to you, which is why these are proposals in a sheet you edit.",
{"_comment_path":"A path is a stroke whose width is not the point: it is thinned to its centreline and comes out as an ordered polyline, because the thing built from it on the other side is a spline. width_m is what the road really is on the ground and is carried rather than used. One stroke is one path - a fork reports its two longest arms as one line and drops the third - so paint each run separately and check the piece count in `terrain plan`.",
"_comment_generate":"Generated roads are a minimum spanning tree over the settlements along least-cost paths, not every pair, so there is exactly enough road to reach everywhere. Water is impassable, so each landmass gets its own network and a bridge stays a deliberate act.",
"_comment":"A painted tectonic layer: one colour per plate, and how that plate is moving. heading_deg is a compass bearing over the map - 0 points at the top of the image, 90 to the right, 180 to the bottom. speed_cm_yr is drift; what happens at a margin is the difference between the two plates either side of it, so two plates drifting the same way are a boundary doing nothing. spin_deg_myr turns a plate about its own centre, positive clockwise, and it is worth setting on at least one: without it every margin is the same all the way along, and with it one end collides while the other slides. Paint the plates, not the mountains - where two of these meet, the collision, the belt and its faults are worked out from the motions. Repaint the blobs freely; only the colours have to keep matching this file.",
# the same painting as a different world: massifs, rock, faults and coastline detail all re-rolled
Tools/Terrain/bin/terrain.exe plan --seed 9342
# the upland fabric at another size, without editing the manifest
Tools/Terrain/bin/terrain.exe plan --massif-km 5
# the painting tool: brushes that carry the legend's numbers, and Plan as a button
Tools/Terrain/bin/terrain.exe studio # http://127.0.0.1:8099
```
## The studio
`terrain studio` is the tool to reach for first. It exists because the two halves of a painted world used to
live in different programs: the shapes in an image editor that knows nothing about uplift rates, the meanings
in this legend, which cannot show you where they land.
The brushes **are** the classes. Picking `highland` is picking 0.25 mm/yr, and the panel tells you that is
11.7° of ground and reads as hill country while you are painting it — with the 32° divide angle beside it in
grey, because that is where the number comes from and what the repose clamp eventually binds against. So the
table in the section above stops being something to look up. Change a number and every swatch re-reads
instantly; nothing is written until you press a Save button.
| | |
| --- | --- |
| paint | left-drag. `[` and `]` change the brush size |
| pan | shift-drag, middle-drag or right-drag |
| zoom | wheel |
| Plan | runs the plan **against what is on screen**, not what is on disk, and prints the class table, the seam check and the region cuts |
| the map buttons | draw `class`, `uplift`, `regions`, `erodibility` or `overlay` over the canvas, each with a key under it. Press again, or Escape, to go back to painting |
| layers | the two tabs at the top, or press **o**. `classes` is the geology; `overlay` is the annotation layer, where the brushes are its marks and the last one is an eraser. See **The overlay** |
**Plan is seven seconds the first time and about a third of a second after that**, as long as all you changed
was a number. That is the tuning loop, and it is worth knowing why it works: the classification, the despeckle,
the coast mask, the projection and the region cuts depend on the painting and on the class *colours* only — an
uplift rate decides how the maps are coloured in and nothing else — so a plan that differs from the last one
only in the legend's numbers reuses the whole of it. Touch the painting, or any of the coast or margin
settings, and the next plan is a full one again. The report says which you got.
Rendering the maps smaller does **not** make it quicker, which is worth stating because it is the obvious
guess. Measured on the 100 km template, prepare is flat at about 6.5 s from a 400 px map to a 2400 px one, and
it breaks down as classify 0.09 s, dissolve strokes 0.93, despeckle 1.52, the coast mask 1.62, project 0.05
and `region.Build`**2.68** — and the last one works on the 76-million-cell planet grid, which the size of the
painting and the size of the maps both have nothing to do with.
Three things about it are deliberate:
- **The brush is hard-edged and writes exact colours.** No antialiasing and no soft edges, because a blended
pixel is not a colour between two classes — it is a pixel that classifies as whichever *third* class happens
to sit near the midpoint. See the note on the coastline below; that defect is real and this is where not to
create it.
- **The canvas wraps.** Paint off the left edge and it arrives at the right, because the map is a cylinder.
The first template disagrees with itself on 9.4 % of its rows and this is how that gets fixed.
- **There are two sheets, and only one of them is geology.** The class painting is what the solve reads; the
overlay rides on top of it and, `coast_jitter` aside, changes no height anywhere. It is dimmed while the
brush is on the classes so that a road can never be mistaken for something the solve will act on.
- **It never overwrites anything, and the base map least of all.** Saves go to the next free `Map3_001.png`,
`Map3_002.png`, ... beside the template, and the manifest is repointed at the new one — the same convention
as `Bake_001`, for the same reason: the interesting question is almost always "what did that change", and
answering it needs both. Rolling back is pointing `planet.template` at an earlier one. A painting is
something you made by hand and there is no undo for it outside the studio, and writing back over a *JPEG*
would additionally re-create the blended boundary pixels the despeckle pass exists to remove, compounding
them on every save.
Legend and manifest saves **patch the text** rather than rewriting the file, so the commentary in both
survives and a change still shows up as a small diff.
### Baking from the studio
The **Bake** panel runs the real solve on the painting as it is on screen, and you can watch it. Because the
geology is decomposed per landmass, each one comes out whole — so the preview redraws every time a region
lands and the world fills in a continent at a time. The first one out tells you whether the numbers are right;
the other seventeen do not have to finish for you to know.
| | |
| --- | --- |
| regions | blank bakes everything (~2 h on the 100 km template). A few ids — `11,13` — is the quick version, and the ids are the ones in the regions key |
| steps | 0 is the manifest's full count. A few hundred is under-eroded but enough to see the shape |
| jobs | how many landmasses solve at once. The wall time is set by the largest single region, which runs at about one core, so this helps least on exactly the template that needs it most |
| Cancel | stops it. Regions in flight stop at the end of their current step, so the wait is one step of the biggest one |
A finished bake goes to the next `Bake_NNN`. A **cancelled** one goes to `Partial_NNN` instead — the regions
that finished are complete and worth keeping, everything else in it is still at sea level, and the separate
name is so that nothing downstream (`tiles --bake` takes the newest `Bake_NNN`) can mistake one for the other.
## The picture
Flat cylindrical: **X wraps** — the left and right edges are the same meridian, so a landmass may straddle
them and comes out whole — and **Y does not**: the top and bottom rows are the poles. Any aspect works; the
paint is never stretched to 2:1.
**The painting has to wrap too, and this is the thing to check first.** The left and right edges are the same
meridian, so anything that does not continue from one to the other is a real discontinuity down one line of
the world — and it is the one defect you cannot see by looking at the picture, because the two edges are as
far apart on screen as they can be. `terrain plan` measures it:
```
wrap the left and right edges are the same meridian: they disagree on 355 of 3761 rows (9.4%),
261 of those land against water, and 48 px in the outermost columns match no class.
THAT IS A VISIBLE SEAM. The generator wraps; the painting has to as well.
```
That is `Map3.jpg` as it stands. The crater island crosses the seam perfectly — sampled at the geology grid,
the heights run continuously from the last column into the first — but the islets near the left edge were
drawn touching `x = 0` with nothing to meet them at `x = W-1`, so the world has a 400 m cliff down the seam
wherever that happens. Painting round the edge, or nudging those islets inwards, fixes it.
PNG is better than JPEG, and the seam is where it shows. JPEG bleeds colour across every class boundary, and
two legend colours closer together than the bleed will swap pixels where they meet — survivable in the middle
of the map, but on the outermost columns a lossy encoder leaves a halo, and a halo on the seam is a stripe of
the wrong class down the one line of the world that cannot hide it. `Map3.jpg`'s first two columns are
lighter than the ocean behind them, which the classifier reads as shelf: a 400 m ledge two pixels wide,
running the height of the map.
The paint does not have to match the grid. `Map3.jpg` is 7738 px across a 100 km world, so a pixel is 12.9 m
against an 8 m geology cell: the painting is slightly *coarser* than the simulation, which is the right way
round. The rule from `Docs/Terrain-Next.md` §3.2 is that the painted map owns the wavelengths above its pixel
size and noise owns those below.
## Paint the uplift, never the height
This is the one thing to understand before painting anything. A class does not say how high the ground is; it
says **how fast the rock is rising** and **how easily it erodes**. The simulation then produces the terrain.
Painting a heightmap instead does not work and the reason is worth knowing: a stream-power solve handed a
painted surface erodes it into something else within a few hundred steps, and what comes out has no
relationship to what was drawn — while the drainage network, which is the entire reason this generator exists,
is thrown away. Paint intent; get rivers.
Rivers cannot be painted either. A river is an *output* of the drainage solve. What does work is biasing:
raise `k_mult` along a line so the water finds the soft rock, and the solve chooses to put a river there for
its own reasons — and the result is still a coherent network.
## The legend
One JSON file beside the image. Keys beginning with an underscore are comments; any other unknown key is an
error, because a misspelt key silently ignored is a class quietly running on the default.
```jsonc
{
"image":"Map3.jpg",
"warn_distance":60,// how far in RGB a pixel may sit from every class before the run says so
| `name` | what it is called in the reports and the maps |
| `rgb` | the painted colour. Every pixel takes the nearest one, so there is no unclassified pixel |
| `sea` | water. The solve holds every sea cell at base level for its whole run |
| `depth_m` | sea only: how deep the open water is, in metres below sea level, positive |
| `uplift_mm_yr` | land only: rock uplift, and **the hillslope angle**. See below: `tan(divide) = 2.5 × rate ÷ k_mult` at an 8 m cell, and the *ground* is a third of that in tangent — so 0.08 is 3.8° of median hillslope with 11.3° at its divides, and 0.25 is 11.7° with 32° |
| `k_mult` | land only: the multiplier on stream-power erodibility. Soft rock above 1, hard below |
| `stroke` | decoration rather than data — dissolved into whichever real class is nearest |
| `edge_class` | a stroke touching the top or bottom row of the map is not a stroke; it becomes this class |
| `derived` | never painted: no colour matching, exists only as something else's `edge_class`. Its `rgb`, if any, is for the diagnostic maps |
| `coastal_plain_km` | land only: how far inland the rate ramps up to its full value, so the range sits behind a plain |
| `coastal_floor_mm_yr` | land only: the rate at the waterline. Defaults to 0.02, never raised above the class rate |
| `massif` | land only: `{floor_mm_yr, fraction}` — the class breaks into plain and upland instead of holding one rate everywhere. **Read the next section before writing a legend without one** |
| `faults` | land only: `{per_1000km2, throw_m, length_km}` — traces placed in this class's ground. Absent means none, which is right for a plain. See **One painting, many worlds** |
| `lithology_mix` | land only: 0 to 1, how much of the planet's rock field shows through here. Default 1; 0 is uniform rock, which is what an ice cap or a crater floor should be |
| `crater` | land only: `{rim_m, floor_m, rim_at, wall_at}`, stamped on the finished terrain |
| `snow` | land only: permanently under ice. **Display and material only** — no height moves, no pass reads it, and it is drawn with the palette's `ice` colour. What makes a polar cap *terrain* is its uplift rate and its `detail` block like any other class |
| `detail` | land only: `{droplets_per_cell, strata_contrast, amplitude_m}`, what the detail passes do differently on this ground |
### A rate is an angle, and one rate is one landscape
This is the second thing to understand, and it is the one that caught the first painted planet out.
For `n = 1` the steady-state slope is `S = U / (K·A^m)`, and with `critical_area_m2` at 0 that law reaches down
to a single cell — so at a drainage divide `A` is one cell and the uplift rate, on its own, fixes the hillslope
angle. At the 8 m geology cell and `K` 5e-5 it works out at:
```
tan(angle) = 2.5 × uplift_mm_yr ÷ k_mult
```
**But a divide is the steepest place in a catchment, and almost none of a map is divide.**`A` is smallest at
the top of a hillslope and grows all the way down, so the divide angle is the *ceiling* on a class and not its
landscape. Measured on a 600² grid of 8 m cells at 1000 steps with the manifest's own constants, the median
slope comes out at a third of it in tangent, and the ratio barely moves over a factor of twenty in rate
(0.34, 0.33, 0.33, 0.32). So there are two columns, and **the one to steer by is the second**:
"_comment":"How a preview is drawn. Nothing here changes a height - two bakes of the same world under two palettes are the same terrain. Point a planet manifest at this file with \"palette\": \"<path relative to the manifest>\"; leave it out and these numbers are used anyway. Keys beginning with an underscore are comments.",
"_comment_land_stops":"The hypsometric ramp: sea level at t 0 to the top of the land at t 1. The top is a percentile rather than the maximum, so one high summit cannot push a whole continent into the bottom of the ramp.",
"land_stops":[
{"t":0,"rgb":[72,106,68]},
{"t":0.08,"rgb":[104,132,74]},
{"t":0.2,"rgb":[142,152,88]},
{"t":0.38,"rgb":[164,148,104]},
{"t":0.58,"rgb":[150,128,106]},
{"t":0.75,"rgb":[138,130,128]},
{"t":0.88,"rgb":[176,174,174]},
{"t":1,"rgb":[246,246,250]}
],
"sea_shallow":[56,104,136],
"sea_deep":[18,40,72],
"river":[70,132,180],
"_comment_ice":"Drawn wherever a class is marked snow, whatever height the ground stands at. Not pure white: white has nowhere left to go under the hillshade, so an ice sheet comes out as a flat cut-out with no shape in it at all.",
"ice":[232,238,245],
"_comment_top":"Where the top of the hypsometric ramp sits. The percentile is relative to the world being drawn, which is the only way a low continent is legible at all and is also a picture that lies about scale - measured on this planet's central landmass, a 47 m plain whose median slope is 0.6 degrees comes out with the same bare rock and white caps a 2800 m range would, because 40 m is the top of its own ramp. Set land_top_m to a height in metres for an absolute ramp instead; 0 keeps the percentile, and either way the run summary says which ceiling the preview was drawn against.",
"land_top_percentile":99.5,
"land_top_m":0,
"_comment_light":"Azimuth is degrees clockwise from north and altitude degrees above the horizon; north-west at 45 is what every DEM hillshade uses. Ambient is how lit the shaded side is - at zero a shadow is a hole - and gain how much the lit side brightens.",
oid sha256:3d3b0f70b6932b36974a8423bf6007e5e48020a46c6a2e9cc92ec7bf578f8b26
size 2433944
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.