# New Maps Import — Design (Pilot: Arkania / World 83) **Date:** 2026-07-19 **Status:** Approved (design), pending implementation plan **Scope of this spec:** Import ONE pilot map (Arkania, world index 83) end-to-end across server (OpenMU), PC client, and web admin panel. The other four maps (Acheron 84, Debenter 85, Uruk 86, Ferea 87) and the mobile client are explicitly out of scope for the pilot and will be replicated from the proven pilot template in follow-up work. ## Background A third-party map pack provides 5 maps with both client and server assets: - **Source:** `C:\Users\efpa\Downloads\Arkania Acheron Debenter Uruk Ferea\Arkania Acheron Debenter Uruk Ferea` - **Client Side/Data:** `World83-87` (terrain: `EncTerrain8N.att/.map/.obj`, `TerrainHeight.OZB`, `TerrainLight.OZJ`, tile textures, `minimap.map`), `Object83-87` (object BMD models + textures), `Local/Eng` (`ImgsMapName/*.OZT` map-name images, `Minimap/*.bmd`, `movereq_eng.bmd`). - **Server Side/Data:** `MapManager.txt` (classic C++ MuServer map config — reference only), `Move/Gate.txt`, `Move.txt`, `MoveSummon.txt` (warp gates — reference only), `Terrain/Terrain83-87.att` (walkability/safezone attributes). The server-side files are **classic C++ MuServer format** and are NOT consumed by OpenMU — except the `.att` terrain files, which match OpenMU's terrain resource format exactly. ### Key technical findings (verified) 1. **Terrain is a drop-in for OpenMU.** OpenMU loads map terrain via `GameMapDefinition.TerrainData`, populated by `_mapDefinition.UpdateTerrainFromResources(TerrainVersionPrefix)` in `BaseMapInitializer`, from an embedded resource `Resources/Terrain{Number}.att`. The pack's server `Terrain83.att` is **65539 bytes, header `00 ff ff 04`** — byte-for-byte the same format as OpenMU's existing `Resources/Terrain1.att` (65539, `00 ff ff 04`). The client's `EncTerrain83.att` (65540, encrypted) is NOT what the server wants; the server-side `.att` is. 2. **Indices 82-87 are free** in the current OpenMU (AdamuSw) map set — no collision at 83. 3. **Web admin panel needs no code changes.** Once a `GameMapDefinition` (number 83) exists in the DB, it appears automatically in: - `/edit-config-grid/GameMapDefinition` (GameMaps CRUD) - `/map-editor` → visual `MapEditor` (renders terrain from `TerrainData`; `CreateNewSpawnArea`, `CreateNewEnterGate`, `CreateNewExitGate`, duplicate/remove/undo/save) - `/edit-config-grid/WarpInfo` (`/move` warp list), `/edit-config-grid/MonsterDefinition` (monsters) 4. **Monster spawns / NPCs are NOT in the pack.** The seeded map is intentionally EMPTY (scenery + walkable + safezone only). Spawns, NPCs and gates are added by the user via the web MapEditor. 5. **Index→name ambiguity.** Pack folders are World83-87 (no World82). `MapManager.txt` labels 82=Arkania,83=Acheron,…,87=TeamvsTeam (off-by-one / stock reference). The pack's own title order ("Arkania Acheron Debenter Uruk Ferea") + available folders (83-87) imply **83=Arkania, 84=Acheron, 85=Debenter, 86=Uruk, 87=Ferea**. Pilot uses **World83 = Arkania**, to be confirmed against the pack screenshots during implementation. ## Chosen approach **Approach A — OpenMU-native C# map initializer + terrain resource + DB update-plugin.** This mirrors every existing OpenMU map and the proven Imperial-items dual-path pattern (see `android-add-new-weapon-item`). Rejected alternatives: (B) pure-panel creation — not viable, the 65KB `TerrainData` byte[] cannot be entered via a web form; (C) build a C++→OpenMU map converter to use the MapEditor Import — unnecessary work for a pilot. ## Components / changes Server repo: `AdamuSw` (Gitea, branch off `main`). 1. **Terrain resource** — copy pack `Server Side/Data/Terrain/Terrain83.att` → `src/Persistence/Initialization/Resources/Terrain83.att`. Verify it is included as an embedded resource by the `.csproj` (the `Resources/*.att` glob); add explicitly if not globbed. 2. **Map initializer** — `src/Persistence/Initialization/VersionSeasonSix/Maps/Arkania.cs`: - `Number => 83` - `Name => "Arkania"` - `TerrainVersionPrefix => string.Empty` - Safezone / spawn gate as required by `BaseMapInitializer` (minimal; a single safe spawn gate so players don't spawn on a blocked tile). - Empty `CreateMonsterSpawns` / NPC init (spawns added later via panel). - Follow the existing map-class pattern (many inherit a `Version075.Maps.*` base; Arkania is new so it derives from `BaseMapInitializer` directly, like other SeasonSix-only maps). 3. **Registration (fresh seed)** — add `Arkania` to the map initializer list so a zero DB seeds it (alongside `Weapons.Initialize()`-style wiring in the SeasonSix data-initialization). 4. **DB update-plugin (existing DB)** — `src/Persistence/Initialization/Updates/AddArkaniaMapUpdateSeason6.cs`: - `UpdateVersion` = next free number (after the Imperial `95`). - Idempotency guard: if a map with `Number == 83` already exists, skip. - Creates the map by invoking the same logic as the initializer. - Applied at runtime only via **AdminPanel → Updates** (per the Imperial finding; `DataUpdateService` is only triggered there). Do NOT call `SaveChanges` inside the plugin. 5. **Access / warp (for testing)** — a `WarpInfo` entry ("Arkania", target map 83, coordinates on a safe tile, level/zen cost) so the map is reachable via `/move Arkania`, plus an entrance `ExitGate`. May be seeded or added via panel; seeding it keeps the pilot self-contained for verification. 6. **PC client** — copy `World83`, `Object83`, and the `Local/Eng` additions (`ImgsMapName/Arkania.OZT`, `Minimap/Minimap_World83_eng.bmd` if present, merge `movereq_eng.bmd`) into `D:\AdaMu\AdaMu\Data`. Verify the MUnique engine supports world index 83 (terrain/object loading is generic; if a world-index cap or per-index table blocks it, add support in `vendor/MuMain` source and rebuild `Main.exe` per `pc-munique-client-build`). ## Data flow Server loads map 83 from `GameConfiguration` → `UpdateTerrainFromResources` decodes `Terrain83.att` into walkable/safezone grid → player issues `/move Arkania` (or uses the entrance gate) → server places them on the safe spawn tile of map 83 → PC client renders `Data/World83` (terrain + objects) → empty but walkable map. In the web panel, `MapEditor` renders the same terrain from `TerrainData`; the user places `MonsterSpawnArea`/gates/NPCs and saves → they take effect on the live server. ## Verification 1. **Server build:** `docker build -f Startup/Dockerfile -t adamu-openmu:dev .` succeeds; map 83 present in built config (symbol/log check). Local `dotnet build` is expected to fail at the source-gen pre-step (normal, per Imperial notes). 2. **Web:** map "Arkania" appears in `/edit-config-grid/GameMapDefinition`; `/map-editor` renders its terrain (not blank). 3. **PC client:** `/move Arkania` enters the map; terrain and objects render; no crash; safezone correct; player can walk. 4. Only after all three pass is the pilot considered done. ## Out of scope (follow-up, after pilot proven) - Maps 84-87 (Acheron/Debenter/Uruk/Ferea) — same template, replicated. - Mobile client asset import + APK considerations. - Authoring actual monster spawns / NPCs / drops (done by the user via panel; not part of the seed). - Any C++→OpenMU map converter. ## Risks - **Index/name mismatch** → wrong map name shown. Mitigation: confirm World83 identity against pack screenshots before finalizing `Name`. - **Engine world-index support** on the MUnique client for index 83 → if unsupported, requires a `vendor/MuMain` change + rebuild. Low likelihood (loading is data-driven) but flagged. - **Terrain resource not globbed** by the csproj → map loads with empty terrain. Mitigation: verify embedded-resource inclusion during step 1.