OVERDOSE
PROTOCOL

RE PROJECT v0.3

HomeDashboardRoadmapDev LogCommunityWikiSupportFAQAboutContact
GitHub RepoDiscord
Dashboard
v1.00

OVERDOSE PROTOCOL

Total Overdose — Reverse Engineering Project

8,308
Functions Mapped
24
Tasks Done
3
In Progress
2
Milestones
2026
Started

ACTIVE MILESTONE

Full Roadmap

Phase 2 - Rendering Pipeline

DirectX 9 fixed-function pipeline. DONE: RenderParticle, RenderTexturedQuad_3 (5-mode billboard), GfxInternal_Dx9 compiles and links. Remaining: real DDS texture loader (currently stubbed).

PROGRESS90%

LATEST TRANSMISSION

All Logs
WEEK #0042026-06-22

MILESTONE: KapowEngineEditor.exe builds

The standalone Kapow Engine Editor binary now builds end-to-end. 2.13 MB PE32 i386 GUI executable, separate from the dinput8.dll injection used to boot the retail game. This is the foundation of the Editor - our actual end-goal tool.

TASK BOARD

BACKLOG(18)
GEN

Q72: LoadNativeResource placeholder fallback shipped (cf2d4e3)

Defensive guard: when resdir is non-empty (e.g. texture_pc), construct placeholder Asset with HasPlaceHolder flag instead of returning null. Independent path to first pixels alongside Sonnet's Q70/Q71. Source: AI_BRIDGE.md, parallel-assignment cadence per Sandy directive 'aim for massive win'.

medium
GEN

Q80-Q100: M7/M8/M9/M10 next-wave backlog (Sonnet+Gemini)

Animation system (Q80-85), texture decoder (Q86-90), audio pipeline (Q91-95), physics integration (Q96-100). Drafted as immediate post-M5-first-pixels work. See AI_BRIDGE.md Opus 4.8 entry at 09:48. Source: AI_BRIDGE.md, parallel-assignment cadence per Sandy directive 'aim for massive win'.

medium
GEN

Q106 SHIPPED: Instantiate guard softened for THREE-type assets

Commit 1a2c292. When asset type isn't resolved upstream but assetPtr's vtable points into a sane code-section range (0x00400000-0x7FFE0000) AND AssetType==THREE, dispatch ApplyAssetData anyway. Unblocks Q86 checkerboard chain. Pending harness verification (env wobble this session). Source: AI_BRIDGE.md, parallel-cadence session.

medium
GEN

Engine state milestone: 60fps stable 900 frames with scene loaded

Engine successfully boots, loads OverdoseIntro.scene, walks 102 entities in recursive scene-tree walker, Sprite::Render fires for 50+ sprites/frame. Q72 LoadNativeResource placeholder confirmed firing. 33 Sprites now have valid m_AssetPtr (up from 0). 14 FindLoadedAsset matches (up from 0). Last remaining gate: m_Texture_1 population - Q106 should fix once verified. Source: AI_BRIDGE.md, parallel-cadence session.

medium
GEN

Q111: harness env recovery (fresh shell investigation)

Multiple harness attempts show 'TOD never spawned' even after killing TOD/cdb processes. cdb log shows DINPUT8.dll loads with full Debug CRT chain but TOD process termination/spawn detection fails. Possibly stale OS resource. Workaround: run from fresh PowerShell or reboot. Investigation task. Source: AI_BRIDGE.md, parallel-cadence session.

medium
GEN

TR-2: Verify Sprite::Render emits DrawPrimitive (validation of abfa74d)

Assignee: Sonnet Sonnet's commit abfa74d shipped Sprite::Render full implementation. Run harness, look for 'DIAG Sprite::Render entry 1:' trace lines. Verify Sprites with valid m_Texture references actually emit DrawPrimitive. Report DrawIdx/frame counts. Source: AI_BRIDGE.md update at 2026-06-24 08:18 ('KabutoKun Discord intel + state ack').

medium
GEN

[ASSET PARSE] Recursive Instantiate produces garbage index (>1.9B) - pointer-advance off

