Game and profile files

This page documents the function and format of some of Halo's installation and profile files, excluding maps.

haloce.exe #

This is the main game executable containing the bulk of the game's code.

By default, Halo is only permitted to use 2 GB of virtual memory. By applying value 0x2F at offset 0x136 in the 1.0.10 executable, Halo can be made "Large Address Aware" and capable of using up to 4GB of virtual memory. The same upgrade can be made to Sapien. The increased limit can be useful for client mods like Chimera which run in the game's address space and allocate more memory to speed up map loading.

strings.dll #

The library strings.dll is required to run the game or dedicated server. It serves multiple purposes:

  • Contains the loading screen image seen before the main menu (all other loading screens are contained in maps).
  • Displays crash messages in a window.
  • Prior to the 1.10 patch, it contained the executable_is_valid checksum.

This DLL is often replaced with a modified version for mods like SAPP and Chimera 1.0+.

Watson #

The Watson directory and the files within it (dw15.exe, various dwintl.dll) are a defunct crash reporting system. The server to which crash reports would be sent is no longer running. The mod Chimera disables this to allow the game to crash faster without waiting for a network timeout.

Multiplayer chat: Keystone, controls, and content #

An example modified chat editbox, a practice abandoned after mods implemented better chat systems.

The library Keystone.dll is used for Halo's stock multiplayer chat functionality. The game also requires the library msxml.dll to be installed on the system for chat to display properly. An installer can be found in Halo's redist directory.

The controls directory is host to Controls.ini and Controls.dll, a library used to render the multiplayer chat input box. It makes use of files in the content directory, which can be modified to customize the appearance of the chat "editbox" and text input.

The mods HAC2 and Chimera implement their own chat display to replace Halo's, which becomes unreliable after tabbing out of the game.

Profile and savegame files #

Halo stores savegames and profile data according to the system-wide %USERPROFILE% environment variable. On Windows, with a system drive "C" and user name "John", Halo saves can be found in C:\Users\You\Documents\My Games\Halo CE\. When running on Linux under Wine, the default location is ~/My Games/Halo CE/. Some mods also store data under this location, such as downloaded maps.

lastprof.txt #

The file lastprof.txt stores the path of the last used profile so it can be loaded at game startup. It has a fixed length of 256 bytes and a very simple structure:

  1. An ASCII-encoded absolute filesystem path to a profile directory, with trailing \. For example, C:\Users\You\My Documents\My Games\Halo CE\savegames\New001\
  2. A null byte, 0x00, to terminate the above string.
  3. The ASCII-encoded string lam.sav (not a typo).
  4. 0x00 padding until the end of the file.

savegame.bin #

The file savegames\<profile name>\savegame.bin contains the saved state of the campaign, allowing progress to be resumed when reloading from a checkpoint or returning from the main menu. The Halo console commands game_save and game_revert use this file. A newly-created savegame.bin is typically filled with NULL to 0x480000 (4,718,592 bytes).

The structure of this file is not fully mapped out, however some fields are known:

Field Offset Type Comments
Last difficulty 0x1E2 uint8
Option Value
Last played scenario 0x1E8 ASCII string An ASCII-encoded scenario tag path, null-terminated and 32 characters max. An example value is levels\b30\b30 for The Silent Cartographer.

blam.sav #

The file savegames\<profile name>\blam.sav contains the configuration for a HCE profile. Information includes player details, video/audio/network settings, and input configurations (mouse, keyboard, and controller). It has a fixed length of 8192 bytes (8 KiB). File integrity is verified by a checksum at the end of the file; if the checksum does not match the game will fall back to default settings.

The file structure follows, but is known to be incomplete:

Section Field Offset Type Comments
Profile Name 0x0002 utf-16 string The player's name, encoded as UTF-16. Null-terminated with a maximum of 11 characters (excluding the null).
Colour 0x011A uint8

Determines the player's multiplayer armour colour.

Option Value
Random (default)0xFF
Controls Invert vertical axis 0x012F bool
Keyboard bindings 0x0134-0x020D binding array

An array of 109 keyboard input mappings, each a little-endian uint16 (2 bytes long). The entries are ordered roughly like the rows of a QWERTY keyboard, with each position in the array corresponding to a certain input key. If a key is unbound, then that position holds the bytes 0x7F 0xFF. Otherwise, bound keys store a value representing the game function the key is mapped to, for example 0x05 0x00 for flashlight.

Some example key offsets are:

Offset Key

The following are some example bindings which can appear at these locations. Remember that these values are stored in little-endian form in the file, so 0x0013 becomes the bytes 0x13 0x00.

Value Function
0x0013Move Forward
0x0014Move Backward
0x0015Move Left
0x0016Move Right
0x0017Look Up
0x0018Look Down
0x0019Look Left
0x001ALook Right
Gamepads and other devices 0x020E-0x93A binding array

Similar to above, but a much larger array for all other types of mappable input devices such as gamepads. It is not known what all the devices and their inputs are, but some are mapped:

