Design: Biomes — a hand-authored patchwork world (ground + fixtures + move-cost) #135

Closed
opened 2026-07-22 13:20:59 +02:00 by panda · 3 comments
Collaborator

Design doc: docs/game-design/systems/biomes.md (agreed; reviewed by a 4-persona critical panel).
Bible updated: docs/game-design/vision.md → "Designed, not yet built".

From the player's POV

The world stops being one endless grass field. Walking it, the ground under you changes —
grassland → dry savanna → cracked salt flats → black volcanic plain → frosted tundra — each region
with its own ground texture and its own scatter of plants and rocks, so you learn to read where you
are
without a map label. Some things (pine, boulder, cactus) block your path like trees; some ground
drags at you — the marsh is crossable but slow, a real shortcut-or-detour choice. MVP is
atmosphere + legibility + that one traversal trade-off. Biome identity is the reserved key for future
creature-spawns and gathering (designed-for, not built here).

Six-lens summary

  • Player POV — read the world by its look; cross the marsh slow-or-go-around.
  • Coherence — generalizes today's 3-type terrain; three orthogonal, data-driven axes
    (biome ground: walkable + move-cost; server fixture: blocks-walk + blocks-sight; client-only
    decorative scatter). Two-layer map (ground char + object char). No ProtocolVersion bump
    (terrain never crosses the wire — verified against ServerMessage).
  • Server-authority — walkability, move-cost (step-cooldown scaling, max(from,into), applied to
    players and creatures), and line-of-sight all validated server-side; a modified client cannot
    cross marsh fast. Client scatter is render-only and MUST NEVER feed a server rule.
  • UI/UX — no HUD; per-cell ground variant selection, blocking-vs-passable silhouette convention
    (contact shadow) + red target-cursor, tall fixtures fade like trees (#66), marsh per-step ripple +
    one-time notice, border edge-scatter feathering (bare seams rejected).
  • Breakage — marsh symmetric (not a mob trap), free-exit-burst closed by max(), player terrain
    griefing closed by construction, creature-kiting amplification flagged to the combat/AI track.
  • Scope/MVP — visual biomes + fixtures + marsh slow now; spawns/gathering/blend-tiles/region-names/
    proc-gen/flying-movers deferred.

Definition of Done (player-observable)

  • A straight walk crosses ≥4 visually distinct biomes, each with per-cell ground variety (no
    obvious repeat grid) and its own scatter.
  • Every walkable ground is walkable; every blocking fixture stops you like a tree; the target cursor
    over a fixture reads blocked (red).
  • A player can predict block-vs-pass from a prop's silhouette alone (grounded+shadow = blocks).
  • Marsh is visibly slower than grassland; a fast/modified client cannot cross it at normal
    speed; a creature chasing through marsh is slowed equally (timed run) — not a mob-favored trap;
    first marsh step gives a one-time notice + per-step ripple (never reads as lag).
  • No fixture or tall scatter can fully hide the self-player (fades like a tree).
  • Two players on the same tile see the same scatter (deterministic).
  • Line-of-sight is blocked by boulder/pine but not by cactus.
  • No prop renders as an opaque square; biome borders are feathered (no bare stair-step seam).
  • The world still loads and plays with the art pack absent (placeholder fallback).

Authoring prerequisites (block art, independent of code)

  • Source PNGs are RGB, no alpha → props must be re-exported RGBA with cut-out background (no color-key).
  • All are 1254² → downscale (ground ~128–256, props to native display size) or the committed pack balloons.
  • Ground variants must be seamless iso-tileable; blocking props drawn as grounded volume + contact shadow.

Technical breakdown to follow (separate review).

**Design doc:** `docs/game-design/systems/biomes.md` (agreed; reviewed by a 4-persona critical panel). Bible updated: `docs/game-design/vision.md` → "Designed, not yet built". ## From the player's POV The world stops being one endless grass field. Walking it, the ground under you changes — grassland → dry savanna → cracked salt flats → black volcanic plain → frosted tundra — each region with its own ground texture and its own scatter of plants and rocks, so you learn to read *where you are* without a map label. Some things (pine, boulder, cactus) block your path like trees; some ground drags at you — the **marsh is crossable but slow**, a real shortcut-or-detour choice. MVP is atmosphere + legibility + that one traversal trade-off. Biome identity is the reserved key for future creature-spawns and gathering (designed-for, not built here). ## Six-lens summary - **Player POV** — read the world by its look; cross the marsh slow-or-go-around. - **Coherence** — generalizes today's 3-type terrain; three orthogonal, data-driven axes (biome ground: walkable + move-cost; server fixture: blocks-walk + blocks-sight; client-only decorative scatter). Two-layer map (ground char + object char). **No `ProtocolVersion` bump** (terrain never crosses the wire — verified against `ServerMessage`). - **Server-authority** — walkability, move-cost (step-cooldown scaling, `max(from,into)`, applied to players *and* creatures), and line-of-sight all validated server-side; a modified client cannot cross marsh fast. Client scatter is render-only and MUST NEVER feed a server rule. - **UI/UX** — no HUD; per-cell ground variant selection, blocking-vs-passable silhouette convention (contact shadow) + red target-cursor, tall fixtures fade like trees (#66), marsh per-step ripple + one-time notice, border edge-scatter feathering (bare seams rejected). - **Breakage** — marsh symmetric (not a mob trap), free-exit-burst closed by `max()`, player terrain griefing closed by construction, creature-kiting amplification flagged to the combat/AI track. - **Scope/MVP** — visual biomes + fixtures + marsh slow now; spawns/gathering/blend-tiles/region-names/ proc-gen/flying-movers deferred. ## Definition of Done (player-observable) - A straight walk crosses **≥4 visually distinct biomes**, each with per-cell ground variety (no obvious repeat grid) and its own scatter. - Every walkable ground is walkable; every blocking fixture stops you like a tree; the target cursor over a fixture reads blocked (red). - A player can **predict block-vs-pass from a prop's silhouette alone** (grounded+shadow = blocks). - **Marsh is visibly slower** than grassland; a **fast/modified client cannot** cross it at normal speed; a **creature chasing through marsh is slowed equally** (timed run) — not a mob-favored trap; first marsh step gives a one-time notice + per-step ripple (never reads as lag). - **No fixture or tall scatter can fully hide the self-player** (fades like a tree). - Two players on the same tile see the **same** scatter (deterministic). - Line-of-sight is blocked by boulder/pine but **not** by cactus. - No prop renders as an opaque square; biome borders are feathered (no bare stair-step seam). - The world still loads and plays with the **art pack absent** (placeholder fallback). ## Authoring prerequisites (block art, independent of code) - Source PNGs are RGB, no alpha → props must be re-exported **RGBA with cut-out background** (no color-key). - All are 1254² → **downscale** (ground ~128–256, props to native display size) or the committed pack balloons. - Ground variants must be **seamless iso-tileable**; blocking props drawn as grounded volume + contact shadow. _Technical breakdown to follow (separate review)._
Author
Collaborator

Technical breakdown of this design into implementation slices (order: B -> C/D/E, A in parallel):

  • #136 -- B: data-driven terrain + biome ground layer (foundation)
  • #138 -- C: terrain move-cost (marsh slow) for all movers (depends on #136)
  • #139 -- D: fixtures object-layer (blocks walk + blocks sight) (depends on #136)
  • #140 -- E: per-biome scatter + border feathering (depends on #136)
  • #137 -- A: import authored biome art into the pack (blocked on art re-export: RGBA + downscale)

Deferred follow-ups (separate issues when needed): creature one-step side-step (anti-kiting, combat/AI track), move-rejected bump cue, blend/transition tiles, region names, spawns-by-biome, gathering-by-biome.

**Technical breakdown** of this design into implementation slices (order: **B -> C/D/E**, **A** in parallel): - [ ] #136 -- B: data-driven terrain + biome ground layer (foundation) - [ ] #138 -- C: terrain move-cost (marsh slow) for all movers *(depends on #136)* - [ ] #139 -- D: fixtures object-layer (blocks walk + blocks sight) *(depends on #136)* - [ ] #140 -- E: per-biome scatter + border feathering *(depends on #136)* - [ ] #137 -- A: import authored biome art into the pack *(blocked on art re-export: RGBA + downscale)* Deferred follow-ups (separate issues when needed): creature one-step side-step (anti-kiting, combat/AI track), move-rejected bump cue, blend/transition tiles, region names, spawns-by-biome, gathering-by-biome.
Owner

⏭️ Heads-up @andrea: #143 (full tiledata data-file) is being implemented now as the foundation for the #113 map editor (owner's call). It absorbs TerrainInfo + BiomeVisuals + StaticCatalog + the terrain legend into one content/tiledata.txt and replaces the TerrainType enum with string ids. This touches the #142 foundation this issue builds on — when you pick it up you'll rebase onto the new model (terrain = string id, flags/art/tint read from TileData). No ProtocolVersion change. Design + invariants recorded on #143.

⏭️ Heads-up @andrea: #143 (full tiledata data-file) is being implemented now as the foundation for the #113 map editor (owner's call). It **absorbs `TerrainInfo` + `BiomeVisuals` + `StaticCatalog` + the terrain legend into one `content/tiledata.txt`** and **replaces the `TerrainType` enum with string ids**. This touches the #142 foundation this issue builds on — when you pick it up you'll rebase onto the new model (terrain = string id, flags/art/tint read from `TileData`). No `ProtocolVersion` change. Design + invariants recorded on #143.
Owner

Chiudo: il design dei biomi è stato consegnato. Figli: B (#136) e D (#139) chiusi; A (#137) e C (#138) completati e chiusi in questa stessa tornata; E (#140) ridotta al solo residuo di feathering. Il doc docs/game-design/systems/biomes.md resta il riferimento. Chiudo il parent di design — il lavoro residuo vive su #140.

Chiudo: il **design dei biomi è stato consegnato**. Figli: B (#136) e D (#139) chiusi; A (#137) e C (#138) completati e chiusi in questa stessa tornata; E (#140) ridotta al solo residuo di feathering. Il doc `docs/game-design/systems/biomes.md` resta il riferimento. Chiudo il parent di design — il lavoro residuo vive su #140.
marco closed this issue 2026-07-25 19:06:23 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
marco/IsoMmo#135
No description provided.