After fixing FragmentAsset crash, subsequent Instantiate calls get assetTypeIndex=1900414856 (and similar billions) -- pointer arithmetic in ParseAssetData/the parser is off by N*sizeof(record). We survive only because of the bounds check. Real fix: align our parser to the original asset DB layout. Related to #39 (checksum drift).

medium
GEN

[ASSET] CompiledAssetInfo::_85E160 is a Ghidra stub - needs proper reimpl

FragmentAsset::ApplyAssetData line 81 calls _85E160 which (in AssetManager.cpp:1613) is a partial Ghidra decompile with TODO branches; the advance overshoots and leaves assetInfoPtr=0xFFFFFFE0. Need to disassemble TOD.exe at 0x85E160, study original advance logic, complete impl. Until then FragmentAsset::ApplyAssetData stays stubbed (issue #38).

medium
GEN

[GFX] DEV_FORCE_WINDOWED produced 0x0 invisible window - needs SetupWindowedRenderer fix

## Symptom Defining `DEV_FORCE_WINDOWED` in `KapowEngineClass.cpp` to force `SetupWindowedRenderer` instead of `SetupFullScreenRenderer` caused TOD.exe to create a window with client area 0x0 (invisible). Reverted in commit `c78c1e8`. ## Why we wanted it Original 800x600 fullscreen often fails on modern displays. Windowed is more permissive. ## Root cause hypothesis `SetupWindowedRenderer(m_DisplayModeResolution)` was called with `m_DisplayModeResolution` not yet populated ? `(0,0)`. Need to use a sensible default (e.g. `{800, 600}`) or read `m_ViewportResolution` instead. ## Status note Since we now run via `Direct3DCreate9Ex` + `Windowed=TRUE` set at `CreateRenderDevice` time (in commit `1ff681b`), this issue is partially obsolete - D3D opens windowed and gets a real `hWnd`. But the dedicated DEV_FORCE_WINDOWED path is still broken if anyone re-enables it.

medium
GEN

[CLEANUP] Remove DIAG noise (ListType ctor, DataType ctor, PP.* dump) once boot is stable

## What While debugging the boot crash we added ~10 `LogDump::LogA("DIAG ...")` lines in: - `TOD1/ListType.cpp` (BEGIN/MID/STEP1/STEP2/END for every ctor - fires ~50 times) - `TOD1/DataType.cpp` (every ctor) - `TOD1/GfxInternal_Dx9.cpp` (PresentParameters dump, Direct3DCreate9Ex result, 3-tier device fallback chain log) - `TOD1/KapowEngineClass.cpp` (LoadScripts MILESTONE) - `TOD1/Texture.cpp` (CreateDirect3DTexture diag) ## Why keep them now They're load-bearing for the next round of debugging (Retail Assets table). Once boot reaches the main loop, demote them to `#ifdef DIAG_BOOT_FLOW` or delete. ## Action 1. Wait until Retail Assets blocker is resolved 2. Delete or gate the DIAG lines 3. Keep the `DIAG: PP.*` dump permanently (rare but valuable for future driver-compat issues)

low
GEN

[RECON] Replace _reconPad_* alignment fields with real members (~62 classes)

## Context ASSERT_CLASS_SIZE enforces ABI compatibility with TOD.exe. ~62 reconstructed classes still have placeholder `_reconPad_*` byte arrays to hit the asserted size. Notable: - `Scene` (+32 bytes pad) - `EntityType` (+16 bytes pad) - `Texture` (verified clean) - `GfxInternal_Dx9` (large pad mid-class) ## Why this matters now The Properties/Commands checksum mismatch may partially originate here - if a reconstructed property's offset is wrong because surrounding pads are wrong size, the CRC of the property table will differ from the original. ## Action Tracked per-class. Open sub-issues as each is tackled. Reference original Ghidra struct vs reconstruction.

medium
GEN

[EDITOR] --editor cmdline switch missing on KapowEngineEditor.exe

## What `KapowEngineEditor.exe` (the standalone Release EXE) builds cleanly (commit `1a2cdda`) but currently launches in game mode like `TOD.exe` would. We need a `--editor` cmdline flag that: 1. Opens the engine's Editor UI (the File/Edit/Functions debug menu we saw briefly during the early boot test) 2. Skips the splash/intro 3. Loads `OverdoseIntro.scene` directly into the editor ## Where to add `InitialiseGame(char* cmdline)` already receives the cmdline. Parse `--editor` / `-e` there and set a global flag the editor mode reads in `KapowEngineClass::Init`. ## Blocked by The Retail Assets table issue - editor needs assets too. Pick this up once the engine reaches main-loop.

medium
GEN

Editor: wire up file menu / scene browser

Once boot works, hook up: New Scene, Open Scene, Save Scene Session (the EDITOR_SESSION_FILE_VERSION=3 format), editor camera controls (mouse/wasd), node tree panel.

medium
GEN

First boot: launch the reconstructed binary

Once linking, drop dinput8.dll into game install and attempt boot. Expect crashes; debug boot path.

critical
GEN

Reverse Scene::LoadMap (FUN_00890000, asset block loading)

Map-chunk loader - critical EXE path. Loads .naz/.main blocks into the scene via MAIN_ASSETS/MISSION_ASSETS allocators.

medium
GEN

Assemble Scene::Update (FUN_00897450) from reversed helpers

BLOCKED on the 10 leaf helpers. Once all are reconstructed and declared, assemble the full 3,159-byte function using the verified Scene.h symbol table. Mechanical once deps exist.

critical
GEN

Build .naz / .main asset format parser

Open-source parser for the Kapow engine asset block format. Required for standalone EXE asset loading.

medium
GEN

Reverse remaining 268 engine stubs

Epic: 268 TODO_IMPLEMENTATION markers remain across 73 source files. Prioritized by critical EXE path (Scene, AssetManager, PhysSystem first).

medium
TO DO(13)
GEN

[BOOT] Engine 'Not Responding' after main-loop entry - msg pump not running?

Window opens with correct title ('Total Overdose ** ( scripts: /data/scripts/stable/)'), 243 MB memory, but Windows shows 'Not Responding' - message queue not pumped. Could be: (a) genuinely hung in init, (b) blocked on missing asset, (c) message pump not implemented in Platform::Process. cdb non-invasive attach + ~* kpn will tell us where the threads are.

critical
GEN

[ASSET] Properties/Commands checksum mismatch (asset DB vs recompiled engine)

## Symptom At `AssetManager.cpp:600,608` the engine compares two CRC32 fingerprints (Properties table + Commands table) against the values stored in the asset .main file. Currently: | Field | Asset has | Engine has | |-------|-----------|------------| | Properties checksum | `0x65c37710` | `0x6e6b6da6` | | Commands checksum | `0xe5ae7722` | `0xaf5d3dab` | Validation already bypassed under `INCLUDE_FIXES` (logs instead of returning null). Without the bypass, asset loading hard-fails. ## Why this matters The mismatch tells us our reconstructed `DataType` properties and `Command` tables don't match the 2005 game's exactly. With the bypass, downstream code may parse `CompiledAssetInfo` with the wrong offsets ? silent corruption. ## Two paths - **(A) keep bypass**, treat mismatch as informational, fix concretely on a case-by-case basis as downstream bugs surface - **(B) brute-force match**: enumerate every Property name/type that contributes to the CRC, diff against the original, fill missing entries until checksums agree (A) is the current pragmatic choice. (B) needs Ghidra archaeology of `GetGlobalPropertyListChecksum` / `GetGlobalCommandListChecksum`. ## Refs - `TOD1/AssetManager.cpp:590-612` - INCLUDE_FIXES guard around both `return nullptr;` lines

critical
GEN

[D3D9] Review D3DPOOL choice for vertex/index buffers after D3D9Ex migration

## Context D3D9Ex devices don't support `D3DPOOL_MANAGED`. Commit `169085f` swapped all 4 sites: - `Texture::CreateDirect3DTexture` non-RT path ? `D3DPOOL_SYSTEMMEM` - `GfxInternal_Dx9::CreateVertexBuffer` ? `D3DPOOL_DEFAULT` - `GfxInternal_Dx9::CreateIndexBuffer` ? `D3DPOOL_DEFAULT` - `GfxInternal_Dx9::CreateTexture` helper ? `D3DPOOL_SYSTEMMEM` ## Risk `D3DPOOL_DEFAULT` vertex/index buffers **cannot be Lock'd** unless created with `D3DUSAGE_DYNAMIC`. If the engine later calls `Lock()` on a `DEFAULT` VB/IB without that flag, it returns `D3DERR_INVALIDCALL` (we'll see "Error - could not lock" again). ## Action 1. Audit every `VertexBuffer::SetData`/`IndexBuffer::SetData`/`Lock` call path 2. Add `D3DUSAGE_DYNAMIC` to the `usage` arg in `CreateVertexBuffer`/`CreateIndexBuffer` when the original used `MANAGED` and the buffer is mutable 3. For static, write-once buffers, leave as `DEFAULT` (faster) and use `UpdateTexture`/`UpdateSurface` instead of `Lock` ## When to fix Only after we get past the Retail Assets blocker - won't hit this code path until rendering starts. ## Refs - `TOD1/GfxInternal_Dx9.cpp` line ~1640 - Commit `169085f`

medium
GEN

Editor: launch KapowEngineEditor.exe directly into editor mode

Add cmdline flag (--editor or similar) to InitialiseGame so the standalone binary boots into editor mode. Currently it just runs the same game-mode init path.

medium
GEN

Reverse FUN_00892f50 (per-child script trigger)

Triggers active scripts on child entities in the Scene::Update script-dispatch tail (m_ScriptSlots[1] & 0x20).

low
GEN

Reverse FUN_00893a50 (scene helper)

Helper called in the rewind-commit branch of Scene::Update.

low
GEN

Reverse FUN_008aae20 (rewind transaction commit)

Commits per-frame entity property transactions into the rewind buffers when in gameplay mode.

medium
GEN

Reverse FUN_0089c050 (sound-emitter update helper)

Iterates the sound-emitter list in Scene::Update's tail.

medium
GEN

Reverse FUN_0088e1e0 (node/child rewind helper)

Per-child helper invoked during the MODE_STOP rewind path of Scene::Update.

medium
GEN

Reverse FUN_00896180 (scene update tail helper)

Part of the Scene::Update entity-update tail (MODE!=STOP branch).

medium
GEN

Reverse FUN_00893b30 (post-flag scene update step)

Called immediately after the camera/rewind flag block in Scene::Update.

medium
GEN

Reverse FUN_00894bf0 (FlushRewind implementation)

Handles the m_FlushRewindRequested flag in Scene::Update - flushes the rewind transaction buffers.

medium
GEN

Reverse FUN_00892b10 (Scene::_892B10 sub-update)

Scene method called on SceneInstance in both the init-mode and main-update paths of Scene::Update. Blocker #2.

medium
IN PROGRESS(3)
GEN

Asset loader: diagnose 'asset has 0' checksum bug

Engine boots and tries to load resource block 0; FileBuffer reads all zeros from the asset file. Could be wrong path, wrong file association in .naz archives, or FileBuffer not finding the .naz entry. Diagnostic LogDump lines added - need a fresh boot trace.

critical
GEN

Apply GfxInternal_Dx9 stubs to source

Port implemented stubs from GfxInternal_Dx9_stubs.cpp into GfxInternal_Dx9.cpp per APPLY_GUIDE.txt.

medium
GEN

Implement Scene::Update (FUN_00897450)

3159-byte per-frame state machine: delta time, save/restore, rewind flags, m_State dispatch. Decompile at decompiled_output.txt:482858. Handed to Gemini via AI_BRIDGE.md.

critical
DONE(24)
GEN

Q70/Q71: blocks.naz stride parser fix (Sonnet, critical-path)

Sentinel-anchored record parser using 0xBAADF00D + 0xABABABAB MSVC alloc-fill patterns as boundaries. Hex evidence in docs/BLOCKS_NAZ_FIRST_4K_HEX.txt. Records start every ~192 bytes with twin-string pattern (camelCase + lowercase alias). Goal: registry goes from 8 garbage entries to 500+ valid ones, unblocks DrawIdx > 0 -> FIRST PIXELS. Source: AI_BRIDGE.md, parallel-assignment cadence per Sandy directive 'aim for massive win'.

medium
GEN

TG-1: Auto-call Scene::Start at end of OpenScene + F5 shortcut

Assignee: Gemini Per Sonnet analysis (DIAG bridge entry): editor's Scene::Start is skipped (m_ShouldStartGame=false), so m_PlayMode stays MODE_STOP, scripts never fire, MoviePlayer::Play() never called, DrawIdx stays 0. Options: (a) Auto-call Scene::Start at end of OpenScene under INCLUDE_FIXES; (b) F5 keyboard shortcut to Scene::Start; (c) both. Source: AI_BRIDGE.md update at 2026-06-24 08:18 ('KabutoKun Discord intel + state ack').

medium
GEN

TG-2: Verify Mode panel STOP/PLAY actually reach Scene::Start

Assignee: Gemini Gemini's prior commit (Task A) wired WM_COMMAND for Mode panel control ID 1045 PLAY. Verify it reaches Scene::Start. Run TOD interactively, click Play after Open Demo Scene, check trace for Scene::Start log. If broken, fix. Source: AI_BRIDGE.md update at 2026-06-24 08:18 ('KabutoKun Discord intel + state ack').

medium
GEN

[BOOT BLOCKER] Hidden VC++ Runtime Library dialog after main-loop entry

## What we know After capping `GetNextLoadedAsset` (issue #46 workaround), engine now: - Returns from `KapowEngineClass::Init` - Window status flips `Not Responding` -> `Running` (243 MB -> 470 MB) - ~160 more trace lines fire (5065 -> 5229) But then a **hidden** modal dialog appears: ``` hwnd=1315520 visible=False parent=3610014 (main window) class=#32770 (dialog) title='Microsoft Visual C++ Runtime Library' ``` The dialog is *owned* by the main game window so it sits behind it - user sees nothing on screen, just a blank/unresponsive main window. `SetForegroundWindow` couldn't pull it forward (probably because main window owns the modal stack). ## Stack at the time (cdb non-invasive attach) ``` 00 win32u!NtUserWaitMessage+0xc 01 USER32!DialogBox2+0x1ba 02 USER32!InternalDialogBox+0x11c 03 USER32!SoftModalMessageBox+0x6f3 04 USER32!MessageBoxWorker+0x309 05 USER32!MessageBoxTimeoutW+0x187 06 USER32!MessageBoxTimeoutA+0xae 07 USER32!MessageBoxA+0x45 08 TOD+0x561caa <- caller in original TOD.exe 09 TOD+0x55c687 ``` ## Most likely cause Last log before silence: `DIAG Instantiate: ParseAssetData done` for asset index 1,900,419,068 (garbage). Next line in our source is: `cpp if (assetBuffer->AssetType == CompiledAssetInfo::tAssetType::THREE) assetPtr->m_GlobalResourceId = g_AssetManager->AddAssetReference(assetPtr); ` `assetPtr` has a garbage vtable (`0x714617FC`) because no AssetInstance resolved. `AddAssetReference` probably trips `abort()` / pure-virtual / `_invalid_parameter` from inside the STL when handling this garbage pointer. ## Next steps 1. `LogDump::LogA` flushed *immediately before* `AddAssetReference` to narrow the trigger 2. cdb attach earlier, set breakpoint on `MessageBoxA` and `abort`, dump caller before dialog shows 3. Or: skip `AddAssetReference` when `resolved == nullptr` (treat as junk asset, don't register) ## Related - Issue #46 (recursive Instantiate produces garbage indices) - root cause - Issue #47 (`_85E160` stub) - same upstream parsing bug

critical
GEN

[BOOT BLOCKER] ApplyAssetData crashes on asset type index 4 (vtbl=0x71460748)

## ?? Asset loading complete - engine now reaches main loop ### Resolution path 1. Retail Assets table was NEVER the problem (verified DIAG: retailSize=11, ourSize=11, AssetInstance for 'fragment' resolved cleanly). 2. Real crash was in `FragmentAsset::ApplyAssetData` - its line 81 call to `CompiledAssetInfo::_85E160` (a Ghidra-decompiled stub) overshoots the data stream and overwrites `assetInfoPtr` to `0xFFFFFFE0`. Next line tries to deref ? AV. 3. Stubbed `FragmentAsset::ApplyAssetData` to early-return under INCLUDE_FIXES. Other 14 assets load fine. ### New state - `Done. Loading 15 resource took 0.15 secs.` - Engine runs 17+ seconds with no further trace output - **main loop reached** - 5065 trace lines (up from 4878) ### Follow-ups (will be filed separately) - `FragmentAsset::ApplyAssetData` proper implementation - re-implement `_85E160` based on Ghidra disasm at original address `0x85E160` (issue #39 territory - same code path uses the type info) - The recursive Instantiate is currently producing `idx=1900414856` (garbage out-of-bounds index) because ParseAssetData's pointer-advance is also off - we survive only because we now log+return on bad indices. Real fix wants the index decode to match the original parser. Marking this issue as Done (the Retail Assets misdiagnosis is resolved).

medium
GEN

?? D3D9Ex breakthrough - 6x boot progress (Win11/AMD compat)

## ?? BREAKTHROUGH (2026-06-22 overnight session) After 20+ hours of investigation, TOD.exe boot progression went from **800 trace lines (crash)** to **4,871 trace lines (graceful exit at asset instantiation)**. ### Root cause (found via WinDbg/cdb) The original boot crash was `__fastfail(5) FAST_FAIL_INVALID_ARG` triggered by stack-cookie corruption in `Texture::CreateDirect3DTexture` epilogue. Real bug: `m_Direct3DDevice` was NULL because the upstream `CreateDevice` failed silently with `D3DERR_DEVICELOST` (0x88760868). Three device tiers (HARDWARE/SOFTWARE/REF) ALL returned the same error - REF doesn't use the GPU, so this ruled out driver/adapter issues. Cause: **Win11 + AMD WDDM driver no longer accepts classic `Direct3DCreate9`**. ### Fix (commits `1ff681b`, `169085f` on `gitlab/main`) 1. Added a `Direct3DCreate9Ex(D3D_SDK_VERSION, &d3dEx)` call after the classic `Direct3DCreate9`. `IDirect3D9Ex` inherits from `IDirect3D9` so the rest of the engine uses it transparently. 2. `D3DPOOL_MANAGED` ? `D3DPOOL_DEFAULT`/`SYSTEMMEM` everywhere (Ex devices don't support MANAGED): - Textures (lockable path) ? SYSTEMMEM - Render-target textures ? DEFAULT - Vertex/Index buffers ? DEFAULT ### Now passing - ? D3D9Ex device created - ? Graphics init complete (no errors) - ? All 5 NAZ archives opened (blocks, sounds, uk_sounds, videos00, videos01) - ? Script database loaded - ? Resource block loaded - ? `OverdoseIntro.main` (413,476 bytes) opened - ? CompiledAssetInfo created ### Open issues from this session - #38 [CRITICAL] Retail Assets static registry empty at LoadResourceBlock - #39 [CRITICAL] Properties/Commands checksum mismatch (asset DB vs engine) - #40 [MEDIUM] D3DPOOL choice review (DYNAMIC usage flag for VB/IB) - #41 [MEDIUM] DEV_FORCE_WINDOWED produced 0x0 window - #42 [LOW] Remove DIAG noise once boot stable - #43 [MEDIUM] Replace _reconPad_* fields (62 classes) - #44 [MEDIUM] --editor cmdline switch missing ### Tooling added - `C:\tod2026\debug-hang.ps1` - automated cdb harness for live call stacks - `C:\tod2026\cdb-script.txt` - reusable cdb command sequence - `DIAG:` instrumentation throughout boot path (gated under INCLUDE_FIXES) Engine source: `gitlab/main` HEAD = commit `1ff681b`

critical
GEN

?? Standalone KapowEngineEditor.exe builds

Release EXE config fixed (DynamicLibrary -> Application); renamed TargetName to KapowEngineEditor. 2.13 MB PE32 i386 GUI binary. Commit 1a2cdda.

critical
GEN

Linker pass: resolve unresolved externals

After C2xxx -> 0, expect a wave of LNK2001/LNK2019 unresolved externals. Reverse / stub the missing functions until link succeeds.

critical
GEN

Fix remaining 40 build errors (C2065/C2248/C2039)

22 undeclared identifiers, 13 access violations, 4 not-a-member, 1 identifier-not-found. Final compile push -> linker stage.

critical
GEN

Fix 159 implementation errors (missing decls + access fixes)

Gemini cleared 159 errors across multiple files. Commit 82f1615.

medium
GEN

Struct sizes: pad all 62 undersized classes to expected size

Build-verified actual vs expected sizes for all 62 classes; padded with char _reconPad[N] tail members. Commits c303d80, 563dff1, 9a19174. C2338 -> 0.

critical
GEN

Fix SystemSubAllocator aligned-malloc inversion

Backwards #ifdef + wrong _aligned_offset_malloc_dbg args. Commit d3f39d3.

medium
GEN

Config: add ThirdParty include + /vmg + DIRECTX defines to Release

Three vcxproj config gaps fixed: ThirdParty on include path (-125 errors), /vmg member-pointer ABI on Release (-2064 errors), DIRECTX;PLATFORM_PC on Release (-152 errors). Commits a841b66, 0d320ef, 3747138.

critical
GEN

Set up VS Build Tools 2022 + DirectX SDK

Toolchain installed: VS Build Tools 2022 (v143 + MSVC 14.44), DirectX SDK June 2010, DXSDK_DIR set. Build script build.ps1 written and committed.

critical
GEN

BestFitAllocator - fully implemented

All stubs implemented and verified against Ghidra decompile: - `_478F70` free-list insertion - `PlacementNewAligned` (FUN_00479350) - alignment bug fixed (header offset), missing stats added - `Realloc` (FUN_004795C0) - shrink-in-place, adjacent merge, fallback alloc+copy+free - `TryExpandBy` (FUN_00479490) - speculative in-place expansion via merge loop Commit: de3cc42 on kapow-systems-3d-2026-project

critical
GEN

Fix GetAvailableMemory bucket off-by-one

Existing loop uses i=20..1 (accesses field_24[20] OOB, skips field_24[0]). Should be i=19..0 like the verified GetBiggestUsedMemoryBlock walk.

low
GEN

Implement BestFitAllocator::_478910 (free-list rebalancer)

327-byte self-contained bucket load-balancer: migrates blocks between adjacent free-list buckets when a neighbour has <= half the count. No external deps - Claude implementing, Gemini to cross-check.

medium
GEN

Reverse FUN_00951640 (frame-time ms helper)

Leaf dependency of Scene::Update. Provides the millisecond delta used to accumulate Scene::RealTimeMs. Smallest of the 10 blockers - start here.

medium
GEN

Implement RenderParticle (FUN_00454d70)

23,593-byte particle render function fully implemented and verified against Ghidra decompile.

medium
GEN

Implement RenderTexturedQuad_3 billboard path

Full 5-mode billboard system: camera-facing, H/V-constrained, look-aligned, pass-through. Matrix math confirmed via binary analysis (matWorld = matBillboard x matTranslation).

medium
GEN

Reconstruct MemoryManager arena system

10-arena fixed-pool memory model reconstructed: DEFAULT, MAIN_ASSETS, MISSION_ASSETS, CUTSCENE_OR_REWIND, PLAYER_DATA, TEMP, RENDERLIST, SCRATCHPAD, COLLISION_CACHE_ENTRIES, DEFRAGMENTING.

medium
GEN

Implement Scene::ReleaseQuadTreeAndRenderlist (FUN_00896C30)

Quadtree + render-list teardown. Stub has partial logic; needs _895F50 internals and ClearNodesLists verification from Ghidra.

medium
GEN

Implement BestFitAllocator::GetBiggestUsedMemoryBlock + identify stub27/stub29

GetBiggestUsedMemoryBlock returns NULL; stub27/stub29 need real names from vtable analysis.

low
GEN

Engine documentation - memory, rendering, scene systems

Initial docs/ written: memory-system.md (BestFitAllocator internals), rendering-pipeline.md (Dx9 fixed-function, billboard modes), scene-system.md (Scene lifecycle + Update state machine). Commit ab0ab42.

medium

Fair Use & Educational Notice

The Overdose Protocol is a non-commercial, educational preservation project dedicated to reverse-engineering the Kapow Engine from Total Overdose (2005).

By accessing this site, you acknowledge:

  • This project is for educational and preservation purposes only
  • We do not distribute, sell, or provide copyrighted game files
  • Reverse-engineering for documentation falls under fair use protections
  • Respect intellectual property rights of the original creators

For details, see our Legal & Fair Use FAQ.