# ADR 0039: Inline Height-Grid Terrain Foundation ## Status Accepted ## Context Terrain sculpting, material painting, physics placement, recovery, and prefab workflows need one stable owner for height data. Generated meshes and colliders cannot be authoritative because they are runtime artifacts, while introducing an external binary heightmap before editing semantics exist would add file-move, revision, import, and multi-document transaction complexity prematurely. ## Decision `TerrainDesc` schema v1 stores a bounded square grid of normalized finite `f32` heights directly in the authored scene component. It also stores sample spacing, height scale, chunk quad size, an optional shared base Material/Material Instance reference, collider generation, and shadow flags. Hydration deterministically partitions grid quads into generated children. Boundary samples are duplicated between neighboring render chunks so each chunk has complete normals and independent triangle geometry. Chunk meshes/colliders are never `LevelObject` entities and are therefore absent from saved scenes, recovery documents, prefabs, and history snapshots. Resolution changes are explicit destructive flat-grid replacements in the foundation inspector. Sculpt tools mutate the existing grid through grouped history transactions. A future external heightmap representation requires an explicit schema migration and authored-file ownership ADR; it must not silently rewrite an inline terrain during normal load. ## Consequences - Scene, prefab, undo, recovery, collaboration, and validation use one exact terrain document. - V1 grids are bounded to 1025×1025 samples to prevent accidental unbounded scene payloads. - Large production terrains may eventually need tiled external storage and streaming. - Foundation chunks remain raster-only in Solari until terrain layer materials have an exact Surface evaluator in `#24`; explicit exclusion is preferred to a black or mismatched ray-traced proxy. - Layer weights and sculpt strokes extend this descriptor contract in `#23`/`#24`; generated chunks remain disposable regardless of the editing representation.