Device Offset Input
Mouse0x20ELeft Button
0x210Middle Button
0x212Right Button
0x214Button 4
0x216Button 5
0x218Button 6
0x21AButton 7
0x21CButton 8
0x21EHorizontal Axis -
0x220Horizontal Axis +
0x222Vertical Axis -
0x224Vertical Axis +
0x226Wheel -
0x228Wheel +
Unknown 0x0953 uint8
Horizontal sensitivity 0x0954 uint8 Ranges in value from 0 (minimum) to 10 (maximum).
Vertical sensitivity 0x0955 uint8 Ranges in value from 0 (minimum) to 10 (maximum).
Video Horizontal resolution 0x0A68 uint16 This value is little-endian, for example the value 1280 is encoded as the bytes 0x00 0x05.
Vertical resolution 0x0A6A uint16 This value is little-endian, for example the value 960 is encoded as the bytes 0x03 0xC0.
Refresh rate 0x0A6C uint8 Options: 59 (0x3B), 60 (0x3C)
Unknown 0x0A6D pad(2) Example value: 0x00 0x02
Frame rate 0x0A6F uint8 Options: vsync off (0x0), vsync on (0x1), 30 FPS (0x2)
Specular 0x0A70 bool
Shadows 0x0A71 bool
Decals 0x0A72 bool
Particles 0x0A73 uint8 Options: off (0x0), low (0x1), high (0x2)
Texture quality 0x0A74 uint8 Options: low (0x0), medium (0x1), high (0x2)
Gamma 0x0A76 uint8 Options: +1 (0xD8), +2 (0xDF), +3 (0xE6)
Audio Master volume 0x0B78 uint8 Ranges in value from 0 (minimum) to 10 (maximum).
Effects volume 0x0B79 uint8 Ranges in value from 0 (minimum) to 10 (maximum).
Music volume 0x0B7A uint8 Ranges in value from 0 (minimum) to 10 (maximum).
Sound quality 0x0B7D uint8 Options: low (0x0), medium (0x1), high (0x2)
Sound variety 0x0B7F uint8 Options: low (0x0), medium (0x1), high (0x2)
EAX 0x0B7B bool
Hardware acceleration 0x0B7C bool
Network Server name 0x0D8C utf-16 string Stores the last-used hosting server name for the "create game" menus (both LAN and Internet). Null-terminated with a maximum of 31 characters (excluding the null).
Password 0x0EAC utf-16 string Stores the last-used hosting password for the "create game" menus (both LAN and Internet). Null-terminated with a maximum of 8 characters (excluding the null).
Max players 0x0EBF uint8 Stores the last-used max players for hosting a server. The value 0x00 actually corresponds to the minimum of 2 players, with 0x0E being the maximum of 16.
Connection type 0x0FC0 uint8 Options: 56k (0x0), dsl-low (0x1), dsl-avg (0x2), dsl-high (0x3), t1/lan (0x4)
Server address 0x0FC2 utf-16 string Stores the default server address for Direct IP connections. This value could contain an IP and port separated by a ":" or even a DNS host name. Encoded as UTF-16, null-terminated with a maximum of 31 characters (excluding the null).
Server port 0x1002 uint16 This value is little-endian, for example the value 2302 is encoded as the bytes 0xfe 0x08.
Client port 0x1004 uint16 This value is little-endian, for example the value 2303 is encoded as the bytes 0xff 0x08.
Other CRC32 checksum 0x1FFC uint32 The blam.sav has a CRC-32 checksum appended at the end of it. The value is actually stored in its complement equivalent (i.e. bitwise NOT). The checksum validates the data between 0x000 and 0x1FFC - the checksum itself is not included! There is a relatively large amount of padding before this field, and it is the final 4 bytes of the file. Due to the complement on this field, the entire file will always have a CRC of 0xFFFFFFFF. Therefore the file can be verified by either comparing its overall CRC to 0xFFFFFFFF, or comparing the CRC of its prior sections to the complement of this field.

00.sav and 01.sav #

In saved\player_profiles\default_profile there are two files, 00.sav and 01.sav with the same player profile structure as blam.sav. However, these files contain empty or default values only. They have default key bindings and no controller bindings. The 01.sav file differs from 00.sav in only three ways:

  • An unknown field at offset 0x11D is set to true.
  • The invert Y axis field at offset 0x12F is set to true.
  • The checksum differs due to the above differences.

Halo overwrites or creates these files with their original contents every time the game starts. Replacing their contents with other profile data and forcing the files to be read-only does not have any effect on default profile creation, default bindings, or controls used when loaded into a map before first profile creation. Their purpose is a mystery.


Thanks to the following individuals for their research or contributions to this topic:

  • Conscars (Additional blam.sav reversing)
  • Miris (Profile and savegame reversing, LAA patch)
  • MrChromed (Loading screen tip)
  • Sparky (Control binding ranges)
  • Vaporeon (Watson and strings.dll background)