Deep Dives
Long-form technical writeups that don’t fit the Snippets/Sample Scripts format — full investigations into a hard problem, including the wrong turns, the dead ends that were still worth knowing about, and the final working result. Where Recipes gives you a building block, a Deep Dive gives you the reasoning that got there, so you can adapt the technique to a different problem instead of just copy-pasting the end result.
Available Deep Dives
- Building a Real Freecam — how to get genuine continuous analog stick and d-pad input into a Lua script (something no documented engine API provides), by hijacking the PDA widget’s own input-handling event, and using it to drive a fully controllable detached flying camera.
- Overriding a Function — replacing a piece of the game’s own logic instead of just reading/writing a value, worked through end to end: the original approach, three wrong turns, the fix that actually worked, and the general pattern for applying this technique elsewhere.
- Custom Networked Events — core dispatch confirmed live — mod-authored Lua scripts really can exchange their own custom data across an already-connected co-op session (matchmaking/ connection itself is out of scope, already solved elsewhere): the native callback-by-convention dispatch behind
Net.SendCustomEvent/NetEventCallback, two real constraints discovered along the way (event IDs get masked to a small range, string arguments arrive unreadable), a ping-pong test, and a full catalog of everyNETEVENT_*constant in the decompiled corpus. - A Basic Co-op Text Chat — confirmed working end-to-end across two real players — input, send, and display all fire correctly together over a real network connection; input is backed by the lua-bridge API’s
Loaderkeyboard functions rather than anything achievable in game Lua alone — the one Deep Dive here that depends on lua-bridge itself (v0.1.6+), not just a script. - Building a Chat/Log UI — confirmed working by live testing — a real engine crash bug found in
MrxGuiTextBuffer’s own documented constructor, a scope-sealing dead end while trying to patch around it, and the bug-free internal function that turned out to be the real fix — plus a confirmed static-source-vs-runtime discrepancy inMrxGuiitself. Its display module has since been superseded by UI Kit’sUI.Chat— see the page’s own Update section. - Adding a Custom Contract — research notes, currently broken — registering a mission into
WifMissionDataand Fiona’s briefing menu, confirmed working end to end exactly once (menu, accept, teleport-out, spawn/destroy/reward), plus two hard native-safety rules (dynamic_import/dynamic_removeunsafe to touch beyond normal use; neverreturn fOriginal(...)in a wrapper) discovered the hard way — but the same script permanently breaks the lua bridge when a save spawns the player directly inside the PMC HQ, root cause not yet found. - Building a World Inspector (WAILA) — work in progress — a menu-driven “what am I looking at” mode and bulk nearby-object dump, confirmed working live (cycling, in-world marker, detailed per-object dump), built around a low-radius
Pg.FastCollect*sweep instead of an unconfirmed reticle-targeting native. Documents the hard ceiling hit while chasing a real spawn-template string out of an object (only a hashed localized name is ever reachable), plus three still-open threads it led to:Pg.Spawnonly catching a tiny fraction of real world population, whether any deeper native hook exists for object creation (short answer: not a clean one — see the layer system instead), and an unbuilt “layer delamination” tool for extracting a per-layer object roster. - Making the Destroyer Driveable — partially working — turning the “Chinese Destroyer”/”Allied Destroyer” set-dressing ships into a spawnable, boardable vehicle for both players in co-op, confirmed working for spawning and seat entry/exit. A systematic hardpoint-naming probe, a full
Vehicle.GetSeatParamsdump, and an extensive camera-recipe test matrix (built around the one confirmed live-gameplay camera lock anywhere in the corpus) all come up empty on the two open problems — physics (needs external tooling, not reachable from Lua) and the camera (very likely the same “no Lua touchpoint” category as turret firing itself, already confirmed elsewhere on this wiki). - Custom UI — Authoring Scaleform Movies — experimental, confirmed rendering and driving live in-game — a from-scratch pipeline for building brand-new Scaleform GFx UI movies in pure Python (gfxforge) and injecting them into the WAD (gfx_tool), no Adobe Flash or Scaleform tooling required: vector shapes, imported-font text, buttons, menus, and a two-way
fscommand/CallActionScriptCallbackbridge to Lua, plus the one wrongPlaceObject2flag bit that was causing custom movies to render blank. - Setting Custom World State from OnLoad — experimental, in development — rewriting persistent world ownership state (captured layers, faction attitudes, landing-zone ownership) from an
OnLoadscript instead of the real mission flow, for a territorial-war gamemode that needs every session to start from a custom “all outposts already settled” baseline. Covers whyMrxLayerManager’s layer edits are inert without a manually-drivenMrxState.STATE_WAITFORSTREAMINGreload, the exactEnter/Exitrefcount pairing that reload needs (getting it wrong silently hangs the post-reload fade-in on a black screen — a real bug this hit live), and a “pristine” layer that turned out to be base geometry rather than a status flag, removing it left captured overlays floating over empty ground — another real, confirmed-live bug, now fixed. - Building ForgeCam — a Forge-Mode Placement Tool — confirmed working live — a Halo-Forge-style world editor built on the freecam: fly with the controller, pick a spawn template from a scrolling Scaleform menu with the keyboard, and drop/remove/export placements as a paste-ready table for a runtime spawn director. Settles the question that sat between the freecam and the custom-UI dive (a HUD
FlashWidgetdoes render and takeCallActionScriptCallbackwhile the PDA pauses the world), lays out the performance model of the one callback that ticks under that pause (capture cheap every call, time-gate the heavy work, handle buttons immediately, drain the keyboard withPopKeyEvents), and documents a confirmed engine limitation —Object.SetPositionwon’t move a spawned AI human, so the ghost preview follows by re-spawning instead. - Building Nested Menus with MrxMultiPageMenu — confirmed working live — the native paginating menu every custom menu on this wiki hijacks has no built-in submenu concept at all, just one shared, module-global “current menu.” Nesting is entirely a modder-built pattern: every level is its own
Reset/AddOption/Displaycall, and “Back” is just an ordinary option whose callback rebuilds the parent. Extracted from the real, confirmed four-submenus-deepMasterCheatMenu.lua, including the one genuinely non-obvious part — why the menu-builder functions are bare globals instead oflocal function, and the silent-failure mode (a menu option that quietly does nothing) that ordering mistake would cause the other way. - Building ForgeMenu — a Reusable Nested-Menu Library — new, built on already-confirmed pieces — a small library that reuses the shipped
forge.gfxmovie (the same one ForgeCam/MissionForge drive) to turn nested-menu-building into declaring a plain tree of categories and entries — no widget code, no navigation-stack bookkeeping, none of the bare-global gotcha the native-menu approach requires. Explains the one detail that makes it fundamentally simpler than everything upstream of it: a menu only needs discrete key events, whichLoader.PopKeyEventsalready provides, so it never needs the PDA-pause trick the freecam lineage is built around. - Building MissionForge — a Contract Authoring Tool — new, in development — the in-game half of the Contract Framework’s authoring pipeline, sharing ForgeCam’s menu/input lineage but deliberately inverting its core design: runs in the live, unpaused world instead of a paused one, and never spawns a live preview at all — every placement is an inert marker (a faction supply crate, an empty vehicle, a bare prop, or a zone ring) with the real template recorded separately for export, sidestepping ForgeCam’s spawned-human repositioning problem entirely rather than working around it. Documents two concrete fixes baked into the shipped script: a stray-table-hole bug that silently truncated exports, and a keyboard-polling rewrite that cut bridge calls per tick from 14 to 2.
- Reading and Attaching to Any Bone — confirmed working live — every bone on a character and a vehicle is reachable from Lua by name:
Object.GetHardpointPositionreads any bone’s live world position andObject.Attachparents a spawned object/effect to it so it follows the skeleton. Confirmed on 85 of 89 human bones, all 158 destroyer bones, and by gluing fire/smoke/flare onto hands, fingers, feet, and head. Explains the one insight behind it (hardpoints and skeleton bones are one hashed keyspace, so synthetic collision handles address bones whose real name was never cracked), includes the full 89-bone human skeleton reference, and closes the loop on the turret aim vector the destroyer dive called unreadable — while confirming that same camera wall still holds. - Getting Into Interior Spaces — confirmed working live — three genuinely different things this engine calls an “interior,” easy to conflate: the PMC HQ mansion (a true separate-region layer), the five faction bases (not interiors at all — ordinary open-world locations), and the newest find, each faction’s own walkable HQ office — a worldentity template spawned on demand onto one shared hidden coordinate island. Documents the one real trap (
MrxUtil.SpawnActoris asynchronous — teleport too early and you fall through the floor), every live-confirmed coordinate, and a decoded-from-vz.wadcontents reference for every interior layer block, honestly caveated as a raw string-scan rather than a fully decoded transform. Paired with a ready-to-useGoInside/GoOutsidesnippet. - Cracking the Bone-Name Hashes — method proven, results delivered and cross-validated — where every bone and hardpoint name on this wiki actually came from. The full arc: from an in-game Lua probe brute-forcing strings against a Transport Truck parked in the PMC HQ overnight, to a pair of GPUs solving the last character of the hash algebraically at ~17 trillion candidates a second. Covers the exact
pandemic_hash_m2function (FNV-1a with a case-fold and an “m2” finalize), the one piece of math that caps the whole problem — you cannot out-brute a 32-bit hash, precision = keyspace/2³² — the corroboration principle that makes recovery collision-proof (mirror pairs, consecutive families, joint ids), three collision blunders that had to be caught and undone, and the hard wall a large share of the names sit permanently behind (opaque procedural ids with no authored string, unrecoverable by anything). Final tally: ~47.5% of the ~10,199 distinct hashes now carry a real or best-effort name (the other dev’s own extraction had 6%), and 100% are addressable through a real name or a synthetic hash-matching handle. The prequel to the bone-manipulation dive above.