Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS

Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
This commit is contained in:
Cyd
2026-06-24 21:28:16 -05:00
commit 2b8ca921cb
66341 changed files with 7923174 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
# BattleTech: FireStorm — Git attributes (full-mirror repo)
# Legacy Windows tree: preserve bytes as-is (git config core.autocrlf=false).
# Strategy: route ALL binary file types to Git LFS so the git history stays lean,
# while plain-text source/scripts/headers stay in normal git for real diffs.
# Anything binary NOT listed here still commits fine (just not LFS-optimized) — the
# post-stage size check catches large stragglers.
# ---- Game/art assets ----
*.tga filter=lfs diff=lfs merge=lfs -text
*.bmp filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.raw filter=lfs diff=lfs merge=lfs -text
*.ico filter=lfs diff=lfs merge=lfs -text
*.cur filter=lfs diff=lfs merge=lfs -text
*.erf filter=lfs diff=lfs merge=lfs -text
*.bid filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.gaf filter=lfs diff=lfs merge=lfs -text
*.material filter=lfs diff=lfs merge=lfs -text
*.igdata filter=lfs diff=lfs merge=lfs -text
*.mw4anim filter=lfs diff=lfs merge=lfs -text
*.mw4 filter=lfs diff=lfs merge=lfs -text
*.d3f filter=lfs diff=lfs merge=lfs -text
*.ebf filter=lfs diff=lfs merge=lfs -text
*.obb filter=lfs diff=lfs merge=lfs -text
*.pkg filter=lfs diff=lfs merge=lfs -text
*.256 filter=lfs diff=lfs merge=lfs -text
*.016 filter=lfs diff=lfs merge=lfs -text
# ---- Audio / video ----
*.wav filter=lfs diff=lfs merge=lfs -text
*.avi filter=lfs diff=lfs merge=lfs -text
*.mpg filter=lfs diff=lfs merge=lfs -text
*.mp3 filter=lfs diff=lfs merge=lfs -text
*.ogg filter=lfs diff=lfs merge=lfs -text
# ---- Binaries / build outputs / toolchain ----
*.exe filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text
*.ocx filter=lfs diff=lfs merge=lfs -text
*.sys filter=lfs diff=lfs merge=lfs -text
*.lib filter=lfs diff=lfs merge=lfs -text
*.obj filter=lfs diff=lfs merge=lfs -text
*.pch filter=lfs diff=lfs merge=lfs -text
*.pdb filter=lfs diff=lfs merge=lfs -text
*.idb filter=lfs diff=lfs merge=lfs -text
*.ilk filter=lfs diff=lfs merge=lfs -text
*.exp filter=lfs diff=lfs merge=lfs -text
*.res filter=lfs diff=lfs merge=lfs -text
*.sbr filter=lfs diff=lfs merge=lfs -text
*.bsc filter=lfs diff=lfs merge=lfs -text
*.tlb filter=lfs diff=lfs merge=lfs -text
*.ncb filter=lfs diff=lfs merge=lfs -text
*.opt filter=lfs diff=lfs merge=lfs -text
*.aps filter=lfs diff=lfs merge=lfs -text
# ---- Archives ----
*.zip filter=lfs diff=lfs merge=lfs -text
*.cab filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.7z filter=lfs diff=lfs merge=lfs -text
# ---- Fonts / help / office ----
*.ttf filter=lfs diff=lfs merge=lfs -text
*.fon filter=lfs diff=lfs merge=lfs -text
*.otf filter=lfs diff=lfs merge=lfs -text
*.hlp filter=lfs diff=lfs merge=lfs -text
*.chm filter=lfs diff=lfs merge=lfs -text
*.gid filter=lfs diff=lfs merge=lfs -text
*.xls filter=lfs diff=lfs merge=lfs -text
*.xlsx filter=lfs diff=lfs merge=lfs -text
*.doc filter=lfs diff=lfs merge=lfs -text
*.mdb filter=lfs diff=lfs merge=lfs -text
*.db filter=lfs diff=lfs merge=lfs -text
*.mr filter=lfs diff=lfs merge=lfs -text
# NOTE: intentionally NO `text`/eol attributes. This is a byte-for-byte mirror — with
# core.autocrlf=false and no text attrs, git stores/restores text files exactly as-is
# (no LF<->CRLF conversion) and still auto-detects text for diffs. Do not add `text` here.
+8
View File
@@ -0,0 +1,8 @@
# BattleTech: FireStorm — full disaster-recovery mirror.
# NOTHING is excluded on purpose: this repo is a complete, self-hosted (local Gitea)
# snapshot of c:\VWE so that one `git clone`/`git pull` reconstitutes a working machine
# (source + assets + VC6 toolchain + SDKs + build outputs + deployed game + archive).
# Large binaries are routed to Git LFS via .gitattributes; they are NOT excluded.
#
# (Intentionally empty. Add entries here only for truly machine-local, non-portable
# state you decide you never want mirrored.)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+561
View File
@@ -0,0 +1,561 @@
# BattleTech: FireStorm — Project Notes (CLAUDE.md)
Working notes for Claude Code. Updated as work progresses.
## What this project is
A total-conversion / expansion ("FireStorm") built on the **MechWarrior 4** game
engine (the *Gameleap* engine, v5.03), using Microsoft's **GameOS / GOS**
technology (same lineage as MechWarrior 4 and MechCommander 2). ~60k files mixing
C++ engine source, an asset/content pipeline, and game-design spreadsheets.
Toolchain is late-90s/early-2000s **Visual C++ 6.0** — no git, no modern build system.
## Repo layout (top level)
> **2026-06-23 cleanup:** unused/duplicate trees archived to **`_UNUSED\`** to reduce newcomer
> confusion (Gameleap\{Archive,Drivers,EditorDocs,Notes,batch,utilities}; GameleapCode5_03\{Content,hsh};
> resource_fullbak). Build paths untouched. See **`README.md`** for the orienting layout map.
> Build/deploy uses only: `Gameleap\mw4` (data), `Gameleap\code` (code+binaries), `build-env` (toolchain).
- **`Gameleap\code/`** — THE BUILD TARGET. Engine + game source + content. *(confirmed by user)*
(Its `Content\` + `hsh\` were stale 2005 duplicates → moved to `_UNUSED\`; live data is `Gameleap\mw4`.)
- **`Gameleap/`** — only **`mw4/`** is used (game-data source for resource packing). Former siblings
(editor docs, drivers, batch tools, runtime env) were historical/utility → moved to `_UNUSED\`.
- **`BTFrstrm/`** — FireStorm design data: mech stat workbooks (`MechInfo_5.04.xls`, `scriptaddmech.xls`).
- **`Finished HUDS from J&J/`** — per-mech HUD art (MFD + Radar) for ~15 'Mechs.
### Inside `Gameleap\code/`
- `CoreTech/` — reusable engine layer (GameOS, gosFX, GOSScript, MLR renderer, Network, Stuff, Language, blade) + Tools.
- `mw4/Code/` — the game itself. `mw4/Code/MW4/` = ~590 files; AI subsystem dominates (~65 `AI_*` files).
- `mw4/Libraries/` — mw4-local libs (Adept, Compost, ElementRenderer, gosfx, ImageLib, MLR, server, stuff, **stlport**).
- `Content/` — game content: `ABLScripts/` (ABL scripting language), Defines, Subsystems, Tables, `.build` files.
- `rel.bin/` `dbg.bin/` `pro.bin/`**build OUTPUT folders** (libs/exe/dll land here). Generated, not source.
---
## ✅ STEP 1: Build process reconstruction — COMPLETE
### Toolchain
- **Compiler/IDE:** Visual C++ 6.0 / MSDev98 (all `.dsw`/`.dsp` are "Format Version 6.00").
- **STL:** bundled **STLport** at `mw4/Libraries/stlport/` (custom, build it first).
- **External SDKs (NOT bundled)** — exact reqs from `CoreTech/Libraries/GameOS/pch.hpp`:
- **DirectX 7.0 SDK** — headers must be **FIRST** in include order
(`#if DIRECTDRAW_VERSION != 0x0700 → #error`; uses ddraw7, dinput7, d3d.h immediate mode, dplay).
- **DirectX Media 6.0 SDK** — DirectShow video (`amstream.h`, `__IDDrawExclModeVideo`).
- **EAX SDK** (Creative `eax.h`) — audio.
- **DirectX 8 link libs** (`d3d8.lib d3dx8.lib dinput8.lib dxguid.lib`) — used by standalone tools
(Gos2Light/Text, HighTide, etc.).
- NOTE: SDK paths are NOT in the `.dsp` files — they come from the IDE's global
**Tools → Options → Directories**, which is why DX7-first ordering matters.
- Compiler flags of note: `/G6 /Zp4` (struct packing 4 — must be consistent across all libs),
`/MD` runtime (Release), `/MDd` (Debug). Mismatched packing/runtime = link/crash.
### Locating VC6 + SDKs on the ORIGINAL DISK IMAGE
- **VC6 / MSDev98:** `C:\Program Files\Microsoft Visual Studio\`
- `VC98\Bin\` (cl.exe, link.exe, `VCVARS32.BAT`), `VC98\Include`, `VC98\Lib`, `VC98\MFC`
- `Common\MSDev98\Bin\MSDEV.EXE` (IDE + command-line builder).
- **DirectX/Media/EAX SDKs** — check these era-typical roots:
- DX7 SDK: `C:\DXSDK\`, `C:\mssdk\`, or `C:\DX7SDK\`
- DX8 SDK: `C:\DXSDK\` or `C:\Program Files\Microsoft DirectX 8*SDK\`
- DX Media 6: `C:\DXMedia\` or `C:\DXMEDIASDK\`
- EAX SDK: under `C:\` or the Creative/SB SDK folder.
- **⭐ Most valuable artifact — the IDE directory ordering** (reproduces the env exactly).
Load the build user's `NTUSER.DAT` and read:
`HKCU\Software\Microsoft\DevStudio\6.0\Build System\Components\Platforms\Win32 (x86)\Directories`
→ values **"Include Dirs", "Library Dirs", "Path Dirs"** (ordered; copy verbatim).
Also: `HKLM\SOFTWARE\Microsoft\VisualStudio\6.0`, `HKLM\SOFTWARE\Microsoft\DirectX` (records DX version).
- **Signature-file search on a mounted image:** `MSDEV.EXE`/`VCVARS32.BAT` → VC6;
`ddraw.h`/`d3d.h`/`dinput.h` → DX7 includes (verify `DIRECTDRAW_VERSION 0x0700`);
`amstream.h` → DX Media 6; `d3dx8.lib`/`eax.h` → DX8 / EAX SDK.
### Master workspace & final target
- **Workspace:** `Gameleap\code/mw4/Code/MechWarrior4.dsw` (the modern/current one).
- Self-contained: all 24 sub-projects verified present on disk, spanning both
`mw4/Libraries` and `CoreTech/Libraries`.
- **`MechWarrior4Build.dsw`** = LEGACY/alternate (uses old `MW4Gos`, `Network`, `GamePlatform`,
`MW4GameEd` v1). Do not use; superseded by `MechWarrior4.dsw`.
- **Final game target:** project **`MW4Application`** → `MW4.exe`.
- **Editor target:** project **`MW4GameEd2`** → editor exe (separate).
### Build configurations → output paths (from MW4Application.dsp)
| Config | Defines | Output |
|---------|------------------------|-------------------|
| Debug | `_DEBUG _ARMOR` `/MDd` | `dbg.bin/MW4.exe` |
| Armor | `NDEBUG _ARMOR` `/Zi` | `arm.bin/MW4.exe` |
| Profile | `NDEBUG` profiling | `rel.bin/MW4pro.exe` |
| Release | `RELEASE NDEBUG` | `rel.bin/MW4.exe` |
| icecap | `_ICECAP` | `ice.bin/` |
A prior successful **Release build exists** in `rel.bin/` (MW4.exe, MW4pro.exe, all `.lib`s,
Launcher.exe, ctcls.dll, MissionLang.dll, ScriptStrings.dll, autoconfig.exe, mw4print.exe).
`arm.bin/` and `ice.bin/` are absent (those configs were never built here).
### Build dependency order (topological, from MechWarrior4.dsw)
1. **`stlport`** — foundation, no deps. Build first.
2. **Leaf libs** (depend only on stlport / nothing): `GameOS`, `Stuff`, `MLR`, `gosFX`,
`ImageLib`, `Compost`, `GOSScript`, `ElementRenderer`, `Adept`, `server`,
`DLLPlatform`, `MFCPlatform`, `GamePlatformNoMain`, `ctcls`.
3. **`MW4`** — the game library.
4. **Helper exes/dlls:** `Launcher`, `autoconfig`, `mw4print`, `MissionLang`,
`ScriptStrings`, `MW4DedicatedUI`.
5. **`MW4Application`** — links everything into `MW4.exe`. *(Set as Active Project.)*
VC6 honors these dependencies automatically via the `.dsw` "Project Dependency" records,
so a single "Build" of MW4Application pulls the whole chain in order.
### How to build
- **IDE:** Open `mw4/Code/MechWarrior4.dsw` in VC6 → set **MW4Application** as Active Project
→ pick config (Win32 Debug / Release) → Build.
- **Command line (VC6):**
`msdev MechWarrior4.dsw /MAKE "MW4Application - Win32 Debug"`
(or `"... - Win32 Release"`). Add `/REBUILD` for a clean build.
### How to RUN (the `mw4/*.bat` scripts are LAUNCH, not compile)
- `game_dbg.bat` etc. just run the exe: `binaries\mw4\MW4_dbg -armorlevel 3 -nobuild`.
- `-build` = (re)build game resource `.erf`s from source assets at startup; `-nobuild` = skip.
- `bldresources_game_dbg.bat` = run with `-build` to regenerate resources.
- `editor_dbg.bat` = launch the editor (`MW4Ed2_d`).
### ⚠️ Open discrepancies to resolve before a real build
1. **Output path vs. launch path mismatch:** `.dsp` files emit to `dbg.bin/MW4.exe` /
`rel.bin/MW4.exe`, but the `game_*.bat` launchers point at `binaries\mw4\MW4_dbg.exe`.
There is a missing copy/deploy step (or the bats target a different deployed layout).
`mw4/Binaries/` currently only holds `3DSPlug-ins/`. **TODO: find/recreate the deploy step.**
2. `FullExport.batch` references dead studio network paths (`\\aas1\...`, `d:\ContentExport\`).
That's the *art* export pipeline, irrelevant to the code build.
---
## ✅ STEP 2: Toolchain extracted from original disk image (E:\) — COMPLETE
Original build machine image mounted at `E:\`. Build user = **`jeff`**.
Everything needed is now copied into **`build-env/`** (self-contained):
- **`build-env/VisualStudio6/`** ← `E:\Program Files\Microsoft Visual Studio` (VC6: CL, LINK, NMAKE, MSDEV).
- **`build-env/dx7asdk/`** ← `E:\Code\dx7asdk` (DirectX **7.0a** SDK; `ddraw.h` = `DIRECTDRAW_VERSION 0x0700` ✓).
- **`build-env/DXMedia/`** ← `E:\Code\DXMedia` (DirectX **Media 6.0** SDK; amstream/control/strmif + libs).
- **`build-env/setup-mw4-build.bat`** + **`README.md`** (generated; build instructions).
Resolutions to prior open items:
- **DirectX version pinned:** DX **7.0a** SDK (headers) + DX **Media 6.0** SDK. NOT DX8 for the game.
- **VC6 located & copied:** VC++ 6.0 at `build-env/VisualStudio6/`.
- **EAX:** bundled in repo (`GameOS/Eax.h`); no static `eax.lib` needed (runtime-resolved).
- **DX8 SDK:** absent from image; only blocks 3 standalone tools (Gos2Light/Text, HighTide), not the game/editor.
- **Critical ordering:** DX7 includes MUST precede VC98\INCLUDE (engine `#error` guard); enforced in setup .bat + README.
### ✅ Exact registry directory order RECOVERED (from jeff's NTUSER.DAT)
Key: `HKCU\...\DevStudio\6.0\Build System\Components\Platforms\Win32 (x86)\Directories`
- **Include:** `DXMedia\include → dx7asdk\include → VC98\INCLUDE → VC98\MFC\INCLUDE → VC98\ATL\INCLUDE`
- **Library:** `VC98\LIB → VC98\MFC\LIB` only.
Two verified facts that make this work:
1. `DXMedia\include` has NO core DX headers (DirectShow only) → `ddraw.h` still resolves
from `dx7asdk` before VC98's old one (satisfies the `pch.hpp` 0x0700 guard).
2. The DX/DShow `.lib`s were **copied into `VC98\Lib`** on the original machine (verified
present in our copy: ddraw/dinput/dsound/dxguid/strmiids/quartz/strmbase/amstrmid);
pulled in via `#pragma comment(lib,...)` in `GameOS\guids.cpp`, not the link line.
Captured as **`build-env/vc6-directories.reg`** (rebased to local copies; HKCU import, no admin)
and reflected exactly in **`build-env/setup-mw4-build.bat`**.
### ✅ HKLM VC6 install registration extracted & rebased
Exported jeff's offline `software` hive trees (`Microsoft\VisualStudio\6.0`,
`Microsoft\DevStudio\6.0`) and transformed into **`build-env/vc6-hklm-registration.reg`**:
- Key root redirected `oldsw``HKLM\SOFTWARE\Wow6432Node\...` (32-bit `msdev` on 64-bit Windows
reads HKLM\SOFTWARE redirected to Wow6432Node; HKCU\Software is NOT redirected).
- All paths rebased: `C:\Program Files\Microsoft Visual Studio``build-env\VisualStudio6`;
`C:\Program Files\Common Files\Microsoft Shared``build-env\CommonFiles-MSShared`
(copied `VS98` + `MSDesigners98` so those refs resolve).
- Verified: 0 leftover `oldsw`, 0 un-rebased paths, 202 keys, ProductDir/InstallDir correct.
- Raw exports kept as `build-env/_raw_*.reg` (provenance).
- Import order (ELEVATED): `vc6-hklm-registration.reg` then `vc6-directories.reg`.
---
## ✅ STEP 3: Clean build from source — SUCCESS (game target)
Registry imported (HKLM `vc6-hklm-registration.reg` + HKCU `vc6-directories.reg`), msdev
runs from the copy, and a **full clean rebuild of `MW4Application - Win32 Release` succeeds**:
- 22 projects compiled in dependency order (stlport → GameOS/Stuff/MLR/gosFX/… → MW4 →
helper exes/dlls → MW4Application). **`MW4.exe` — 0 errors**, 384 warnings (normal for VC6).
- Output: `rel.bin\MW4.exe` (~3.64 MB), plus fresh `*.lib`, `Launcher.exe`, `autoconfig.exe`,
`mw4print.exe`, `MissionLang.dll`, `ScriptStrings.dll`, `ctcls.dll`.
- Build is reproducible head-lessly via:
`msdev MechWarrior4.dsw /MAKE "MW4Application - Win32 Release" /REBUILD /OUT <log>`
(run via `Start-Process -Wait`; msdev is a GUI-subsystem app so the shell won't block otherwise).
- Build logs kept in `build-env\build_*.log`.
### ✅ `stlnative` dependency relocated INTO the working tree
`mw4/Libraries/stlport/stl_inc_find.hpp` hardcoded a native-headers path
`<c:\stlnative/##x>` (3 macro defs, the only references in the codebase). STLport wraps a
27 MB snapshot of the VC98 + Platform SDK headers (974 files) restored from the image.
Originally placed at `C:\stlnative`; now **moved into `build-env\stlnative\`** and the 3
macros repointed to `<c:\VWE\build-env\stlnative/##x>`. Verified: with `C:\stlnative`
removed, a full clean rebuild still succeeds (MW4.exe, 0 errors). The build is now
self-contained under `c:\VWE` — no external `C:\stlnative` needed.
---
## ✅ STEP 4: Runnable deployment assembled at `C:\VWE\MW4` — DONE
Rules-based deploy (no image/E: dependency) via **`build-env\deploy-mw4.ps1`**:
- **Result: `C:\VWE\MW4` — 845 files, 895 MB** (target was ~900 MB), with our freshly
built `MW4.exe` (3,637,248 bytes) + all runtime DLLs + prebuilt `resource\*.mw4`.
- Sources (all from working dir): runtime base = `Gameleap\mw4`; binaries = `rel.bin`.
- The old `game_*.bat` assumed a `binaries\mw4\MW4_dbg.exe` layout that the real game
never used — the runnable game has `MW4.exe` at the deployment root. Launch via
**`C:\VWE\MW4\run-mw4.bat`** (resources prebuilt, no `-build` needed).
### Deployment selection rules (the dev tree `Gameleap\mw4` is a ~6 GB bloated superset)
- KEEP whole: `Resource\` (767 MB .mw4 packages), `hsh\` (102 MB), `Assets\`, `Stats\`.
- KEEP subset: `Content\shellscripts\` MINUS `Graphics\` (119 MB source .tga) and
`Original\` (57 MB backups) -> ~9 MB of compiled scripts/.gaf/.d3f.
- KEEP root: runtime `*.dll/*.ini/*.options/*.txt/*.rtf/*.ico/*.016/*.256/...` + `clokspl.exe`.
- DROP: `Content\*` (4.6 GB source except shellscripts), `Movies\` (352 MB), `Notes\`,
`fonts\`, all tool exes (ERF Deluxe, EffectEdit, MapCreator, ResourceBrowser, MW4Ed2, ...).
- OVERLAY: fresh `rel.bin` binaries (MW4.exe, MW4pro.exe, Launcher, autoconfig, mw4print,
MissionLang.dll, ScriptStrings.dll, ctcls.dll).
---
## ✅ STEP 5: Runtime brought up at `C:\VWE\MW4` — RUNS (fullscreen + windowed)
Reference for "working" = **`C:\MW4knowngood`** (NOT `E:\gameleap`, NOT `D:\5.0.8.2_console`
— those are unrelated). Two independent issues had to be fixed; both are now in
`deploy-mw4.ps1` so a fresh deploy is runnable out of the box:
1. **DirectDraw 16-bit compat shim (Win11).** MW4 runs `bitdepth=16`; modern Windows fails
its DirectDraw hardware-surface creation with `DDERR_NODIRECTDRAWHW` unless the
**`DWM8And16BitMitigation`** AppCompat layer is applied to the exe *path*. Our path had a
stray `HIGHDPIAWARE`-only layer that suppressed the auto-shim. Fix: set HKCU layer
`DWM8And16BitMitigation HIGHDPIAWARE` for `C:\VWE\MW4\MW4.exe` (deploy script does this;
matching all-users HKLM `$ DWM8And16BitMitigation` is in `build-env\mw4-compat-hklm.reg`).
Note: AppCompat is keyed on exe PATH, so a copy at a new path needs the layer re-applied.
2. **Dev-only DLLs shadowing system DLLs.** Our rules copied every root `*.dll`, which pulled
in `dbghelp.dll`/`imagehlp.dll` (2003 copies that shadow Windows' system DLLs and break
DirectDraw init) plus tool DLLs `ijl10.dll`, `ctcl.dll`, `Language.oeg.dll`, `Resources.dll`.
known-good has none of these. Fix: deploy script now excludes those 6 by name. Removing
them was what made it run in BOTH fullscreen and windowed.
Diagnostic note: swapping known-good binaries into our deploy still failed *before* the shim
was applied — that proved our rebuilt binaries are NOT the cause (the shim + DLL excludes were).
Final deployment: **`C:\VWE\MW4` = 894 MB, 839 files, DLL set identical to known-good**, running
our freshly built `MW4.exe`.
---
## Resource (`.mw4`) build process — documented & ✅ VERIFIED
Full writeup in **`build-env\RESOURCE-BUILD.md`**. Tested end-to-end 2026-06-11 with our
freshly built `MW4pro.exe` (Profile/LAB_ONLY): minimal `Content\MechWarrior4.build` ->
`resource\restest.mw4` + `.dep` (exit 0); `#VBD` magic + payload confirmed; `.dep` tracks
source; incremental skip/rebuild both verified; Release exe confirmed to ignore `-build`.
Key facts:
- The resource compiler is **inside the game exe**, triggered by the **`-build`** flag,
which is `#ifdef LAB_ONLY` — so **only Debug/Armor/Profile (`MW4_dbg`/`MW4_arm`/`MW4pro.exe`)
can build resources; Release `MW4.exe` cannot**. (That's why `bldresources_game_*.bat`
use the LAB_ONLY exes.)
- Entry point: `MW4Application.cpp` -> `Tool::Instance->BuildResources("Content\MechWarrior4.build",
VER_CONTENTVERSION=63, deps)`; recursive driver `Adept::Tool::BuildResources` /
`ParseBuildFile`; per-type packers in `Adept\Tool.cpp` + `MW4\MWTool.cpp`.
- Input: `Content\MechWarrior4.build` (master tree) -> per-package `.build` manifests
(`[resource\X.mw4]` + `data=`/`instance=`/`file=`/`notation=`/`campaign=`/... entries) ->
source assets under `Content\`. Output: `resource\*.mw4` + `*.dep` (incremental via `.dep`
timestamps + content version). Needs the full ~4.6 GB `Content\` source tree.
## ✅ STEP 6: Editor (`MW4GameEd2`) builds — DONE (with a 1-line source fix)
- Target `MW4GameEd2 - Win32 Release` -> **`rel.bin\MW4Ed2.exe`** (3,973,120 bytes, 0 errors).
MFC app (`Use_MFC 6`); needs `mfc42.dll` (present in deployment) at runtime. Profile config
also exists (-> `pro.bin\MW4Ed2.exe`).
- **Source fix required** (editor source had drifted; shipped `MW4Ed2.exe` is from 2003 and
was never rebuilt against the 2009 code): enum `MPGameTypes` in
`mw4\Code\MW4GameEd2\ObjectManager.h` was **missing `GT_StockCampaign`**, which
`ObjectManager.cpp` references (string map @1013, int map `case 14`). Added the enum member
between `GT_StockSiegeAssault` and `GT_CustomDestruction`. (This is the only repo source edit
beyond the stlnative relocation; both are marked with `[...]` comments in-place.)
- Built incrementally but it was a *full* compile of the editor's own sources (none existed
prior); shared libs reused from the Release game build.
---
## ⚠️ STEP 7: Editor builds + launches + draws UI, then HANGS (viewport spin)
Set up via **`build-env\deploy-editor.ps1`**; launches to window
**"MechWarrior 4 Mission Editor - 05.07.00.00"** and creates its MDI children (Game View,
Object Manager, Overview Window) — but then **spins one CPU core at ~100% with zero memory
growth and a stalled message pump** ("not responding"; 282s CPU / 283s uptime). It's a
busy-loop hang in the editor's real-time 3D viewport/idle loop — a **runtime** compat issue
on modern hardware, NOT a build issue (it compiled, launched, and drew its UI). The game runs
fine (different render path: fullscreen exclusive vs the editor's windowed live viewport).
### ROOT CAUSE FOUND: incomplete dev content + modal-STOP-over-windowed-DDraw
The editor loads/builds the full content tree at startup and **STOPs (fatal) on missing/
inconsistent dev content**, one item at a time:
- `skies\reduex_sky\reduex_night.erf` — misnamed (`Reduex_sky_night.erf`); FIXED by copy.
- `Texture skyfbb1` (referenced by `Content\Skies\fact01_sky\fact01_sky.hint`) — **genuinely
absent** from the dev tree (no file of that name anywhere). The FireStorm dev `Content\`
is an incomplete WIP with real asset gaps.
GameOS's `STOP` pops a **modal dialog**. Build-specific behavior on that dialog:
- **Profile** (LAB_ONLY, lighter opt): shows the STOP dialog cleanly; dismissing it exits.
- **Release** (`/Ox /Og`, no LAB_ONLY): trying to show the modal STOP over the **windowed
DirectDraw** viewport **hangs (100% spin) or crashes (AV)** — a dialog/DDraw interaction
fragility under full optimization. So the earlier "hang/crash" was this same content STOP,
handled badly by the Release build (NOT a separate memory bug as first guessed).
So: **editor compiles + launches correctly; the blocker is incomplete dev content** (a
content-curation task on the project's own unfinished assets, distinct from build/toolchain).
### Option 2 attempted (make content STOPs non-fatal) -> uncovered the REAL bug: heap corruption
- Patched `mw4\Libraries\Adept\ResourceImagePool.cpp:385` (texture-not-found): first tried
`continue` (skip) -> downstream **access violation** (missing texture deref'd later); then a
**placeholder-substitute** (`file_name="content\\textures\\01AACA1.tga"`) -> got PAST the
content STOPs. Both are tagged `[editor degraded-mode]` in-source.
- With content handled, the editor returns to the original symptom: **main UI thread spins at
100% CPU, not responding**. EIP sampling (`Wow64GetThreadContext`) located the spin in a tight
loop inside **`SysWOW64\ntdll.dll`** heap code (~`0x76F73E04`) = **walking a corrupted heap
free-list**. ROOT CAUSE = **heap corruption** (buffer overrun / double-free / use-after-free)
in the editor; it manifests non-deterministically as the ntdll heap-loop HANG or an AV, and
shifts with optimization (Release vs Profile) -> exactly the observed behavior.
- To actually fix: enable **PageHeap** for `MW4Ed2.exe` (registry `Image File Execution
Options\MW4Ed2.exe` GlobalFlag=0x02000000; needs admin) to trap the corrupting write at its
source with the Profile build's symbols, then fix the overrun. This is a deep memory-bug hunt
in old code (the 2003 editor never hit it on XP / with complete content).
- NOTE: `ResourceImagePool.cpp` placeholder patch is a degraded-mode hack; revert if not wanted.
### PageHeap hunt (in progress) — corruption confirmed, but a Heisenbug to pin down
- Enabled full PageHeap via `build-env\mw4ed2-pageheap.reg` (IFEO GlobalFlag=0x02000000,
PageHeapFlags=0x3; off-switch in `mw4ed2-pageheap-off.reg`). Confirmed active (editor mem
45->94 MB). Built `pro.bin\MW4Ed2.map` (added `/map` to the Profile link in MW4GameEd2.dsp,
preferred base 0x00400000) for address->function resolution.
- **With PageHeap + NO debugger: editor reliably AVs (0xC0000005) at ~1 s** = the overrun caught
at the corrupting write (the goal). **But under my PowerShell debug loop it will NOT reproduce**
(many attempts, even with `_NO_DEBUG_HEAP=1`): attaching perturbs heap/timing so the editor
takes a different path and exits without faulting -> classic heap-corruption Heisenbug.
- Conclusion: pinning the exact corrupting instruction needs a REAL debugger that holds heap/
timing steady. Cleanest: install **Debugging Tools for Windows** (`cdb`) and run
`cdb -g -G -c "kb;q" -o MW4Ed2.exe` with PageHeap on -> one-shot symbolicated faulting stack.
Alt: WER LocalDumps (HKLM) -> parse the minidump's exception stream for the faulting EIP ->
map via `MW4Ed2.map` (uncertain: GameOS's UEF may pre-empt WER). The corruption is in the
content-load path (~1 s, texture/sky loading).
- Working dir = proven runtime DLLs from the game deploy (NO `imagehlp`/`dbghelp`) + editor
tool DLLs (`ctcl`/`ijl10`/`Resources`/`Language.oeg`) + MFC + our `MW4Ed2.exe`; the bulk
(`Content\`, `resource\`, `hsh\`) are **directory junctions** to the dev tree
`Gameleap\mw4` (no 5.5 GB copy). Same `DWM8And16BitMitigation` compat shim as the game.
- **Content data fix needed to launch:** `Content\skies.build:109` declares
`File=Skies\reduex_sky\reduex_night.erf`, but the night-sky erf was misnamed
`Reduex_sky_night.erf`. The editor (LAB_ONLY, asserts on missing files) STOPped on it.
Fixed by adding `reduex_night.erf` (copy of `Reduex_sky_night.erf`) in
`Gameleap\mw4\Content\Skies\Reduex_sky\`. (A dev-content naming inconsistency, not a
build/toolchain problem — the editor itself builds+runs correctly.)
---
## ✅ STEP 8: Editor RUNS — root cause was DirectInput, NOT heap corruption (2026-06-22)
Installed **Debugging Tools for Windows** (`cdb` at `C:\Program Files (x86)\Windows Kits\10\
Debuggers\x86\cdb.exe`) and got the first fully-symbolicated faulting stack. **This overturned
the STEP 7 hypothesis:** the crash is NOT content-load heap corruption — it is a **modern-Windows
DirectInput init cascade** during `CMInstall` (GameOS), reproducible and deterministic:
1. **Joystick enumeration heap-corrupts in modern `dinput.dll`.** `CMInstall` ->
`CMCreateJoysticks` -> `wEnumDevices(DIEDFL_ATTACHEDONLY)` -> `CMCreateJoystick7`
(`ControlManager.cpp`). On Win11 the legacy **IDirectInput7** path, when it `Release()`s a
phantom/virtual HID "joystick" (0-axis "misreported device" at line ~602), corrupts the heap
inside `dinput.dll`. Surfaces as `RtlFreeHeap` AV (normal heap) or, under full PageHeap, as a
guard-page over-read in `dinput!DIWdm_InitJoyId` (`[esi+0x44]`). **The PageHeap "AV at ~1s"
from STEP 7 was THIS, mis-attributed to content loading.** The game survives by heap-layout luck.
- **FIX (source):** `CoreTech\Libraries\mfcplatform\MFCPlatform.cpp` `InitGameOS` now sets
`gDisableJoystick=1` (editor/`Platform_MFC` only; the game uses a different platform path and
is unaffected). Chosen over the `/gosnojoystick` switch because in **LAB_ONLY** builds
`WinMain.cpp:~398` shows a help dialog and **exits** if any leftover `/gos` token remains on
the command line — fragile (e.g. cdb perturbs the cmdline -> trips it). Tagged `[editor modern-Windows fix]`.
2. **Mouse `SetCooperativeLevel(NULL, FOREGROUND|NONEXCLUSIVE)` fails 0x80070006.**
`CMCreateMouse` (`Mouse.cpp`) resolves the coop window from `hWindow`, which is **always NULL**
in the editor at `CMInstall` time: the editor passes `pFrame->GameWnd->m_wndView.m_hWnd`, but
`InitSecondaryWindows` (`MainFrm.cpp:173`) only `new`s `CGameFrame` and never `Create()`s it, so
`CGameFrame::OnCreate` (which builds `m_wndView`) hasn't run. XP tolerated a NULL coop window;
modern DirectInput rejects it -> fatal PAUSE. (Keyboard has no coop-level call, so it survived.)
- **FIX (source):** `Mouse.cpp` `CMCreateMouse` falls back to `GetForegroundWindow()`/
`GetDesktopWindow()` with `BACKGROUND|NONEXCLUSIVE` when the resolved window is NULL; the game
path (valid `hWindow`) is unchanged. Tagged `[editor modern-Windows fix]`.
Rebuilt **`MW4GameEd2 - Win32 Profile`** (recompiles GameOS + MFCPlatform, relinks; 0 errors) ->
deployed `pro.bin\MW4Ed2.exe`+`.pdb` to `C:\VWE\MW4Editor`. With both fixes + the content fixes
below, the editor **launches to a live, responsive, idle (0% CPU) main window** ("MechWarrior 4
Mission Editor - 05.07.00.00", ~70 MB) — the old "100% spin / not responding" is GONE. Launch with
just `-armorlevel 3` (no `/gos` flag needed).
### Content-curation fixes (FireStorm WIP dev tree, in `Gameleap\mw4\Content`)
The editor enumerates+loads EVERY mission/map at startup (`ObjMan->BuildResources()`) and STOPs
fatally on the first defect. Fixed (all additive/non-destructive unless noted):
- **`_backup` dev-copy dirs** (files named after the original, not the dir): created the missing
`<dir>.build`/`<dir>.instance` (page `[<dir>]`, unique resource targets):
`Maps\Colsm01_backup`, `Maps\StormCanyonSiege_Backup`, `Missions\Coliseum_backup`.
(Editor compiled these into `resource\maps\colsm01_backup.mw4` etc. — confirms they're valid.)
- **Dangling map refs:** `Missions\EditorTemplate\EditorTemplate.instance` `Map=` arctic01 (exists
nowhere) -> `arctic04`; `Missions\s1s2\s1s2.instance` `Map=` lunar02 -> `lunar01`.
- **Double-nested user mission:** `Missions\PhoenixPalaceSTB\PhoenixPalaceSTB\*` moved up one level
(the files already referenced the top-level path); then its `.instance` `Model=` pointed at
`dropzones\hill.contents` (page `[droppoints]`) -> fixed to `phoenixpalacestb.data` (page `[gamedata]`).
- Scans confirmed scope is small: 0 remaining mission page-name mismatches; 1 dangling map ref
(fixed); arctic01/lunar02 are genuine content gaps absent from ALL installs (dev Resource\Maps
has 46 .mw4 — MORE complete than game-deploy/knowngood's 26 — so launch folder/junctions are correct).
### ✅ 3D viewport FIXED via DDrawCompat (2026-06-22)
Root cause pinned with temporary diagnostics in `SetupMode`/`DirectDrawCreateAllBuffers`
(`DXRasterizer.cpp`, since reverted): every surface (front/back/Z), the clipper, and the
`IDirect3D7` object create fine with a valid `hWindow`, but **`IDirect3D7::CreateDevice` fails
with `0x88760082 = DDERR_INVALIDOBJECT`** for BOTH the hardware HAL (`IID_IDirect3DTnLHalDevice`
-> `IID_IDirect3DHALDevice`) and the Blade software device — i.e. **Win11's legacy DirectDraw does
not support creating a windowed Direct3D7 device** on an offscreen backbuffer (the game avoids
this by using a fullscreen flip-chain). Not a code-flag issue.
**Fix:** dropped **DDrawCompat** (narzoul, v0.7.1, `ddraw.dll`) into `C:\VWE\MW4Editor\` — a
drop-in ddraw/d3d7 reimplementation. With it, `CreateDevice` succeeds and the **Game View/Overview
render** (user-confirmed). Source kept at `build-env\ddrawcompat\ddraw.dll`; `deploy-editor.ps1`
now copies it. The standalone game (`C:\VWE\MW4`, fullscreen) is unaffected and does NOT use it.
**The editor is now fully working: launches, edits, and renders the 3D viewport.**
### ✅ Open-Mission dialog now lists ALL source missions (2026-06-22)
Symptom: editor's File->Open showed only **5** missions. Cause: `COpenMissionDlg::OnInitDialog`
(`OpenMissionDlg.cpp`) listed `Resource\UserMissions\*.mw4` (compiled/published user-mission
packages) — only 5 exist in the dev tree (and **0** in the game deploy `C:\VWE\MW4`, so co-locating
the editor with the game would have shown ZERO, not more). But `CMainFrame::LoadMission` loads from
`Content\Missions\<name>\<name>.Instance`. **Fix:** changed the dialog to enumerate
`Content\Missions\*` subdirectories that contain a matching `<name>.instance` -> now lists all **51**
source missions. Tagged `[editor data fix]`. (Note: `INVALID_FILE_ATTRIBUTES` isn't defined in the
VC6 SDK; used the literal `0xFFFFFFFF`.) This made the requested "move editor into the game-binaries
folder" unnecessary — the editor already junctions the dev tree (`Gameleap\mw4`), the most complete
data (51 missions, 46 maps); the game deploy `C:\VWE\MW4` actually has **0** user missions, so it
would have shown FEWER.
**Second half of the fix — actually LOADING the listed missions (`EditorApplication.cpp`
`LoadMissionResources`):** listing wasn't enough. Opening any non-user mission STOPped with
`Can't open <garbage>`. Cause: `LoadMissionResources` hardcoded the resource path as
`"Resource\\User"` + (name after first `\`), i.e. only `Resource\UserMissions\<name>.mw4` (the 5
user missions), and produced a garbage path (bad `strchr+1` pointer) for other name forms. But
**stock** missions compile to `Resource\Missions\<short>.mw4` with abbreviated lowercase names
(`CentralPark`->`cpark.mw4`, `Frostbite`->`fbite.mw4`) that aren't derivable by transform — the
short name is declared in each mission's `.build` (`[resource\missions\X.mw4]`). Fix: extract the
bare mission name, prefer `Resource\UserMissions\<name>.mw4`, else read the resource path straight
out of `Content\Missions\<name>\<name>.build`. Verified headlessly via `-report` (which also calls
`LoadMissionResources`): Coliseum -> 248 entities, CentralPark (cpark.mw4) -> 1709 entities, no STOP.
All 51 missions are now openable; the 5 user missions still work. Tagged `[editor data fix]`.
### (historical) Editor INTERACTIVE; the (now-fixed) windowed 3D viewport blocker
Verified via window enumeration: at startup the editor creates ALL its MDI children
(**Game View, Object Manager, Overview Window**) and presents a modal **"Open Mission"** dialog
(normal startup; main frame correctly disabled behind it) — the user opens a map from there and
the UI is usable. (Headless test runs "exit code 1" simply because nothing clicks that modal
"Open Mission" dialog — NOT a crash. Earlier "idle/Responding" readings were the process sitting
on that dialog; `Responding=True`+0% CPU cannot distinguish a working UI from a modal dialog —
enumerate windows to tell them apart.) The only real failure is **live 3D rendering**: selecting
**Game View** (and the Overview render once a mission draws) STOPs:
**`No software rasterizer available`**
(`DXRasterizer.cpp:2488`). Path: `DirectDrawCreateAllBuffers` -> `SetupMode` tries windowed
**hardware D3D7** (primary surface + clipper on `hWindow` + VRAM 3D backbuffer) which fails on
Win11's legacy DirectDraw, then falls back to **Blade software** (555 system-mem surface,
`SetupMode` line ~1816/1835) which also fails -> STOP. This is the **windowed legacy DirectDraw/
D3D7-on-Win11** problem — the SAME core incompatibility the game avoids by running **fullscreen-
exclusive** (+ `DWM8And16BitMitigation` shim). It is a distinct, deeper rendering-compat task from
everything above (which was input + content). To pursue: capture the exact failing `HRESULT` by
reproducing interactively (open map -> Game View) under cdb; candidate directions = a DDraw
compat layer (e.g. DDrawCompat), forcing a supported windowed surface format, or hosting the
viewport via a different present path. NOT yet solved.
### ✅ Deployment finalized (2026-06-22)
- **PageHeap REMOVED** (debug aid only): ran `reg import C:\VWE\build-env\mw4ed2-pageheap-off.reg`
ELEVATED (UAC) -> HKLM IFEO `MW4Ed2.exe` key gone. The real-name `MW4Ed2.exe` now runs directly
(no longer AVs at ~2s). The `MW4Ed2_nph.exe` copy remains as a page-heap-immune fallback.
- **`deploy-editor.ps1` updated:** sources the **Profile** build (`pro.bin`, the working config) +
`.pdb`; writes `run-editor.bat` (`MW4Ed2.exe -armorlevel 3`, no `/gos`); sets the DDraw shim;
warns if PageHeap IFEO is present. A fresh deploy is runnable to the editor UI.
- **Launch:** `C:\VWE\MW4Editor\run-editor.bat` (or `MW4Ed2.exe -armorlevel 3`). Pick a mission in
the startup "Open Mission" dialog. Everything except the live 3D render works.
- Expect more WIP content STOPs only if exercising missions/maps not loaded at startup.
- (Optional) Build Debug/Armor configs (need `dbg.bin`/`arm.bin` output dirs).
## ✅ STEP 9: Editor runs IN PLACE in the data tree — no separate `MW4Editor` dir (2026-06-23)
The editor's only job is editing the source content/resources in `Gameleap\mw4`, so the separate
`C:\VWE\MW4Editor` deploy (which just junctioned back to `Gameleap\mw4`) was removed. `deploy-editor.ps1`
now **installs the editor into `Gameleap\mw4`**: copies `MW4Ed2.exe`(+pdb) + DDrawCompat `ddraw.dll`,
renames the two DDraw-breaking DLLs (`dbghelp.dll`/`imagehlp.dll``.disabled`), sets the DWM shim on
`Gameleap\mw4\MW4Ed2.exe`, and writes `Gameleap\mw4\run-editor.bat`. Verified: editor launches in place
with the full UI + DDrawCompat viewport (Game View/Overview/Object Manager/Resources).
- **Conflict handled:** DDrawCompat `ddraw.dll` is **fatal** to `MW4pro.exe`'s fullscreen build init
(`[DDrawCompat] Fatal Error`). Since the resource builder runs from the same `Gameleap\mw4`,
`build-resources.ps1` now moves `ddraw.dll` aside (`.buildaside`) for the build and restores it in a
`finally` (verified: build exit 0, ddraw restored).
- **Game deploy unaffected:** `deploy-mw4.ps1` adds `ddraw.dll` to its skip list, so DDrawCompat + the
editor exe/pdb/launcher/`.disabled` DLLs never leak into `C:\VWE\MW4` (verified: 682 files / 868 MB,
58 packages, fullscreen native DDraw). Old launch path `C:\VWE\MW4Editor\...` is superseded by
`C:\VWE\Gameleap\mw4\run-editor.bat`.
## 📋 Reference: raising the MP player cap 16 → 24 (investigated 2026-06-24; NOT planned)
Captured for the future; **we are not tackling this in the foreseeable future.** Question was
whether `ConLobby.script`'s `MAX_ROSTER_COUNT 16` could be 24. Findings:
- **No engine wall at 16 — the real ceiling is 255.** `Adept::Maximum_Players = 255`
(`mw4\Libraries\Adept\Application.hpp:139`); every per-player fixed array (`servedConnectionData[]`,
scoreboards, net-stats, mission-review logs, `pdmg_given/rcvd`) is sized to 255. `connectionID`
is a `BYTE` (0255). `Environment.NetworkMaxPlayers` is passed straight to DirectPlay's
`dwMaxPlayers` (`CoreTech\...\GameOS\Net_Main.cpp:2142`) — no GameOS ceiling; `m_maxPlayers` has
no hard upper clamp (`MW4Shell.cpp:1803` only clamps *bots* down to the player count).
- **16 is enforced in THREE layers — a script edit alone is insufficient/misleading:**
1. UI: `Content\ShellScripts\ConLobby.script` `#define MAX_ROSTER_COUNT 16` (already 8→16; gated by
`USE_O_MORE_PODS`/`g_nMechPodNum`; also clamps vs `MAXTESLA_P` = cafe Tesla count, ≤8).
2. **Compiled defaults (the real connect gate):** `MW4Shell.cpp:13319-13321` non-coop sets
`m_maxPlayers=16; Environment.NetworkMaxPlayers=16; m_maxBots=16` (coop branch caps at 9).
Editing only the `.script` shows 24 slots but the session still rejects the 17th player.
3. Lobby pods / scoreboard (`hudscore`) / radar UI are laid out for ≤16.
- **To actually reach 24:** raise `MAX_ROSTER_COUNT` **and** the `m_maxPlayers`/`NetworkMaxPlayers`/
`m_maxBots` defaults (→ rebuild `MW4.exe`), rework lobby/scoreboard/radar layouts, and ensure maps
define **≥24 drop zones / start points** (many MP maps only have ~16 — a per-map content limit).
- **Why the cap exists (the practical blocker):** replication is ~O(n²) — 24 vs 16 ≈ (24/16)² ≈
**2.25× host outbound + CPU**; the dictionary/culling netcode was tuned for ≤16. Bandwidth, not
the data structures, is the ceiling.
### 📐 PLAN: raise MP cap 16 → 32 (drafted 2026-06-24; NOT scheduled)
Concrete plan extending the reference above to **32 players**. Phased; each phase is independently
testable. 32 is safe vs the engine ceiling (255 arrays, `BYTE` connectionID) and has **no 32-bit
player-mask boundary risk** — verified the only `0x1<<id` masks are per-mech *weapon* bits
(`MWEntityManager.cpp:1332`, `NetWeapon.cpp`), not player/connection indices.
**Phase 1 — Code defaults + lobby-param path (rebuild `MW4.exe`, Release + Profile).**
- `MW4Shell.cpp:13319-13321` (non-coop game setup): `m_maxPlayers`, `Environment.NetworkMaxPlayers`,
`m_maxBots` `16 → 32`. Coop branch `13309/13315-13316` (`=16`/`=9`/`=8`) — leave or bump per design.
- `MW4Shell.cpp:1803-1831` (lobby-driven path): `m_maxPlayers=INTPARM(1)`, `m_maxBots=INTPARM(1)`,
`Environment.NetworkMaxPlayers = params->m_playerLimit`. No hard upper clamp exists
(`1808 Max_Clamp(m_maxBots, m_maxPlayers)` only clamps bots down) — but confirm the lobby
"player limit" control feeds a value up to 32 (param `PLAYER_LIMIT_PARAMETER`, `NetParams.h:53`).
- Grep-audit for any other implicit ≤16 assumptions before rebuild (none found so far; arrays=255).
**Phase 2 — Lobby + in-game UI (repack `props.mw4`). [LOW PRIORITY]**
Cosmetic/usability, not a functional blocker: with only Phases 1+3 done, 32 players can still
connect, spawn, and play — the lobby pods/roster and scoreboard/radar just overflow or clip past
16 (and the host can still set the limit via the param path even if the slider UI caps lower).
Defer this polish until 32p is otherwise proven; do the minimum to make the lobby usable, leave full
pod/scoreboard re-layout for later.
- `Content\ShellScripts\ConLobby.script`: `MAX_ROSTER_COUNT 16→32`, `MAX_TEAMMATE_COUNT 8→16`
(both under `USE_O_MORE_PODS`/`g_nMechPodNum`); raise the player-limit control's max to 32.
Note the `MAXTESLA_P` clamp is cafe-only (CTCL Tesla count) and won't block non-cafe play.
- **Biggest UI lift — the mech-selection "pods":** the lobby draws a fixed grid of player/mech pods;
32 needs a reworked layout (grid size, scrolling, or smaller pods). Same for the team-assignment
panel (`TEAM_MAX_PLAYERS`, `team_max_plyrs` @ ConLobby:328).
- Multiplayer lobby scripts (`Content\ShellScripts\Multiplayer\*` incl. `lobby_listbox.script`,
`HostLobbyMission.script`): roster list sizing + player-limit slider range.
- In-game **scoreboard** (`hudscore.cpp`) and **radar** (`GUIRadarManager.cpp`): data is fine
(255 arrays) but the on-screen score table / legend is laid out for ≤16 → rework for 32 (scroll
or two columns). `MP_Review.script` top-down review screen likewise.
**Phase 3 — Map content (per-map; the gating gameplay task).**
- Every MP map used at 32p must define **≥32 drop zones / start points**. Most stock maps have ≤16;
players 17-32 silently fail to spawn otherwise. Audit + author extra drop points in the editor
(now runnable in place from `Gameleap\mw4\run-editor.bat`). This is per-map, independent of code.
**Phase 4 — Netcode / performance. [LIKELY FINE on modern hardware/networks]**
- Replication is ~O(n²): 32 vs 16 ≈ (32/16)² = 4× host outbound + CPU. This was the limiting factor
in 2002 (dial-up / early broadband), but **modern broadband upstream + CPU absorb 4× easily** — raw
bandwidth/CPU is no longer expected to block 32. Demote from "real ceiling" to a verification item.
- Residual (non-bandwidth) thing to check when implementing: any **fixed-size netcode buffers / per-
frame packet or replication caps** hardcoded for ≤16 (distinct from bandwidth; e.g. packet-count or
buffer limits). Audit during Phase 1; bounded by the 255-array design, so likely none. Still do a
live load test to confirm, but don't expect tuning to be needed.
**Verification:** (1) rebuild → headless `-report`/launch sanity; (2) host a game, confirm 32 slots
in lobby + 17th32nd players connect (`Environment.NetworkMaxPlayers`/DirectPlay `dwMaxPlayers`);
(3) confirm spawns on a 32-drop-zone map; (4) load/bandwidth test; (5) check scoreboard/radar/review
UI legibility. **Primary remaining work:** per-map drop-zone authoring (Phase 3) is now the main
gating task. UI (Phase 2) is low-priority non-blocking polish; bandwidth/CPU (Phase 4) is expected
fine on modern hardware — just verify fixed-size netcode buffers and run one live load test.
## Next steps (proposed)
- [x] ~~Windowed 3D viewport on Win11~~ — DONE via DDrawCompat (see STEP 8 viewport section).
- [ ] (Optional) Curate remaining WIP content as features are exercised (editor loads dev `Content\`).
- [ ] (Optional) Build Debug/Armor configs (need `dbg.bin`/`arm.bin` output dirs).
- [ ] (Parked, NOT scheduled) Raise MP cap to 24 or 32 — see "Reference"/"PLAN" sections above.
@@ -0,0 +1,13 @@
Annihilator Exploded
LL 0,148,78,324
RL 260,148,340,324
LA 6,40,78,132
RA 260,40,334,132
RT 212,80,240,216
LT 100,80,128,216
CT 146,12,192,200
CTR 0,0,0,0
HD 162,236,176,242
S1 0,0,0,0
S2 0,0,0,0
@@ -0,0 +1,13 @@
Annihilator Unexploded
LL 78,152
RL 182,152
LA 56,72,
RA 210,72
RT 180,64
LT 132,64
CT 146,10
CTR 0,0
HD 162,32
S1 0,0
S2 0,0
@@ -0,0 +1,13 @@
Annihilator Exploded
LL 8,270,108,500
RL 398,270,498,500
LA 30,24,126,42
RA 400,28,498,146
RT 322,120,362,294
LT 146,118,186,292
CT 226,54,282,294
CTR 0,0,0,0
HD 244,338,266,348
S1 0,0,0,0
S2 0,0,0,0
@@ -0,0 +1,13 @@
Annihilator Unexploded
LL 34,186
RL 164,186
LA 4,78
RA 198,78
RT 158,66
LT 100,68
CT 120,2
CTR 0,0
HD 138,26
S1 0,0
S2 0,0
@@ -0,0 +1,25 @@
Argus Unexploded
LL 42,138
RL 176,138
LA 54,30
RA 224,24
RT 194,38
LT 124,38
CT 128,14
CTR 0,0
HD 156,48
S1 0,0
S2 0,0
Argus Exploded
LL 4,138,120,326
RL 216,138,332,336
LA 12,14,82,90
RA 242,14,324,114
RT 174,200,202,262
LT 140,200,158,262
CT 126,14,208,186
CTR 0,0,0,0
HD 156,294,178,302
S1 0,0,0,0
S2 0,0,0,0
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
LL 98,142,148,328
RL 190,142,240,328
LA 56,48,124,154
RA 216,48,282,154
RT 180,22,220,120
LT 120,22,158,120
CT 144,36,194,186
CTR 0,0,0,0
HD 158,70,180,86
S1 148,10,190,48
S2 0,0,0,0
@@ -0,0 +1,11 @@
LL 6,148
RL 282,148
LA 6,10
RA 266,10
RT 206,22
LT 98,22
CT 144,180
CTR 0,0
HD 158,140
S1 148,10
S2 0,0
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
LL 8,220
RL 336,220
LA 8,48
RA 314,48
RT 244,48
LT 120,48
CT 178,206
CTR 0,0
HD 192,78
S1 178,3
S2 0,0
@@ -0,0 +1,11 @@
LL 114,170,178,406
RL 232,170,294,406
LA 60,48,144,184
RA 264,48,348,184
RT 218,18,268,140
LT 142,18,190,140
CT 174,36,234,140
CTR 0,0,0,0
HD 192,78,218,98
S1 178,2,230,48
S2 0,0,0,0
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,25 @@
Avatar Unexploded
LL 60,108
RL 138,108
LA 40,40
RA 168,40
RT 140,28
LT 76,28
CT 98,6
CTR 0,0
HD 116,16
S1 112,78
S2 0,0
Avatar exploded
LL 12,174,56,316
RL 198,174,240,316
LA 12,42,46,86
RA 198,42,248,90
RT 158,42,186,118
LT 60,42,86,118
CT 96,42,144,174
CTR 0,0,0,0
HD 120,202,128,210
S1 116,238,132,254
S2 0,0,0,0
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,25 @@
Avatar Unexploded
LL 98,174
RL 222,174
LA 62,64
RA 266,64
RT 220,44
LT 118,44
CT 152,10
CTR 0,0
HD 184,24
S1 178,124
S2 0,0
Avatar Exploded
LL 50,258,116,484
RL 384,258,450,484
LA 24,38,80,110
RA 408,38,490,112
RT 324,38,372,162
LT 104,38,152,162
CT 198,38,278,248
CTR 0,0,0,0
HD 230,356,248,372
S1 224,302,254,332
S2 0,0,0,0
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
LL 6,172
RL 246,172
LA 6,8
RA 281,8
RT 226,82
LT 72,82
CT 138,172
CTR 0,0
HD 164,122
S1 142,8
S2 0,0
@@ -0,0 +1,11 @@
LL 76,170,152,302
RL 184,170,262,302
LA 12,106,126,174
RA 212,106,326,174
RT 176,86,226,174
LT 110,82,160,1742
CT 140,96,198,224
CTR 0,0,0,0
HD 164,122,174,134
S1 142,38,194,98
S2 0,0,0,0
@@ -0,0 +1,11 @@
LL 8,236
RL 348,236
LA 8,26
RA 302,26
RT 294,130
LT 108,130
CT 202.242
CTR 0,0
HD 230,174
S1 202,28
S2
@@ -0,0 +1,11 @@
LL 84,206,184,374
RL 222,206,322,374
LA 2,124,150,210
RA 260,124,404,210
RT 214,94,278,210
LT 130,94,194,210
CT 166,110,242,274
CTR 0,0,0,0
HD 198,144,210,158
S1 170,36,236,112
S2 0,0,0,0
@@ -0,0 +1,26 @@
BlackHawk Unexploded
LL 32,82
RL 188,82
LA 6,12
RA 236,12
RT 176,18
LT 92,18
CT 152,6
CTR 0,0
HD 154,38
S2 184,112
S1 110,112
BlackHawk exploded
LL 8,128,116,340
RL 228,128,334,340
LA 8,0,90,122
RA 252,0,334,122
RT 188,0,246,114
LT 0,96,152,114
CT 160,0,180,126
CTR 0,0,0,0
HD 164,146,178,150
S1 132,168,164,194
S2 176,168,208,194
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More