Repository navigation
Address Discord feedback: Reforged skin data, custom model rendering, shortcuts, terrain palette - #32
Merged
Merged
Conversation
…me/model Reforged's World Editor splits per-map object overrides across two tables per kind: war3map.w3* holds gameplay edits, war3mapSkin.w3* holds the art/skin overrides (Name unam, Model File umdl, Icon uico, Tooltip utip). wc3-forge loaded only the primary half, so a custom Peasant-based unit loaded the right row COUNT (from w3u) but displayed the base "Peasant" name + default model — its real name/model/icon live only in the never-read war3mapSkin.w3u. Session.Open now reads the war3mapSkin.w3* companion for every registered kind (read-only, keyed by kind) and MergedObjects layers it UNDER the primary shadow: primary wins on any field it sets; the skin fills the art fields the primary leaves unset. This is faithful for real maps (name/model live only in the skin table) and keeps the edit path coherent — edits route to the primary table and are never masked by the skin overlay. The skin tables are never marked dirty, so Save preserves them verbatim via the lossless copy-through. Adds objects_skin_test.go covering the overlay (name+model surface) and the primary-wins precedence. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HdJMLPgZf25tirfS26CobN
The 3D viewport's unit merge (mergeUnitIndex/applyUnitOverrides) only carried name + icon overrides, never the model file — so a custom unit that swaps its "Art - Model File" (e.g. a Peasant-based unit using the Sylvanas model) rendered with the base type's model, the exact mismatch users saw vs the World Editor. Doodads already handled this via applyDoodadOverrides; units just missed the `case "file"`. - unitFieldMap: map umdl -> file and usca -> modelscale. - applyUnitOverrides: set the model file (extension-stripped to the stem placeUnit expects) and model scale from the override. - mergeUnitIndex: layer the war3mapSkin.w3* companion first, then the primary war3map.w3* on top (same primary-wins precedence as MergedObjects), so a custom unit's umdl — which usually lives only in the skin table — flows through to the renderer. - scene-instances: the unit type index is now per-map (it folds in this map's overrides), so drop the process-wide cache on each loadMap and re-fetch — otherwise the fix would never surface. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HdJMLPgZf25tirfS26CobN
The File/menu advertised F4 (Trigger Editor) and F6 (Object Editor) but the keys were never wired — pressing them did nothing. World Editor veterans also had no discoverable list of what shortcuts exist. - Wire the advertised keys: F4 -> Trigger Editor, F6 -> Object Editor. - Add F2/F3/F8 to switch the viewport editor mode (Doodad / Terrain / Region), matching the existing Tab-cycle and the header mode buttons. - Add a keyboard-shortcuts cheat sheet overlay toggled by '?' (Shift+/), a Help-menu entry, and Escape / backdrop / × to dismiss. Lists every binding — the single highest-value discoverability fix for a WE veteran. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HdJMLPgZf25tirfS26CobN
The terrain palette mounts already-open, but refresh() only ran from the FAB toggle or a map-changed event — and map-changed has already fired by the time the user enters Terrain mode. So on first entry the grid stayed empty and showed "No ground tiles." on a map full of terrain (the exact symptom a user reported). - Call refresh() on mount so the tiles load the first time Terrain mode opens. - Distinguish the empty-grid reasons instead of always claiming "No ground tiles.": "This map has no terrain file (war3map.w3e)." when GetTerrain reports no terrain, vs "Couldn't load tiles." with a Retry on an unexpected failure. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HdJMLPgZf25tirfS26CobN
The "file" column is shared across several unit FourCCs, so a per-map Model File override (umdl) is stored under its own FourCC-keyed slot (storeCol), not under "file". The preview's unitModelPath only read "file", so a custom-skin unit's 3D preview kept showing the base model even though the override was loaded (the list name + the model field value were already correct). Check the "umdl" slot first, falling through to the stock file/file:hd/file:sd columns otherwise. Verified end-to-end on Enfo FFB v2.64f: N01O "Lord of the Everlasting Flame" (base Firelord) preview model_path now resolves to war3mapImported\HeroFlameLord instead of the stock Firelord path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HdJMLPgZf25tirfS26CobN
…s, terrain Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HdJMLPgZf25tirfS26CobN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses four issues from a Discord user testing wc3-forge against a heavily-customized Reforged map. All four were reproduced/root-caused in the source; two were confirmed data bugs (not just World-Editor-familiarity gaps).
1. Custom units all showed as base "Peasant" (name/model/icon) — confirmed bug
Reforged splits per-map object overrides across two tables per kind:
war3map.w3*(gameplay) andwar3mapSkin.w3*(art/skin: Nameunam, Model Fileumdl, Iconuico, Tooltiputip). wc3-forge read only the primary half, so custom units loaded the right row count (from w3u) but displayed the base name + default model — the real name/model/icon live only in the never-readwar3mapSkin.w3u.Session.Opennow reads thewar3mapSkin.w3*companion for every kind (read-only, keyed by kind).MergedObjectslayers it under the primary shadow (primary wins on any field it sets; skin fills the art fields the primary leaves unset).objects_skin_test.gocovers the overlay + primary-wins precedence.Precedence note (for review): "primary wins, skin fills gaps" is faithful for real maps (name/model live only in the skin table) and keeps the edit path coherent — edits route to
war3map.w3uand are never masked by the skin overlay. Writing edits back into the skin table (full WE round-trip semantics) is intentionally left as a follow-up.2. Placed units rendered with the wrong (base) model — confirmed bug
Separate code path from #1: the viewport's unit merge (
typeindex.go) carried only name + icon, never the model file, so custom-skin units drew the base model. Doodads already did this correctly.unitFieldMap:umdl → file,usca → modelscale;applyUnitOverridessets the model (extension-stripped) + scale.mergeUnitIndexlayers the skin companion then the primary (same precedence as feat: native macOS support (needs Windows regression triage) #1).scene-instances.tsdrops the process-wide cache on eachloadMap(it was cached for the process lifetime, which would have hidden the fix). (Tintuclr/g/bdeliberately skipped for now to avoid a 0-vs-255 default regression.)3. F4–F12 did nothing; the menu advertised dead F4/F6 labels
?/ Help menu; Esc/backdrop/× to close) — the discoverable index a WE veteran reaches for.4. Terrain palette showed "No ground tiles" on a map full of terrain
Root cause turned out to be a missing mount-fetch (not the folder-extract theory): the panel mounts already-open but
refresh()only ran from the FAB toggle or amap-changedevent that had already fired before Terrain mode was entered.refresh()now runs on mount.Verification
go build ./...,go vet ./...clean;go test ./...— all packages pass except a pre-existingmpqfixture-drift test (TestExtractMatchesStormLib_survival, unrelated personal fixture, fails identically onmain).frontend:npm run check(0 errors) +npm run build(green).🤖 Generated with Claude Code