feat(mapeditor): chunk-backed edit model — overlay, Allaga, incremental save (PR 3 of #229) #232

Merged
panda merged 1 commit from feat/world-map-editor-model into main 2026-08-01 08:34:56 +02:00
Collaborator

Summary

Third slice of the world-map migration (epic #229) — the chunk-backed editor model (MapEditor.Core), the piece that lets the editor open and edit the 133 M-cell world with bounded memory. This is the engine-agnostic model only; the EditorGame UI wiring and authoring UX (zoom/overview/brushes) are the next slice, and undo/redo + autosave/journal are separate follow-ups (kept out to keep this reviewable).

ChunkedEditModel (stacked on the PR #231 store):

  • Overlay reads — a cell resolves to its edited chunk if one exists, else the base WorldMapStore, else the default terrain. Opening reads only the manifest.
  • Materialize-on-edit — a mutable EditableChunk is created only when a cell in it is edited, so retained memory is bounded by the edited set, never the map (a test edits one cell of the 133 M world and asserts a single dirty chunk).
  • FloodMap (Allaga mappa) — the ocean initializer: a manifest default-flip that drops all overrides in one step, no 133 M-cell loop. (The liquid-preserving flood that keeps Z/statics needs the terrain/liquid split — Fase 5.)
  • Incremental save — only regions containing edits are rewritten, merging in their untouched chunks; a region that becomes entirely default is deleted; other regions' files are left byte-identical (a test asserts this). New/flooded worlds take the full-write path.
  • Small supporting change: WorldMapStore.HasMaterializedChunk (so incremental save keeps untouched base chunks without decoding them) and WorldMapPaths made public (single source of the on-disk layout for the editor).

Stacked on #231 (which is stacked on #230). The diff currently includes both parents' commits; I'll rebase onto main as they merge so this shows only the edit-model commit.

Screenshots / recording

N/A — engine-agnostic model, not yet wired into the editor UI (nothing rendered changes). Screenshots come with the UI-wiring slice, captured by piloting the editor.

How it was tested

  • 9 new unit tests (tests/IsoMmo.MapEditor.Core.Tests/Chunked): new-ocean reads default everywhere with nothing materialized; edits materialize only touched chunks; save→reopen round-trips terrain/elevation/statics/spawn; opens the 13,344×9,984 world, edits one cell with a single dirty chunk; flood resets to default and removes all region files; incremental save leaves untouched regions byte-identical; editing an existing chunk preserves its other cells; unknown-terrain and out-of-bounds rejected.
  • Whole solution builds with 0 warnings; dotnet test fully green (MapEditor.Core 35, incl. the 9 new); just lint clean.

DoD delta (beyond the base DoD + epic #229)

  • The editor model opens the 133 M-cell world by reading only the manifest and edits it with memory bounded by the dirty set (not the map).
  • Allaga mappa is a single default-flip that clears to the default without materializing chunks.
  • Save writes only dirty regions; untouched regions' files are byte-identical after an edit-and-save elsewhere.
  • Save→reopen preserves terrain, elevation, statics and spawn exactly.
  • No runtime behavior change: the model is additive; EditorGame still uses the existing MapModel (UI swap is the next slice).

Checklist

  • just lint passes (CSharpier + analyzers, zero warnings)
  • just test is green
  • The whole solution builds (client and tools included)
  • Multi-platform preserved (pure managed .NET; no OS-specific deps)
  • Tests added/updated for this change
  • Linked the related issue (#229) and its per-PR DoD is met
## Summary Third slice of the world-map migration (epic #229) — the **chunk-backed editor model** (`MapEditor.Core`), the piece that lets the editor open and edit the 133 M-cell world with bounded memory. This is the engine-agnostic model only; the `EditorGame` UI wiring and authoring UX (zoom/overview/brushes) are the next slice, and undo/redo + autosave/journal are separate follow-ups (kept out to keep this reviewable). `ChunkedEditModel` (stacked on the PR #231 store): - **Overlay reads** — a cell resolves to its edited chunk if one exists, else the base `WorldMapStore`, else the default terrain. Opening reads only the manifest. - **Materialize-on-edit** — a mutable `EditableChunk` is created only when a cell in it is edited, so retained memory is bounded by the *edited* set, never the map (a test edits one cell of the 133 M world and asserts a single dirty chunk). - **`FloodMap`** (Allaga mappa) — the ocean initializer: a manifest default-flip that drops all overrides in one step, no 133 M-cell loop. (The liquid-preserving flood that keeps Z/statics needs the terrain/liquid split — Fase 5.) - **Incremental save** — only regions containing edits are rewritten, merging in their untouched chunks; a region that becomes entirely default is deleted; other regions' files are left **byte-identical** (a test asserts this). New/flooded worlds take the full-write path. - Small supporting change: `WorldMapStore.HasMaterializedChunk` (so incremental save keeps untouched base chunks without decoding them) and `WorldMapPaths` made public (single source of the on-disk layout for the editor). **Stacked on #231** (which is stacked on #230). The diff currently includes both parents' commits; I'll rebase onto `main` as they merge so this shows only the edit-model commit. ## Screenshots / recording N/A — engine-agnostic model, not yet wired into the editor UI (nothing rendered changes). Screenshots come with the UI-wiring slice, captured by piloting the editor. ## How it was tested - **9 new unit tests** (`tests/IsoMmo.MapEditor.Core.Tests/Chunked`): new-ocean reads default everywhere with nothing materialized; edits materialize only touched chunks; save→reopen round-trips terrain/elevation/statics/spawn; **opens the 13,344×9,984 world, edits one cell with a single dirty chunk**; flood resets to default and removes all region files; **incremental save leaves untouched regions byte-identical**; editing an existing chunk preserves its other cells; unknown-terrain and out-of-bounds rejected. - Whole solution builds with **0 warnings**; `dotnet test` fully green (MapEditor.Core 35, incl. the 9 new); `just lint` clean. ### DoD delta (beyond the base DoD + epic #229) - The editor model opens the 133 M-cell world by reading only the manifest and edits it with memory bounded by the dirty set (not the map). - `Allaga mappa` is a single default-flip that clears to the default without materializing chunks. - Save writes only dirty regions; untouched regions' files are byte-identical after an edit-and-save elsewhere. - Save→reopen preserves terrain, elevation, statics and spawn exactly. - No runtime behavior change: the model is additive; `EditorGame` still uses the existing `MapModel` (UI swap is the next slice). ## 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 managed .NET; no OS-specific deps) - [x] Tests added/updated for this change - [x] Linked the related issue (#229) and its per-PR DoD is met
feat(mapbench): map-architecture baseline benchmark harness (PR 1 of #229)
All checks were successful
ci / Lua content lint (pull_request) Successful in 10s
ci / Lint & Test (pull_request) Successful in 4m53s
aec2a43e8f
feat(world): chunked binary world-map format, store + legacy importer (PR 2 of #229)
All checks were successful
ci / Lua content lint (pull_request) Successful in 9s
ci / Lint & Test (pull_request) Successful in 5m4s
b310dcc9d2
feat(mapeditor): chunk-backed edit model — overlay, Allaga, incremental save (PR 3 of #229)
All checks were successful
ci / Lua content lint (pull_request) Successful in 15s
ci / Lint & Test (pull_request) Successful in 7m49s
30d36149b7
panda force-pushed feat/world-map-editor-model from 30d36149b7
All checks were successful
ci / Lua content lint (pull_request) Successful in 15s
ci / Lint & Test (pull_request) Successful in 7m49s
to 375fa7281a
All checks were successful
ci / Lua content lint (pull_request) Successful in 33s
ci / Lint & Test (pull_request) Successful in 7m38s
2026-08-01 08:27:05 +02:00
Compare
panda merged commit 4ca46e027c into main 2026-08-01 08:34:56 +02:00
panda deleted branch feat/world-map-editor-model 2026-08-01 08:34:57 +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!232
No description provided.