feat(client): admin minimap + click-to-/tp (#237) #244

Merged
panda merged 5 commits from feat/admin-minimap into main 2026-08-01 19:17:53 +02:00
Collaborator

Summary

An admin-only minimap (#237): a baked top-down overview of the whole world (asterra), shown top-right, zoomable with the mouse wheel (cursor-centred) and pannable, with the player marked. Clicking teleports there via a server-validated /tp x y.

It is drawn only for admins (AdminPanel.IsAdmin, a UI gate); the click sends the same GmCommandRequest a /tp chat command would, so the server re-checks the signed admin claim and validates the target is a walkable tile — the client never moves the player itself. Wanted so an admin can jump anywhere on the 13,344×9,984-cell planet without walking or typing coordinates.

Architecture: MinimapBaker (Client.Core, MonoGame-free, unit-tested) bakes the whole IReadOnlyTileMap into a packed-RGBA uint[] (one terrain tint per sampled cell) once at load. Minimap (client UI) uploads it to a Texture2D and draws a zoom/pan view + marker; TryPick maps a screen pixel back to a world cell. Wired thinly into GameScreen (build + dispose), WorldRenderer (draw if admin) and GameInputController (M toggle, wheel zoom, click → tp), with the minimap added to the panel-hit guard so a minimap click never also moves/engages the player. No new wire type (reuses GmCommandRequest) → no ProtocolVersion bump.

Screenshots / recording

Piloted via the debug harness (docs/debug-harness.md), fresh DB, as admin test:

login test          # admin
key M               # toggle the minimap on (top-right, with the player marker)
# (scroll-wheel over the minimap zooms — real input; the harness does not inject the wheel)
click 1161 114      # click a land pixel -> client sends "tp 7760 5296"
status              # -> tile (7760,5296): teleported to the clicked cell
  • Minimap overview — toggled on, whole planet, gold frame + red player marker: mm_overview.png
  • After a minimap click — server replied Teleported, player is now on the distant continent region (~7760,5296, far from spawn ~5183,4378); the minimap here is zoomed in on the continent, done live with the mouse wheel: mm_teleported.png

minimap overview

after teleport

How it was tested

  • Unit (tests/IsoMmo.Client.Core.Tests/MinimapBakerTests.cs): Bake samples the terrain tint at each sampled cell; CellAt maps a minimap pixel back to its world cell.
  • Visual gate (Windows, fresh DB): the harness run above. Confirmed the minimap draws only for admin (HUD · /admin), M toggles it, the wheel zooms, and a click teleports — the server logged tp 7760 5296 -> Teleported and the client reconciled its self position to the exact clicked cell (7760,5296).
    • Bug caught + fixed by the gate: GmCommandRequest must carry the command without the leading / (the registry looks up tp, not /tp) — the first click logged /tp … -> UnknownCommand.
  • Gates: dotnet csharpier check . clean · dotnet build IsoMmo.slnx 0 warnings / 0 errors · dotnet test IsoMmo.slnx all green (739 tests, incl. the 2 new MinimapBaker 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 MonoGame + Client.Core, no OS-specific deps)
  • Tests added/updated for this change (MinimapBakerTests)
  • Linked the related issue (#237) and its Definition of Done is met
## Summary An **admin-only minimap** (#237): a baked top-down overview of the whole world (asterra), shown top-right, **zoomable** with the mouse wheel (cursor-centred) and **pannable**, with the player marked. **Clicking teleports there** via a server-validated `/tp x y`. It is drawn only for admins (`AdminPanel.IsAdmin`, a UI gate); the click sends the same `GmCommandRequest` a `/tp` chat command would, so the server re-checks the signed `admin` claim and validates the target is a walkable tile — the client never moves the player itself. Wanted so an admin can jump anywhere on the 13,344×9,984-cell planet without walking or typing coordinates. Architecture: `MinimapBaker` (Client.Core, MonoGame-free, unit-tested) bakes the whole `IReadOnlyTileMap` into a packed-RGBA `uint[]` (one terrain tint per sampled cell) once at load. `Minimap` (client UI) uploads it to a `Texture2D` and draws a zoom/pan view + marker; `TryPick` maps a screen pixel back to a world cell. Wired thinly into `GameScreen` (build + dispose), `WorldRenderer` (draw if admin) and `GameInputController` (M toggle, wheel zoom, click → `tp`), with the minimap added to the panel-hit guard so a minimap click never also moves/engages the player. No new wire type (reuses `GmCommandRequest`) → no `ProtocolVersion` bump. ## Screenshots / recording Piloted via the debug harness (`docs/debug-harness.md`), **fresh DB**, as admin `test`: ``` login test # admin key M # toggle the minimap on (top-right, with the player marker) # (scroll-wheel over the minimap zooms — real input; the harness does not inject the wheel) click 1161 114 # click a land pixel -> client sends "tp 7760 5296" status # -> tile (7760,5296): teleported to the clicked cell ``` - **Minimap overview** — toggled on, whole planet, gold frame + red player marker: `mm_overview.png` - **After a minimap click** — server replied `Teleported`, player is now on the distant continent region (~7760,5296, far from spawn ~5183,4378); the minimap here is zoomed in on the continent, done live with the mouse wheel: `mm_teleported.png` ![minimap overview](https://git.homelab.devncode.it/attachments/17cf047d-400a-4e5c-91a9-c1e6bf2154b5) ![after teleport](https://git.homelab.devncode.it/attachments/95669344-6867-4274-8166-63ef1331c33d) ## How it was tested - **Unit** (`tests/IsoMmo.Client.Core.Tests/MinimapBakerTests.cs`): `Bake` samples the terrain tint at each sampled cell; `CellAt` maps a minimap pixel back to its world cell. - **Visual gate** (Windows, fresh DB): the harness run above. Confirmed the minimap draws **only for admin** (HUD ` · /admin`), `M` toggles it, the wheel zooms, and a click **teleports** — the server logged `tp 7760 5296 -> Teleported` and the client reconciled its self position to the exact clicked cell `(7760,5296)`. - Bug caught + fixed *by* the gate: `GmCommandRequest` must carry the command **without** the leading `/` (the registry looks up `tp`, not `/tp`) — the first click logged `/tp … -> UnknownCommand`. - **Gates**: `dotnet csharpier check .` clean · `dotnet build IsoMmo.slnx` 0 warnings / 0 errors · `dotnet test IsoMmo.slnx` all green (739 tests, incl. the 2 new `MinimapBaker` 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 MonoGame + Client.Core, no OS-specific deps) - [x] Tests added/updated for this change (`MinimapBakerTests`) - [x] Linked the related issue (#237) and its Definition of Done is met
panda merged commit beeb8a1725 into main 2026-08-01 19:17:53 +02:00
panda deleted branch feat/admin-minimap 2026-08-01 19:17:53 +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!244
No description provided.