Releases: gigaHours/Gibbed.MadMax
Release list
Gibbed.MadMax-1.6.0
Highlights
This release migrates the entire solution to .NET 8.0, adds ADF serialization (import) support, and introduces two new command-line tools for modding workflows.
What's New
.NET 8.0 Migration
- All projects now target
net8.0, replacing the legacy .NET Framework 4.8 / multi-target builds. - Removed legacy
AssemblyInfo.csfiles andapp.configfiles in favor of SDK-style project conventions. - Added
Directory.Build.propsfor unified output path configuration. - Solution file cleaned up and modernized.
ADF Serializer (Import Support)
AdfFile.Serialize()is now fully implemented — ADF files can be written back to binary, enabling round-trip editing workflows.ConvertAdfimport mode is no longer a stub — XML-to-ADF conversion is fully functional.- Type definitions are now exported to and imported from XML (
<typedefs>section). - Instance metadata (
nameHash,typeHash) is preserved in XML output for lossless round-trips. RuntimeTypeLibrarygainedGetTypeDefinitionByName()for type lookups during import.
New Tool: Gibbed.MadMax.BinarySearch
- Search for byte patterns across game archive files with support for little-endian, big-endian, or both.
- Multi-threaded search with configurable patterns.
New Tool: Gibbed.MadMax.ResolveHashes
- Resolve hash values in XML files using project hash lists.
- Supports in-place replacement with optional comment annotations showing original hashes.
Bug Fixes
BytesVariant.Parse(): Fixed off-by-one iteration bug (i += 2→i++) that skipped every other byte when parsing comma-separated byte values.BytesVariant.Parse(): Added null/empty string handling to avoid crashes on empty byte arrays.SmallUnpack: Replaced deprecatedAssembly.CodeBasewithAssembly.Locationfor .NET 8.0 compatibility.ProjectData: AddedPlatformNotSupportedExceptionhandling for cross-platform compatibility.ConvertAdfexport: Output path now appends.xmlinstead of replacing the extension, preserving original filenames likefile.adf.xml.
Gibbed.MadMax-1.5.6
Here's a release note:
ConvertProperty: Fix crash on empty vec_byte values
Fixed a FormatException crash when converting RTPC properties containing empty vec_byte fields (e.g. _decoration_info in CRoadObject).
Also fixed a pre-existing bug where BytesVariant.Parse only read every other byte (i += 2 instead of i++), silently corrupting multi-byte values during round-trip.
Gibbed.MadMax-1.5.5
Bug Fixes
Fix: Library modules broken after decompile/recompile
Library modules (lib_*.xvmc) use flags: 0x1 to register their functions as globals so other scripts can call them. This flag was silently dropped during decompilation, causing recompiled library modules to stop working — any script depending on them would fail at runtime.
29 out of 842 game scripts are affected (all lib_*.xvmc files).
The decompiler now emits #! flags: 0x1 automatically, and the compiler preserves it through to the output .xvmc.
Fix: Missing trailing ret 0 sentinel
The compiler omitted the trailing ret 0 when a function's last statement was already a return. This caused the decompiler's CFG builder to lose if blocks whose jump targets pointed past the last instruction.
Fix: break statement and structural analysis
- Added
breakstatement support insidewhileloops - Fixed while-loop exit block causing post-loop code to be absorbed into the loop body
- Fixed elif chains breaking when the merge point coincided with an outer loop exit
Fix: stitem stack order
The decompiler and compiler had the wrong pop/push order for index store operations (obj[idx] = val), producing invalid code for scripts using indexed assignment.
New Directive: #! flags:
The #! flags: directive is emitted automatically by the decompiler for library modules. It is not gated by --hashes because it affects runtime behavior.
| Value | Meaning | Files in game |
|---|---|---|
0x0 |
Standard script | 813 |
0x1 |
Library module | 29 |
Known Differences (non-functional)
Round-tripped files may differ from originals in constant ordering, StringBuffer layout, max_stack values (precise vs over-estimated), and omission of dead-code jmp instructions after ret. All differences are functionally equivalent.
Gibbed.MadMax-1.5.4
Fix: Compiler missing trailing ret 0 sentinel
Bug: The compiler omitted the implicit ret 0 at the end of functions when the last statement was already a return. This caused jz/jmp labels targeting the end of the function to point past the last instruction (out-of-bounds). On subsequent decompilation, the CFG builder couldn't create a block for the invalid target, reducing a 2-successor jz block to 1 successor — which made the decompiler silently drop if guards.
Impact: Any function ending with if ...: return ... (no else) would lose the if condition on round-trip, turning conditional returns into unconditional ones.
Examples from enemy_boarding_gameplay.xvmc:
GetPositionSB— thirdif 1.0 == GetStateBit(char, 22.0): return 22.0became unconditionalreturn 22.0(function now returns22.0even when no state bit is set, instead ofnone)CheckAttackLock—if local2 and local3:guard was dropped, causingGetBlackboardValueFromObjectto be called with a potentially null vehicle reference
Fix: Always emit ret 0 at the end of every function, matching the Avalanche compiler behavior. One line changed in CodeGenerator.cs.
Gibbed.MadMax-1.5.3
Release 1.5.3
break statement support + decompiler bug fixes
New feature: break keyword
- The
breakstatement is now fully supported in the decompiler, compiler, and round-trip pipeline - Exits the enclosing
whileloop, matching Python semantics
Decompiler fixes (StructuralAnalysis):
- Fixed
breakinsidewhileloops — previously emitted aspass, causing all post-loop code to be absorbed into the loop body. Scripts likelib_vehicleupgrades.xvmc(RecomputeGearbox) produced functionally broken output when recompiled. - Fixed
elifbody absorbing subsequent statements —FindLinearEndcould advance past the stop block, causing code after anif/elifchain to be pulled inside the last branch (e.g. MassCompensateSuspensionLength). - Fixed
elifchains collapsing into nestedifs — merge point detection failed when the merge coincided with the outer exit block, breaking flatelifchains into deeply nestedifblocks with misplacedreturnstatements (e.g. DiminishingReturnsProgression).
StoreItem bug fix:
- Fixed
stitemstack order in both the decompiler (ExpressionRecovery) and compiler (CodeGenerator). The XVM convention ispush value, push obj, push index→stitempopsindex, obj, val.
Batch directory mode:
- Decompiler and compiler now accept a directory as input, recursively processing all
.xvmc/.xvmfiles. Supports drag-and-drop of folders onto the.exe.
Affected files:
StructuralAnalysis.cs— region-based control flow recovery with break supportAst.cs/AstPrinter.cs—BreakStmtAST nodeToken.cs/Lexer.cs/Parser.cs/CodeGenerator.cs—breakcompilationExpressionRecovery.cs/CodeGenerator.cs—stitemstack order fixXvmDecompile/Program.cs/XvmCompile/Program.cs— batch directory mode
Gibbed.MadMax-1.5.2
What's New
Bug Fixes
- Fixed
stitem(StoreItem) stack order in both decompiler and compiler — the XVM stack convention for indexed assignment (obj[index] = value) was incorrectly handled, causing decompilation of scripts with array/list indexing operations (e.g.lib_vehicleupgrades.xvmc) to produce invalid code that could not be recompiled
New Features
- Batch directory mode for
XvmDecompileandXvmCompile— drag a folder onto the.exeor pass a directory path to recursively process all.xvmc/.xvmfiles. Reports success/failure counts on completion
Documentation
- Fixed
stitemstack order documentation across all XVM reference docs and assembly guides - Added batch mode usage instructions
- Updated tool descriptions in README (EN/RU) and project documentation
Full Changelog: updated-1.5.1...1.5.2
Gibbed.MadMax-1.5.1
What's New
🔄 Decompiler & Compiler
- XvmDecompile — decompile
.xvmcbytecode to high-level Python-like.xvmsource - XvmCompile — compile
.xvmsource back to.xvmcbytecode - Full round-trip: decompile → edit → compile → drop into game
✨ Compiler Features
- Auto-computed function name hashes (Jenkins lookup3)
- Auto-computed
source_hash,max_stack, andlocals - Debug info generation (line:column per instruction)
- Constant folding for negative float literals
#! hash:/#! source_hash:directives for exact binary reproduction
🐛 Bug Fixes
- Fixed Jenkins hash for strings with length divisible by 12 (e.g.
DisableBoost) - Fixed
importHashesnot being assigned duringXvmModule.Deserialize()
📖 Documentation
- Complete XVM language reference (English | Russian)
- Full engine API reference in
xvm_globals.txt— 49 modules, 900+ methods with type signatures - Updated README with high-level and low-level workflow examples
Workflow
Decompile
Gibbed.MadMax.XvmDecompile.exe script.xvmc script.xvm
Edit the .xvm file...
Compile
Gibbed.MadMax.XvmCompile.exe script.xvm script.xvmc
Drop into game
copy script.xvmc /dropzone/scripts/...
Gibbed.MadMax-1.5
Changes
- XvmAssemble — assembles
.disfiles back into.xvmcbytecode with full ADF packaging - debug_info round-trip — disassembler emits
@line:colannotations, assembler rebuilds thedebug_infoADF instance (type0xDCB06466). The game requiresdebug_infofor proper script execution - debug_strings round-trip — attribute/global names preserved through disassembly and reassembly
- Bug fix —
ImportHasheswere silently dropped duringXvmModule.Deserialize()(read to local variable but never assigned to the module)
Known Differences vs Original Binaries
Reassembled .xvmc files are functionally identical to originals. Minor binary-level differences (constant ordering, StringBuffer layout, StringHashes count) do not affect script execution.
Documentation
Please refer to the project documentation before use:
- XVM Assembly Guide (EN) — complete instruction reference, examples, workflow
- XVM Assembly Guide (RU) — то же на русском
- Documentation (RU) — full project documentation including XVMC/debug_info format details
Gibbed.MadMax-1.3
- Update Serialize/Deserialize
vec_eventstype (ConvertProperty.exe)- Deserializing with hash lookups
- Serializing from string to hash
- if a string starts with
0xor0X, then this is considered as a direct serialization from the hexadecimal representation
- if a string starts with
- Fixed a bug with reading
.binfiles (Raw Property)- fixed reading a matrix from
3x4to4x4
- fixed reading a matrix from
if you edited a file opened by a previous version, it must be reopened!
Gibbed-Updated-1.2
Fixed ConvertProperty (.blo -> .xml -> .blo)
- Fix invalid matrix type (
4x3->4x4) - Fix Alignment PropertyFormats
If you converted to xml on the old version, you need to convert the original file again!
