Files
jbashrc/claude/integration-memory/project_island_terrain_design.md
2026-09-14 14:43:00 -04:00

46 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: project-island-terrain-design
description: Design decisions for the downloadable-island terrain system (replaces Unreal Landscape)
metadata:
node_type: memory
type: project
originSessionId: 38ffbfc6-93fe-4670-9015-1be594a56944
---
Game concept: like visiting Animal Crossing islands — client downloads an island
(heightfield + weightmaps) from a server and builds terrain at runtime in a
packaged build. Stock Landscape is unusable (editor-only construction). Terrain
is smooth sculpted hills (heightfield, NOT voxels, NOT tile-based). Islands can
be large (multi-km); ~5s load budget is fine.
Decisions as of 2026-06-11:
- **Patches**: 256×256 quads = 257×257 vertices, driven by a 257×257 non-mipped
height texture region (possibly a sub-rect of one big island texture — left open).
- **LOD**: 3 levels (interiors 256/128/64 segments), but patch *edges always stay
at full 257-vertex resolution* — only interiors decimate. Any two neighbor LODs
fit seamlessly by construction; no stitching, no neighbor bookkeeping. Transition
ring fans coarse interior to full-res edge (the tricky indexing part).
- **One shared mesh**: a single flat (z=0) UStaticMesh with 3 LODs, built at
runtime via FMeshDescription + BuildFromMeshDescriptions(bFastBuild=true),
cached lazily in a GameInstanceSubsystem. Rendered via HISM instances (one per
patch); HISM auto per-instance LOD selection is safe thanks to edge-preserving LODs.
- **Displacement**: material WPO samples height texture (explicit mip 0, point
filter, +half-texel offset). UVs NOT stored in mesh — derived from world position
minus island origin (material params). No per-instance custom data needed.
Pixel shader: splat weightmaps + heightfield-derived normal map (those DO get mips;
weightmaps sized 4096², not 4097, so BC compression works).
- **Collision**: custom UPrimitiveComponent wrapping Chaos::FHeightField (no cook,
~ms build, built from the same uint16 samples; crib from LandscapeCollision.cpp:1049).
Nobody public has done this (verified via Sourcegraph 2026-06); trimesh PMC path is
scaffolding only. Heightfield wins on memory (34MB vs GBs at 4097²) and query speed.
- **Height data**: uint16 grid, Landscape convention ((worldZ/scale)+32768).
- **Lumen**: project doesn't use it (no RendererSettings overrides; default GI=None).
Flat-proxy WPO terrain is incompatible-ish with Lumen — accepted, documented risk.
- Heightfield texture is NOT mipmapped (LODs sample full-res at sparse points —
exact vs collision; Landscape instead resamples mips + geomorphs, [[its choice]]).
Code so far: `Source/Integration/TerrainPatch.h/cpp` — USTRUCT FlxTerrainPatch with
stubbed static MakePatch() (returns UStaticMesh*) and editor-only SavePatch()
(writes uasset for debugging; game always generates dynamically).