Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Elevation world data

Settlement elevation comes from the Copernicus DEM GLO-30 digital surface model. The current source is modern rather than a historical reconstruction; terrain height is sufficiently stable for the game's plausibility-oriented 1544 world generation.

The *_DEM.tif tiles belong in the Git-ignored target/world-data-sources/raw/elevation/ directory. just plan-glo30 prints the deterministic request and redacted CDSE_TOKEN_FILE preflight, init-glo30 refuses until the complete tile inventory is pinned, and verify-glo30 checks a strict local source-inventory.json. This release-blocked workflow never logs or stores a token.

sources::elevation uses the pure-Rust tiff crate and does not require GDAL. Its strict tile, georeference, nodata, and nearest-valid-pixel reader is shared with route-terrain enrichment. Route sampling uses a deterministic 64 MiB LRU decoded-tile cache, while the settlement batch remains grouped one tile at a time. It groups settlements by one-degree GLO-30 tile, decodes only the 159 tiles used by the current Viabundus settlement set, and releases each raster before reading the next. A settlement receives a required ElevationMeters value; ElevationBand is derived from it rather than redundantly stored, so the two can never contradict each other. There is no unknown variant. Invalid or void source pixels are replaced by the nearest plausible pixel within eight raster cells of the same source tile, then by sea level if that local window is entirely void. The build report counts these fallbacks. The verified 1544 build sampled all 6,041 settlements without using a fallback.

The settlement Map presentation classifies a native cell as hilly when its elevation difference to any of its eight neighbours implies a slope steeper than 15 degrees using the latitude-correct source-cell distance. Hilly open ground is light brown; hilly ground with at least 20 percent canopy is dark green. Low zooms use a naturalized aggregate of the same classifications.

Mountains are deliberately not an elevation band. A one-kilometre summary grid median-filters native samples, then requires at least 300 metres of local relief in a seven-kilometre radius together with either 150 metres of local one-kilometre relief or at least 15 percent steep terrain. Connected components smaller than roughly ten square kilometres are removed before engraved ridge marks are emitted. This excludes high plains and isolated DEM spikes while retaining low but rugged ranges. Browsers receive only compressed tiles; raw DEM pixels are not served and the presentation layer is not persisted in SpacetimeDB.

Elevation is stored on settlements because it describes the settlement's own location and can directly influence scene selection, climate inference, agriculture, travel preparation, and UI presentation. A future source may add route elevation profiles. See route-terrain.md; settlement elevation is never used as a proxy for terrain along an entire road edge.

Native strategic terrain pack

build-strategic-map reads the 12 whole-degree source tiles intersecting the exact 8.965–11.110°E, 50.877–52.211°N playable bounds into the documented base and final terrain-routing-*-v2.json/.pack artifacts. The packs preserve each source tile's native 1,800/2,400/3,600 by 3,600 grid instead of expanding it into database rows or ElevationCell structs. Independently deflated 256×256 chunks carry signed elevation, road/open/sparse-woods/deep-woods/water surface, exact bounded canopy percentage, a native 15-degree hill bit, and an explicit infrastructure-crossing bit.

The runtime decodes the native hill bit as 0 or 100 percent hill coverage. When pathfinding coarsens a window it averages that percentage, rather than promoting a cell when any sample is hilly. Canopy and hill coverage therefore remain independent and a wooded hillside stays a mixed terrain cell.

The compiler writes STRATEGIC_MAP_DATA_LICENSE.md beside the terrain and map outputs. It contains the prescribed Copernicus WorldDEM-30 production credit, liability notice, modification statement, and the separate CC BY-SA licence for Adventure Simulator's contributions. Distribute that notice with the pack; the repository software's AGPL does not license these generated data artifacts.

The manifest and pack are separately SHA-256 addressed. Readers reject wrong dimensions, overlapping or truncated chunks, digest mismatches, excess entries, and oversized decompression. Runtime decompression uses a deterministic 32 MiB LRU. The compressed pack remains range-readable on disk, is size-checked before opening, and is stream-hashed at startup, so the complete native grid never resides in RAM. Chunk I/O and decompression occur outside the cache lock before a race-safe insert. The bounded map's z3 paper tiles sample this pack at approximately 25 m/pixel. Every presentation tile lies inside native-detail coverage, so close zooming does not need continental fallback tiles.

The same pack is the strategic pathfinding input. A bounded search window begins at the native nominal 30 m spacing and coarsens deterministically only when the hard 750,000-node cap requires it. Eight-neighbour A* minimizes directional travel time: roads are fastest, open ground is slower, sparse and deep woods are progressively slower, and positive elevation gain adds an uphill cost. Water is impassable except where imported infrastructure marks a crossing. Search costs use seconds internally so rounding does not compound at every 30 m cell; persisted journey time is rounded once to whole strategic minutes. Each sampled cell also derives a normalized permille Terrain distribution: Forest is the canopy percentage, Hills is the hill fraction of the remaining non-forest share, Plains receives the remainder, and Urban is currently zero. The departure party's weighted Terrain check multiplies speed by 1 + check / 10; A* includes that profile in both its costs and cache key, so expertise can change the chosen route as well as its duration.

Any missing source tile intersecting the playable boundary remains a hard build error. Whole source cells are retained internally, while the manifest, cell lookup, and route planner enforce the exact decimal playable bounds.

Routes are simplified to at most 512 geographic points for transport and are stored only for an active journey together with exact ordered terrain-time spans, their Terrain mixtures, departure checks, road exposure discounts, and the terrain package digest. The raster remains an optional on-disk asset with a 32 MiB decompression cache. If it is absent, corrupt, outside its coverage, or cannot produce a bounded route, the existing HTML travel flow remains available and labels its straight-line value as a legacy estimate.