Slopcouver Labs

Labs · Experiment 7 of 7 · LiDAR, Open data, The game

Rebuilding a city's ground from LiDAR

Started
Updated
Status
shipped
Verdict
Mixed

The game's ground was 3.5–6 m too high and inconsistent between districts. Can every height grid be rebuilt from the City's LiDAR ground returns, on one datum, without opening seams or leaving objects floating?

Status: shipped. Live in the game since Release 143 ("Solid ground"), 8 Nov 2026 at 02:44 Vancouver time. The figures are from the release candidate's own grids, which are what shipped.

Why

Slopcouver's terrain came from global open terrain tiles (AWS Terrarium), stored relative to the lowest point in each area, in one grid for the core and one for each of 16 outer districts. Measured against the City's 2022 LiDAR ground returns, the core grid stood a median 5.6 m too high inland but only 3.8 m too high within 50 m of the water, and the district grids disagreed with each other by up to a metre. With the sea fixed at the game's 2.0 m, that showed up as low shores, bridge decks measured over their own ground sitting 4.4 m too high over the water, and water standing on plazas. It wasn't one shift that could be subtracted.

Source: each grid minus the LiDAR ground (median of 1 m ground cells within 5 m of each node), from the re-bake plan's measurements, 8 Nov 2026.

Hypothesis

Rebuilding every grid from the LiDAR's ground class, with one datum (game height = CGVD28 + D, the sea kept at 2.0), will:

  1. bring the ground to within 0.5 m of the LiDAR at the shore and inland;
  2. keep the seams between grids no worse than today, and under 0.3 m;
  3. move everything that stands on the ground with it, so that a census finds only a short, explainable list of objects that float or sink.

Method

  • Ground: each grid node takes the median of LiDAR class-2 (ground) points within 5 m, with a measured/unmeasured mask; gaps (water, large buildings, dense canopy) are filled from the old grid, shifted by its local offset and blended over 50 m.
  • Datum: D = 1.85 m from mean sea level at Point Atkinson. (The LiDAR's own water was flown at low tide, −0.5 to −1.1 m CGVD28, so it couldn't serve as the datum directly.)
  • Trust rules, added after review: a measured node more than 10 m off the old grid's trend isn't trusted (decks classed as ground had made 70 m steps); a filled value is trusted only within 5 m of the old grid less its local offset; a gap two grids share carries one value at their seam; water connected to the sea takes the sea's level, while lakes keep their own.
  • Rivers and decks: the river data is rebuilt from the new ground with the game's own code; the elevated viaducts, held at absolute heights, are moved with the regional ground change and pinned where they meet streets; the Lions Gate approach is anchored to the new ground.
  • Census: build the whole city (core plus all 20 regions) on the old ground and on the new one, and compare, for every mesh, instanced item and collider, the change in its base with the change in the ground beneath it.
  • Review: three rounds of independent review on the candidate outputs, read-only.
  • Tools and hardware: Python with NumPy for the rebuild; a headless browser with software WebGL for the census and screenshots; one Debian desktop. No cost.

Results

Ground against LiDAR

Distance from waterOld groundNew groundLiDAR + D
30–50 m3.532.462.65
60–100 m8.114.304.30
110–250 m12.648.748.84
500 m – 1 km56.052.652.6
Core grid, median height above the 2.0 m sea at LiDAR-measured nodes, metres. Land came down a median 3.75 m in the core (p10–p90: 2.3–4.9 m) and 2.7–4.2 m in the districts. We had expected shores to come up; they came down, to their real height above mean sea level. Source: the re-bake's measurement of the core grid against LiDAR-measured nodes on the first full candidate, 8 Nov 2026; not re-run on the final grids.

Seams between grids

SeamOld worst stepRelease 143 worst step
Southlands / Dunbar (the worst seam overall)1.79 m1.43 m
UBC / SW Marine (on a 45 m slope)1.57 m1.22 m
Point Grey0.55 m0.57 m
Every district edgemedian step about 0.1 m, as before; a few 99th percentiles slightly above the old grids'
Steps sampled every 5 m along each district edge. The 0.3 m gate was stricter than the old grids ever met. An earlier candidate made the UBC seam worse (2.05 m); a final pass that makes overlapping district grids agree brought both worst seams below the old ones. Source: the release candidate's seam measurement and its independent review, 8 Nov 2026.

The float/sink census

Source: the whole-city census on Release 143's pack (core plus all 20 regions, software rendering), 8 Nov 2026.

Of 304,340 objects (298,553 matched between the two builds), 97.8% follow the ground within 0.5 m. Most of the rest are merged building chunks whose base is the lowest point of a whole chunk while the ground was sampled at its centre. The real items the census found, all now handled: the elevated viaducts (+5.9 m before they were moved), the Lions Gate approach (+3.9 to +4.3 m before anchoring), the Bloedel Conservatory dome poking through its plaza on the sharper LiDAR summit (now seated on the highest ground under it), and about 90 colliders at BC Place where the stadium came down 6–7 m with the flats while Beatty Street's edge stayed at 11.3 m: the real lie of the land.

Independent review

