The Xbox game allows 16 players on 4 machines (4 split screen players each). The native builds raise both limits to 128, keeping 4 players per machine, and leave the byte-matching build unchanged: every change is under HALO_LINUX (the MSVC objects compare identical). - Limits: every local copy of the player and machine limits, and the bare 4s and 16s that stood for them, follow halo_port_limits.h. The player data array, the machine-to-player table (and its reset) and the per-tick update arrays grow with them. - Records: the copies of struct network_game agree on the larger layout and check it against halo_port_limits.h; maximum_player_count becomes a byte (128 does not fit a signed char); network_player_is_valid checks the machine against the machine limit, not the split screen one; a machine's input carries MAXIMUM_LOCAL_PLAYERS actions (16/4 would have become 128/128). - Protocol: a message holds at most 4095 bytes (its header has a 12-bit length), so the 13 KB game settings record is sent in 3.5 KB pieces that clients reassemble; the per-tick update of 128 players (3,857 bytes) fits. Buffers and the packet codec's limits grow to match, and the game search uses protocol version 2 so these builds and the Xbox game never see each other's games. - Connections: the host accepts a client connection per machine (the split screen count stood in for it), FD_SETSIZE is 256, stream writes send all of a message or drop a peer that stops reading instead of corrupting the stream, and the input and update queues are larger. - Host: lobby changes are sent at most every 250 ms instead of on every change (a full lobby would otherwise send ~650 MB), in-game joins wait in a queue instead of being dropped, the random name and colour pickers stop looping forever once names or colours run out, machines get 60 s to load a map, and the debug dump lists only the slots in use (128 empty slots took seconds to log). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Halo 1 decomp, ported to Linux
This is a port of the decompilation of Halo: Combat Evolved build 2342 (cachebeta.exe, sha256 4cc87b45f721270392a96f1674ed2b5cd4a7bb4355faeab4531d1cf1884d9520) to Linux.
This is based on bnunu's decompilation project, which itself is a fork of punpckhdq/halo.
Agent quick references
- Current campaign house rules and batch/treemap cadence
- Common constants, types, float patterns, tag IDs, and flag conventions
- Shared assertion macros and byte-matching examples
- Supplied CE source maps, recovered names, and next reconstruction packets
- Matching methodology and source-credibility rules
Build instructions
You must source the August 2001 Xbox SDK yourself, and you need Python and ninja-build on your PATH. Extract the XDK/xbox folder from the installer into the repository root such that xbox/{bin,include} are valid paths, then run configure.py from the repository root.
Native Linux build
ninja linux compiles the game with clang into a native 32-bit Linux executable, build/linux/halo. It needs clang, 32-bit glibc development files and 32-bit SDL3. It renders with OpenGL, plays sound through SDL3 audio, and takes keyboard, mouse and gamepad input. Put the PAL game data (build 01.01.14.2342) under assets/ so that assets/maps exists, then run build/linux/halo. See port/linux/README.md for controls and settings.
Debug and release
The native builds (Linux, Windows, Android) are debug builds by default: like the build the decompilation reproduces, they stop at the first failed assertion and log it. python configure.py --release configures release builds instead, which, like the retail game, do not check assertions. The byte-matching build is unaffected.
Frame rate
The native builds draw a frame at every refresh of the display (60, 90, 120, 240 Hz, ...), paced by vsync, while the game still simulates at 30 Hz as on the Xbox: each frame blends the last two ticks. To see the frame rate, open the developer console (the ` key) and enter display_framerate true; the frames per second, averaged over half a second, appear at the bottom right of the screen. HALO_INTERPOLATION=0 restores the original 30 frames per second. See port/linux/README.md.
Native Windows build
ninja windows, run on Windows, compiles the game with clang into a native 32-bit Windows executable, build/windows/halo.exe (with SDL3.dll), sharing the Linux build's platform layer. It needs LLVM, Python and ninja, plus Visual Studio's x86 C++ libraries and a Windows SDK. Put the game data under assets/ as for Linux. See port/windows/README.md.
Android build
ninja android_apk builds an arm64 Android app (port/android/app/build/outputs/apk/debug/app-debug.apk) that runs the game natively on 64-bit ARM phones, with OpenGL ES 3 rendering at the device's aspect ratio, SDL3 audio and game controller support (including a PS5 DualSense over Bluetooth). It needs the Android NDK and a clang with the arm64_32 target in addition to the Linux build's requirements. The game data goes in the app's storage (the app offers to import it). See port/android/README.md.
Matching build
The byte-matching build also needs cachebeta.exe from the Halo 1 PAL debug build in the repository root. Run ninja to compile the game and report progress statistics. On Linux it runs the XDK compiler through wibo (downloaded automatically), assembles the CRT .asm units with UASM when no MASM is available, and builds csplit from source; see port/linux/README.md.
Where's all the type information?
We use debug symbols from later Halo games to help map structures, enums, type definitions, function signatures and some variable names. You should obtain a copy of the Halo CEA beta and run it through pdb-decompiler to obtain debug info for yourself. Note that CEA is based off of Halo PC and has its own modifications which make it not 100% accurate to the original Xbox title.