feat(editor): visible Z + road auto-grading (#246) #248

Merged
panda merged 6 commits from feat/editor-z-roads into main 2026-08-01 22:00:16 +02:00
Collaborator

Summary

Two coupled map-editor authoring aids (#246):

  1. Z is now visible on the canvas. The flat top-down bitmap shades each cell by its local
    Z-gradient (a hillshade, ReliefShade in MapEditor.Core), so elevation reads at a glance — you
    can see the slopes you're authoring. It stays one bitmap + one blit (the shade multiplies the
    per-cell colour; ChunkedEditModel.FillZWindow fills the Z window chunk-by-chunk like the terrain
    window). A Relief shade checkbox (on by default) toggles it.

  2. Roads grade their own Z into a walkable ramp. Painting a road terrain (any isRoad kind —
    a new tiledata flag; road_dirt/road_dirt_snow set it) with the single-cell brush records the
    stroke; on release its Z is graded (RoadGrader) from one end's land height to the other's, each
    step clamped to WorldRules.MaxWalkStepZ, so the road climbs a slope without hitting the walk-step
    wall. A run too steep for its length climbs at the cap and won't fully reach — make it longer /
    switchback.

WorldRules.MaxWalkStepZ is a new shared constant so the editor grades to the exact limit the server
enforces (GameOptions.MaxStepZ now defaults from it). Offline tool — the roads write authoritative
Z into the chunked format the server already validates with the unchanged CanStep; no wire/server
change. Design: docs/superpowers/specs/2026-08-01-editor-z-roads-design.md.

Screenshots / recording

just editor on asterra (--goto 7520 4930 --cellpx 5): the volcanic crater's shape, ridges and lava
now read via the relief shade — flat grey before.

editor relief shade

How it was tested

  • Unit (MapEditor.Core.Tests): RoadGrader — a walkable length follows the linear ramp, a
    too-steep run climbs at exactly the cap, every consecutive step ≤ cap, endpoints anchored, count 0/1
    edges. ReliefShade — flat = 1, a light-facing-away slope darkens to the floor, stays in [floor,1].
    ChunkedEditModel.FillZWindow — matches per-cell ZAt across chunk boundaries and edits.
  • Unit (Shared.Tests): tiledata parses isRoad (default false, round-trips).
  • Editor screenshot (attached): relief shade on real asterra relief. The interactive road paint
    isn't auto-captured — the editor has no mouse-injection harness like the client — but the grading is
    fully unit-tested and the wiring is thin glue.
  • Gates: dotnet csharpier check . clean · dotnet build IsoMmo.slnx 0 warnings · dotnet test
    all green (incl. the 9 new editor/Shared tests).

Checklist

  • just lint passes (CSharpier + analyzers, zero warnings)
  • just test is green
  • The whole solution builds (client and tools included)
  • Multi-platform preserved (pure .NET + MonoGame editor, no OS-specific deps)
  • Tests added/updated (RoadGrader, ReliefShade, FillZWindow, isRoad parse)
  • Linked the related issue (#246) and its Definition of Done is met
## Summary Two coupled map-editor authoring aids (#246): 1. **Z is now visible on the canvas.** The flat top-down bitmap shades each cell by its local Z-gradient (a hillshade, `ReliefShade` in `MapEditor.Core`), so elevation reads at a glance — you can see the slopes you're authoring. It stays one bitmap + one blit (the shade multiplies the per-cell colour; `ChunkedEditModel.FillZWindow` fills the Z window chunk-by-chunk like the terrain window). A **Relief shade** checkbox (on by default) toggles it. 2. **Roads grade their own Z into a walkable ramp.** Painting a **road** terrain (any `isRoad` kind — a new `tiledata` flag; `road_dirt`/`road_dirt_snow` set it) with the single-cell brush records the stroke; on release its Z is graded (`RoadGrader`) from one end's land height to the other's, each step clamped to `WorldRules.MaxWalkStepZ`, so the road climbs a slope without hitting the walk-step wall. A run too steep for its length climbs at the cap and won't fully reach — make it longer / switchback. `WorldRules.MaxWalkStepZ` is a new shared constant so the editor grades to the exact limit the server enforces (`GameOptions.MaxStepZ` now defaults from it). **Offline tool** — the roads write authoritative Z into the chunked format the server already validates with the unchanged `CanStep`; no wire/server change. Design: `docs/superpowers/specs/2026-08-01-editor-z-roads-design.md`. ## Screenshots / recording `just editor` on asterra (`--goto 7520 4930 --cellpx 5`): the volcanic crater's shape, ridges and lava now read via the relief shade — flat grey before. ![editor relief shade](https://git.homelab.devncode.it/attachments/481d883f-b6a4-4691-8906-49683496108f) ## How it was tested - **Unit** (`MapEditor.Core.Tests`): `RoadGrader` — a walkable length follows the linear ramp, a too-steep run climbs at exactly the cap, every consecutive step ≤ cap, endpoints anchored, count 0/1 edges. `ReliefShade` — flat = 1, a light-facing-away slope darkens to the floor, stays in `[floor,1]`. `ChunkedEditModel.FillZWindow` — matches per-cell `ZAt` across chunk boundaries and edits. - **Unit** (`Shared.Tests`): `tiledata` parses `isRoad` (default false, round-trips). - **Editor screenshot** (attached): relief shade on real asterra relief. The interactive road paint isn't auto-captured — the editor has no mouse-injection harness like the client — but the grading is fully unit-tested and the wiring is thin glue. - **Gates**: `dotnet csharpier check .` clean · `dotnet build IsoMmo.slnx` 0 warnings · `dotnet test` all green (incl. the 9 new editor/Shared tests). ## Checklist - [x] `just lint` passes (CSharpier + analyzers, zero warnings) - [x] `just test` is green - [x] The whole solution builds (client and tools included) - [x] Multi-platform preserved (pure .NET + MonoGame editor, no OS-specific deps) - [x] Tests added/updated (`RoadGrader`, `ReliefShade`, `FillZWindow`, `isRoad` parse) - [x] Linked the related issue (#246) and its Definition of Done is met
perf(editor): single-pass terrain+Z fill + flat-cell shade skip (#246)
All checks were successful
ci / Lua content lint (pull_request) Successful in 9s
ci / Lint & Test (pull_request) Successful in 4m58s
849d785b57
panda merged commit 1ae1f06fff into main 2026-08-01 22:00:16 +02:00
panda deleted branch feat/editor-z-roads 2026-08-01 22:00:16 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
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!248
No description provided.