Round 1: fail. Fills that wrapped round a grid's edge were treated as measured ground and put false hills of up to 90 m on the Fraser foreshore. Round 2: fail, narrowly: one wrapped fill made a 6 m trench. Round 3: pass, with the known items. The final pass that makes overlapping district grids agree also passed review, with two medium findings recorded below. A separate tool, the one that moves the viaducts, failed its first review (a 0.78 m step at a three-way junction) and passed its second.

Old ground: Kitsilano Beach from the airLiDAR ground: Kitsilano Beach from the airOld groundLiDAR ground
Kitsilano Beach. The whole scene comes down about 3–4 m; the shore keeps its shape and buildings, trees and paths move with the ground.
Old ground: Bloedel Conservatory at Queen Elizabeth ParkLiDAR ground: Bloedel Conservatory at Queen Elizabeth ParkOld groundLiDAR ground
Queen Elizabeth Park. The LiDAR summit is sharper than the old grid's; the dome is seated on the highest ground under it, with its plaza stepping down as a plinth.
Old ground: The south approach to the Lions Gate Bridge in Stanley ParkLiDAR ground: The south approach to the Lions Gate Bridge in Stanley ParkOld groundLiDAR ground
The Lions Gate Bridge from its south approach in Stanley Park, the deck on the right. The ground comes down, and the deck, authored at absolute heights, is re-seated on anchors written from the LiDAR, so it still meets the ground; mid-span clearance stays at 61 m. Little changes in view, which is the intended result.
Old ground: The Grandview CutLiDAR ground: The Grandview CutOld groundLiDAR ground
Near the Grandview Cut, a rail cutting the old grid didn't have. The measured ground brings the area down; buildings and streets follow it.
Old ground: Science World and the east end of False CreekLiDAR ground: Science World and the east end of False CreekOld groundLiDAR ground
Science World. The water on the plaza is there before and after: it comes from a river-bed cell in the game's water data, not from the ground, and is filed separately.

Limitations and threats to validity

  • D is a single number taken from a tide gauge, not from the survey's own water (flown at low tide).
  • Trust rules are heuristics. At cliffs and deck approaches some measured nodes stay more than 5 m from the LiDAR (3,586 at UBC's cliffs, 1,663 in the core); one ledge at the Southlands escarpment is lumpy.
  • The census compares bases with the ground under an object's centre, which flags slope noise as well as real errors; the 2,273 downtown colliders flagged have a median of 0.54 m, which we read as noise.
  • Correctness was checked in software rendering, not on a phone; timing wasn't measured (grid sizes are unchanged, so memory shouldn't change).
  • Making overlapping grids agree has a cost: it changed 24,115 rendered nodes in narrow bands along the overlaps (290 by more than 1 m), and raised the mean error against the LiDAR by 0.03–0.16 m per district. On bluffs, one grid copies the other's edge row: at SW Marine one spot is 4.77 m further off the LiDAR, and Point Grey has a 3.86 m step where the LiDAR's is 1.13 m. Both have known fixes, not yet made.
  • Four viaduct ramps come out steeper than before (worst 17.8%). The LiDAR shows the real decks still elevated at their mapped ends, so the true touchdown is further along the next street; the old ground hid this.

Verdict

Supported (1): the ground follows the LiDAR to within 0.1 m from 30 m inland, and within 0.2 m at 30–50 m from the water.

Not supported (2) as stated: the 0.3 m gate wasn't met (the old grids never met it either). The worst seams did improve (1.79 → 1.43 m and 1.57 → 1.22 m), while Point Grey and a few 99th percentiles came out slightly worse.

Supported (3): 97.8% of objects follow the ground within 0.5 m, and every real outlier was explained and fixed.

Practical application

  • For the game: shores, beaches, bridges and hills at their real heights; the five bridges can now be raised onto their measured decks. Live since Release 143 (8 Nov 2026).
  • For anyone building terrain from open LiDAR: don't shift old grids; rebuild from the ground class, distrust nodes far off the old trend (decks and cliffs are classed as ground surprisingly often), handle fills separately from measurements, and run a census of everything placed on the ground before shipping.
  • For flood and shoreline work: the same pipeline gives a consistent, sea-level-referenced surface across districts; the corrected shore heights are what freeboard and sea-level-rise visualisations need. (Our grids are for a game, at game resolution; they aren't a survey product.)
  • What remains: a slope-tolerant trust test for cliffs; fixing the Science World plaza water; checking piers and bridge towers on the new ground.

Reproducibility

In the Slopcouver repository (private for now): app/tools/lidar/rebake-ground.py (all grids, D as one parameter; writes only the changed files plus a receipt), app/tools/lidar/reseat-decks.py (moves the viaducts; refuses to run twice), raise-decks.py (the five bridges), and the census scripts.

python3 tools/lidar/rebake-ground.py <pack dir> <rasters dir> <out dir> --D 1.85
python3 tools/lidar/reseat-decks.py <old pack> <new pack> <decks.json> <out decks.json> --D 1.85

Data and credits: City of Vancouver LiDAR 2022, OGL–Vancouver. The old ground: Terrarium elevation tiles (Mapzen / AWS Open Data; sources include USGS, NRCan CDEM and others). Mean sea level at Point Atkinson: Fisheries and Oceans Canada, Canadian Hydrographic Service. Street and bridge data: OpenStreetMap contributors, ODbL.