Design: express terrain + static definitions as a data file (tiledata-style), not code tables #143
Labels
No labels
alpha:wave-0
alpha:wave-1
alpha:wave-2
alpha:wave-3
area:assets
area:combat
area:ecology
area:infra
area:render
area:scripting
area:ui
area:world
enhancement
epic
migration
post-alpha
roadmap
tech-debt
type:bug
type:chore
type:design
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
marco/IsoMmo#143
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Design follow-up (raised during #89). Today a biome/static kind is defined across three code places that must stay in sync: the
TerrainTypeenum,TerrainInfo(server flags: walkable, blocksSight), andBiomeVisuals(client: land-art key + placeholder tint) — plusStaticCatalogfor statics. Adding a biome = edits in 3 files.Idea
Express terrain + static definitions as data, not code (UO
tiledata.mul-style): one file (e.g.content/tiledata.jsonor a diffable text table), one row per kind, the single source of truth for flags + art-key + authoring char + placeholder colour. Loaded by both server (flags) and client (art). Could drop theTerrainTypeenum in favour of string ids (like statics already use), and mergeStaticCataloginto the same file so terrain + statics share one definition table.Considerations
Table[terrain]gives compile/test-time completeness; a file is validated at load — add load-time validation (every id known, no dupes) to compensate.TerrainInfo). Needs its own critical-design-review.Out of scope
Not part of #89 (the object/static layer) — filed so it isn't lost.
Critical design review — agreed, promoted ahead of #113 (2026-07-22)
Decision (owner): do the full tiledata refactor now, as the foundation the map editor (#113) builds on. Verdict: go.
Design (concrete)
content/tiledata.txt— committed, diffable text table (not JSON; consistent withworld.map/world.statics), copied to server+client output. Typed rows:terrain <id> <char> <walkable> <blocksSight> <landArt> <tintRGBAhex>static <id> <blocks>Shared: aTileDataloader →TerrainDef/StaticDefrecords, load-time validated (unique ids, unique chars, required fields →FormatException). ReplacesTerrainInfo+StaticCatalog+TileMap.Legend+ the data half ofBiomeVisuals. Tint parsed asuintRGBA (no MonoGame in Shared).TerrainTypeenum dropped → terrain is astringid everywhere (TileMap._terrain→string[,]).#→tree andS→spawn stay grid conventions inTileMap.TileMap.Parse/Loadtake the loadedTileData; it is loaded at server startup (single-threaded, before the sim host) and at clientLoadContent.BiomeVisualsdeleted (art-key + tint now fromTileData; client convertsuint→Color);GroundTileSelector/GridRenderer/ClientContextkeyed bystring.Why now / coordination
TerrainTypeis not a wire type (absent fromShared/Protocol) → noProtocolVersionbump. Ripple ≈ 9 files + 3 test files, mechanical. This refactors the #142 terrain foundation (@andrea): collision risk is low right now — no open PRs, no branch implementing #137/#138/#140 yet; the biome foundation is already onmain. @andrea heads-up: #137/#138/#140 will rebase onto this — terrain becomes string ids + atiledata.txt,TerrainInfo/BiomeVisualsare absorbed intoTileData.Invariants Check
Full walk of
## Design checklistrecorded in the PR (all N/A except: Scope ✓, Server-authoritative ✓, Single-threaded-sim ✓, Client-engine-independence ✓, Extend-by-data ✓✓ [the goal], Multi-platform ✓, Assets ✓, ModernUO ✓ [converge on tiledata.mul, diverge to diffable text], Docs&DoD ✓). No HARD GATE tripped. Protocol N/A (verified TerrainType is not wire).DoD (delta)
content/tiledata.txt+ its art, zero code change (demonstrable).TileData; a bad/duplicate/unknown row fails at load with a clear error, not silently.TerrainTypeenum removed; no behavioural regression (walkability, LOS, biome rendering, marsh scatter unchanged).