base exe patch moves the per-chapter coin and flag arrays into free .data space (128 entries), so every testlevel chapter is safe (revision 2, caches rebuilt once); new projects start on a free chapter from 32, manual shows number ranges, texture swatch caches follow texture edits, stray levelbau.md.orig removed

This commit is contained in:
MineTec committed 2026-11-07 15:52:00 +01:00
1 parent d6b852a1b6
commit 00b2880d67
24 files changed
+376 -364

No files matched your search

+49 -5
View File
@@ -64,12 +64,56 @@ secrets); the arena adds its dynamic coins (alligator hit/death coins + 5 exit b
Play-tests/exports of an old project: `migrate` (2..19 → 32..49, 20..31 → 32..43).
* The chapter options are choices (level: 1, 32–49; arena: 32–49, default 49); a stored old value is
invalid and falls back to the default (ModOptions).
* Editor: New level / Level settings spinners only offer usable chapters.
* Editor: New level / Level settings spinners only offer usable chapters. The empty template
(`Templates.makeEmpty`) defaults to 32; New level and CLI `--editor-new` take the first chapter
from 32 no project in the levels folder uses (`LevelProjects.nextFreeChapter`).
![chapter option](img/mods/testlevel_chapter_option.jpg)
## Not fixed
## Fix: base exe patch relocates both arrays (ExePatcher.REVISION 2, 2026-11-07)
* The map lets the player pick any unlocked world-9 chapter; empty ones are linked to an installed
world-9 WAD (ModManager), so playing e.g. chapter 9 from the map still clobbers progress. Unlocking
chapter 32+ unlocks 2–31 on the map too.
`ExePatcher.relocateLevelRecords` (part of the always-applied base patch: `ExePatcher.patch` for
the installer, `ExePatcher.changes` replayed as owner "base" in `ModManager.baseExe`) moves both
arrays to a 128-entry buffer (index ≤ 9·6 + 49 = 103) in the slack after .data's VirtualSize:
.data ends at 0x6DB935, the page at 0x6DC000 (.idata follows), so coins u32[128] at **0x6DB940**,
flags u8[128] at **0x6DBB40** (zero-filled and RW, mapped with .data's last page; no new section,
no code). Every absolute address of the arrays in .text is rewritten (whole-file scan of
0x584EC8–0x584EFE / 0x584F1C–0x584FF4: no other references, none in .data):
| Old | New | Sites (operand VA) |
|---|---|---|
| 0x584F1C coins | 0x6DB940 | tally 0x40DE67, KSV load 0x41C72A / save 0x41C8FB, new game 0x41CA6B, level start 0x41CBCC, HUD 0x426AC2 / 0x426D43 / 0x426E08, endLevel 0x54D6BA, levelRecord ptr 0x550BC5, 0x55223E |
| 0x584FF4 coin loop end (`cmp eax, imm; jl`) | 0x6DBA18 | 0x41C74B, 0x41C91A (0x584FF4 itself is also counter var 0xC0 – those uses stay) |
| 0x584EC8 flags | 0x6DBB40 | tally 0x40DEA1 / 0x40DEC9, KSV 0x41C65C / 0x41C832, new game 0x41CA64 (rep stosd 54 bytes), collectible 0x42706B, endLevel 0x54D6E3 / 0x54D708 / 0x54D70F |
| 0x584ECE flags from world 1 | 0x6DBB46 | map icons 0x41B724 / 0x41B79C / 0x41B7EE / 0x54A75E, gold count 0x41CD7B |
| 0x584EFE flag loop end | 0x6DBB76 | KSV 0x41C6D6 / 0x41C8AF, gold count 0x41CD9B |
Worlds 0–8 behave as before (KSV keeps the first 54 entries; the rest is never saved). World-9
flags are not cleared by "new game" (only the 54 saved bytes are) – they only affect the map's
collectible/gold icons of TestLevel chapters within one game session. If the counts of these
references differ (other exe build) the relocation is skipped as a whole. Test: `ExePatcherTest`.
**Effect:** every world-9 chapter is harmless in LlamaMod's groove.exe, so the remaining holes are
closed without restricting the map: picking an empty (linked) chapter like 9 on the world map,
chapters 2–31 that unlock together with 32+, and Boot to level on chapters 2–31 (its option keeps
1–49). Not linking empty chapters is no option: a missing WAD crashes the map ("Couldnt load wad",
`ModManager.world9Fixup`). Mod levels still only use 1 and 32–49 (no migration churn; also safe
with an exe that has not been rebuilt yet after the update).
Verified in game (apptest :24, 2026-11-07):
* A/B, Test World on, map cursor world 9 chapter 9 (the linked empty chapter), start, pause →
quit to the map: old jar (base REVISION 1) → map "°p / Kapitel 0 / 14384" (progress zeroed by the
level start alone); new → "TestLevel / Kapitel 9 / 237" (237 = garbage static coin total, cosmetic).
![chapter 9 before/after](img/mods/testlevel_ch9_fixed.jpg)
* Arena (test mod) on chapter 9, 2 coins collected (HUD 2 / 12), quit to the map → map fine.
* Save with world-1 chapter 1 flags = 3 and gold count 2: slot menu "Goldmünzen 2", the map shows
the collectible and gold icons of Village chapter 1 (KSV load loop + map reads relocated).
* Not verified in game: the KSV save loop after finishing a level (same patch shape as the load
loop, covered by the unit test).
## Before the fix
* The map let the player pick any unlocked world-9 chapter; empty ones are linked to an installed
world-9 WAD (ModManager), so playing e.g. chapter 9 from the map still clobbered progress. Unlocking
chapter 32+ unlocks 2–31 on the map too. Fixed by the relocation above.