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:
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\
A null byte, 0x00, to terminate the above string.
The ASCII-encoded string lam.sav (not a typo).
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
Type
Comments
pad(482)
last difficulty
DifficultyOpts: enum(8-bit)
Option
Value
Comments
easy
0x0
normal
0x1
hard
0x2
legendary
0x3
pad(5)
last played scenario
char[32]
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. All data is little-endian unless otherwise stated.
Field
Offset (relative)
Type
Comments
0x0
pad(2)
player details
0x2
PlayerDetails
Field
Offset (relative)
Type
Comments
player name
0x0
UTF-16(24)
The player's name, encoded as UTF-16. Null-terminated with a maximum of 11 characters (excluding the null).
Contains input-related settings, including mouse, keyboard, and gamepad bindings.
Field
Offset (relative)
Type
Comments
invert vertical axis
0x0
bool
Controls if the player's vertical aiming axis controls are inverted, e.g. pulling the mouse down aims up.
0x1
pad(4)
keyboard bindings
0x5
KeyboardBindings
A mapping of 109 keyboard inputs to game functions, 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.
Field
Offset (relative)
Type
Comments
Escape
0x0
Action: enum(16-bit)
Defaults to 0x09 (MenuBack) and is unchangeable. Hardcoded to pause the game.
Option
Value
Comments
Jump
0x0
SwitchGrenade
0x1
Action
0x2
SwitchWeapon
0x3
MeleeAttack
0x4
Flashlight
0x5
ThrowGrenade
0x6
FireWeapon
0x7
MenuAccept
0x8
Keyboard only
MenuBack
0x9
Keyboard only
Crouch
0xA
ScopeZoom
0xB
ShowScores
0xC
Reload
0xD
ExchangeWeapon
0xE
Say
0xF
SayToTeam
0x10
SayToVehicle
0x11
Screenshot
0x12
MoveForward
0x13
MoveBackward
0x14
MoveLeft
0x15
MoveRight
0x16
LookUp
0x17
LookDown
0x18
LookLeft
0x19
LookRight
0x1A
ShowRules
0x1B
ShowPlayerNames
0x1C
F1
0x2
Action: enum(16-bit)
Defaults to 0x0C (ShowScores)
F2
0x4
Action: enum(16-bit)
Defaults to 0x1B (ShowRules)
F3
0x6
Action: enum(16-bit)
Defaults to 0x1C (ShowPlayerNames)
F4
0x8
Action: enum(16-bit)
F5
0xA
Action: enum(16-bit)
F6
0xC
Action: enum(16-bit)
F7
0xE
Action: enum(16-bit)
F8
0x10
Action: enum(16-bit)
F9
0x12
Action: enum(16-bit)
F10
0x14
Action: enum(16-bit)
F11
0x16
Action: enum(16-bit)
F12
0x18
Action: enum(16-bit)
Printscreen
0x1A
Action: enum(16-bit)
Defaults to 0x12 (Screenshot)
ScrollLock
0x1C
Action: enum(16-bit)
PauseBreak
0x1E
Action: enum(16-bit)
Grave
0x20
Action: enum(16-bit)
NumRow1
0x22
Action: enum(16-bit)
NumRow2
0x24
Action: enum(16-bit)
NumRow3
0x26
Action: enum(16-bit)
NumRow4
0x28
Action: enum(16-bit)
NumRow5
0x2A
Action: enum(16-bit)
NumRow6
0x2C
Action: enum(16-bit)
NumRow7
0x2E
Action: enum(16-bit)
NumRow8
0x30
Action: enum(16-bit)
NumRow9
0x32
Action: enum(16-bit)
NumRow0
0x34
Action: enum(16-bit)
EnDash
0x36
Action: enum(16-bit)
Equals
0x38
Action: enum(16-bit)
Backspace
0x3A
Action: enum(16-bit)
Tab
0x3C
Action: enum(16-bit)
Defaults to 0x03 (SwitchWeapon)
Q
0x3E
Action: enum(16-bit)
Defaults to 0x05 (Flashlight)
W
0x40
Action: enum(16-bit)
Defaults to 0x13 (MoveForward)
E
0x42
Action: enum(16-bit)
Defaults to 0x02 (Action)
R
0x44
Action: enum(16-bit)
Defaults to 0x0D (Reload)
T
0x46
Action: enum(16-bit)
Defaults to 0x0F (Say)
Y
0x48
Action: enum(16-bit)
Defaults to 0x10 (SayToTeam)
U
0x4A
Action: enum(16-bit)
I
0x4C
Action: enum(16-bit)
O
0x4E
Action: enum(16-bit)
P
0x50
Action: enum(16-bit)
BracketL
0x52
Action: enum(16-bit)
BracketR
0x54
Action: enum(16-bit)
Backslash
0x56
Action: enum(16-bit)
CapsLock
0x58
Action: enum(16-bit)
A
0x5A
Action: enum(16-bit)
Defaults to 0x15 (MoveLeft)
S
0x5C
Action: enum(16-bit)
Defaults to 0x14 (MoveBackward)
D
0x5E
Action: enum(16-bit)
Defaults to 0x16 (MoveRight)
F
0x60
Action: enum(16-bit)
Defaults to 0x04 (MeleeAttack)
G
0x62
Action: enum(16-bit)
Defaults to 0x01 (SwitchGrenade)
H
0x64
Action: enum(16-bit)
Defaults to 0x11 (SayToVehicle)
J
0x66
Action: enum(16-bit)
K
0x68
Action: enum(16-bit)
L
0x6A
Action: enum(16-bit)
SemiColon
0x6C
Action: enum(16-bit)
Apostrophe
0x6E
Action: enum(16-bit)
Enter
0x70
Action: enum(16-bit)
Defaults to 0x08 (MenuAccept). Keyboard only and unchangeable.
ShiftL
0x72
Action: enum(16-bit)
Z
0x74
Action: enum(16-bit)
Defaults to 0x0B (ScopeZoom)
X
0x76
Action: enum(16-bit)
Defaults to 0x0E (ExchangeWeapon)
C
0x78
Action: enum(16-bit)
V
0x7A
Action: enum(16-bit)
B
0x7C
Action: enum(16-bit)
N
0x7E
Action: enum(16-bit)
M
0x80
Action: enum(16-bit)
Comma
0x82
Action: enum(16-bit)
Period
0x84
Action: enum(16-bit)
Slash
0x86
Action: enum(16-bit)
RShift
0x88
Action: enum(16-bit)
LCtrl
0x8A
Action: enum(16-bit)
Defaults to 0x0A (Crouch)
LWin
0x8C
Action: enum(16-bit)
LAlt
0x8E
Action: enum(16-bit)
Space
0x90
Action: enum(16-bit)
Defaults to 0x00 (Jump)
RAlt
0x92
Action: enum(16-bit)
RWin
0x94
Action: enum(16-bit)
Unchangeable
Menu
0x96
Action: enum(16-bit)
Unchangeable
RCtrl
0x98
Action: enum(16-bit)
UpArrow
0x9A
Action: enum(16-bit)
DownArrow
0x9C
Action: enum(16-bit)
LeftArrow
0x9E
Action: enum(16-bit)
RightArrow
0xA0
Action: enum(16-bit)
Insert
0xA2
Action: enum(16-bit)
Home
0xA4
Action: enum(16-bit)
PgUp
0xA6
Action: enum(16-bit)
Delete
0xA8
Action: enum(16-bit)
End
0xAA
Action: enum(16-bit)
PgDown
0xAC
Action: enum(16-bit)
NumLock
0xAE
Action: enum(16-bit)
Unchangeable
KPDivide
0xB0
Action: enum(16-bit)
KPMultiply
0xB2
Action: enum(16-bit)
Keypad0
0xB4
Action: enum(16-bit)
Keypad1
0xB6
Action: enum(16-bit)
Keypad2
0xB8
Action: enum(16-bit)
Keypad3
0xBA
Action: enum(16-bit)
Keypad4
0xBC
Action: enum(16-bit)
Keypad5
0xBE
Action: enum(16-bit)
Keypad6
0xC0
Action: enum(16-bit)
Keypad7
0xC2
Action: enum(16-bit)
Keypad8
0xC4
Action: enum(16-bit)
Keypad9
0xC6
Action: enum(16-bit)
KeypadMinus
0xC8
Action: enum(16-bit)
KeypadPlus
0xCA
Action: enum(16-bit)
Unknown1
0xCC
Action: enum(16-bit)
Probably KeyPadEnter
KeypadDecimal
0xCE
Action: enum(16-bit)
Unknown2
0xD0
Action: enum(16-bit)
Unknown3
0xD2
Action: enum(16-bit)
Unknown4
0xD4
Action: enum(16-bit)
Unknown5
0xD6
Action: enum(16-bit)
Unknown6
0xD8
Action: enum(16-bit)
mouse bindings
0xDF
MouseBindings
Bindings for the mouse device, similar to the keyboard structure.
Field
Offset (relative)
Type
Comments
Left Button
0x0
Action: enum(16-bit)
Middle Button
0x2
Action: enum(16-bit)
Right Button
0x4
Action: enum(16-bit)
Button 4
0x6
Action: enum(16-bit)
Button 5
0x8
Action: enum(16-bit)
Button 6
0xA
Action: enum(16-bit)
Button 7
0xC
Action: enum(16-bit)
Button 8
0xE
Action: enum(16-bit)
Horizontal Axis -
0x10
Action: enum(16-bit)
Horizontal Axis +
0x12
Action: enum(16-bit)
Vertical Axis -
0x14
Action: enum(16-bit)
Vertical Axis +
0x16
Action: enum(16-bit)
Wheel -
0x18
Action: enum(16-bit)
Wheel +
0x1A
Action: enum(16-bit)
gamepad bindings
0xFB
GamepadBindings
Bindings for gamepads, similar to the keyboard structure. Supports 4 controllers, with each controller's input groups interleaved.
Field
Offset (relative)
Type
Comments
gamepad buttons
0x0
GamepadButtonBindings[4]
Field
Offset (relative)
Type
Comments
Button0
0x0
Action: enum(16-bit)
DirectInput Button 0 (Face - button A)
Button1
0x2
Action: enum(16-bit)
DirectInput Button 1 (Face - button B)
Button2
0x4
Action: enum(16-bit)
DirectInput Button 2 (Face - button X)
Button3
0x6
Action: enum(16-bit)
DirectInput Button 3 (Face - button Y)
Button4
0x8
Action: enum(16-bit)
DirectInput Button 4 (Shoulder - left bumper)
Button5
0xA
Action: enum(16-bit)
DirectInput Button 5 (Shoulder - right bumper)
Button6
0xC
Action: enum(16-bit)
DirectInput Button 6 (Home - back)
Button7
0xE
Action: enum(16-bit)
DirectInput Button 7 (Home - start)
Button8
0x10
Action: enum(16-bit)
DirectInput Button 8 (Analogue - left stick - click)
Button9
0x12
Action: enum(16-bit)
DirectInput Button 9 (Analogue - right stick - click)
Button10
0x14
Action: enum(16-bit)
DirectInput Button 10
0x16
pad(42)
gamepad menu bindings
0x100
GamePadMenuBindings[4]
Field
Offset (relative)
Type
Comments
menu accept
0x0
DirectInputButtons: enum(16-bit)
Holds the button ID used to accept menu selections.
Option
Value
Comments
Button0
0x0
Face - button A
Button1
0x1
Face - button B
Button2
0x2
Face - button X
Button3
0x3
Face - button Y
Button4
0x4
Shoulder - L shoulder, white
Button5
0x5
Shoulder - R shoulder, black
Button6
0x6
Home - back
Button7
0x7
Home - start
Button8
0x8
Analogue - left stick - click
Button9
0x9
Analogue - right stick - click
Button10
0xA
Button11
0xB
Button12
0xC
Button13
0xD
Button14
0xE
menu back
0x2
DirectInputButtons: enum(16-bit)
Holds the button ID used to go back in menus.
gamepad axis set
0x110
GamepadAxisBindings[4]
Field
Offset (relative)
Type
Comments
Axis1Pos
0x0
Action: enum(16-bit)
DirectInput Axis 1 (Analogue - left stick - down)
Axis1Neg
0x2
Action: enum(16-bit)
DirectInput Axis 1 (Analogue - left stick - up)
Axis2Pos
0x4
Action: enum(16-bit)
DirectInput Axis 2 (Analogue - left stick - right)
Axis2Neg
0x6
Action: enum(16-bit)
DirectInput Axis 2 (Analogue - left stick - left)
Axis3Pos
0x8
Action: enum(16-bit)
DirectInput Axis 3 (Analogue - right stick - down)
Axis3Neg
0xA
Action: enum(16-bit)
DirectInput Axis 3 (Analogue - right stick - up)
Axis4Pos
0xC
Action: enum(16-bit)
DirectInput Axis 4 (Analogue - right stick - right)
Axis4Neg
0xE
Action: enum(16-bit)
DirectInput Axis 4 (Analogue - right stick - left)
Axis5Pos
0x10
Action: enum(16-bit)
DirectInput Axis 5 (Shoulder - trigger - left)
Axis5Neg
0x12
Action: enum(16-bit)
DirectInput Axis 5 (Shoulder - trigger - right)
Axis6Pos
0x14
Action: enum(16-bit)
DirectInput Axis 6+
Axis6Neg
0x16
Action: enum(16-bit)
DirectInput Axis 6-
0x18
pad(104)
gamepad dpad buttons
0x310
GamepadDirPadBindings[4]
Field
Offset (relative)
Type
Comments
DirPadUp
0x0
Action: enum(16-bit)
Directional - up
0x2
pad(2)
DirPadRight
0x4
Action: enum(16-bit)
Directional - right
0x6
pad(2)
DirPadDown
0x8
Action: enum(16-bit)
Directional - down
0xA
pad(2)
DirPadLeft
0xC
Action: enum(16-bit)
Directional - left
0xE
pad(242)
0x80B
pad(26)
horizontal mouse sensitivity
0x825
uint8
Ranges in value from 0 (minimum) to 10 (maximum).
vertical mouse sensitivity
0x826
uint8
Ranges in value from 0 (minimum) to 10 (maximum).
gamepad horizontal sensitivities
0x827
uint8[4]
An array of 4 controller horizontal aiming sensitivities. Index using 0 for the first controller, 1 for the second, etc.
gamepad vertical sensitivities
0x82B
uint8[4]
An array of 4 controller vertical aiming sensitivities. Index using 0 for the first controller, 1 for the second, etc.
0x95E
pad(266)
video settings
0xA68
VideoSettings
Field
Offset (relative)
Type
Comments
resolution width
0x0
uint16
resolution height
0x2
uint16
refresh rate
0x4
uint8
Will take the literal values 59 (0x3B) or 60 (0x3C)
unknown
0x5
pad(2)
Has a value of 0x00 0x02
frame rate
0x7
FrameRateOptions: enum(8-bit)
Option
Value
Comments
vsync off
0x0
vsync on
0x1
30 FPS
0x2
specular
0x8
bool
shadows
0x9
bool
decals
0xA
bool
particles
0xB
ParticlesSettings: enum(8-bit)
Option
Value
Comments
off
0x0
low
0x1
high
0x2
texture quality
0xC
QualityOptions: enum(8-bit)
Option
Value
Comments
low
0x0
medium
0x1
high
0x2
0xD
pad(1)
gamma
0xE
uint8
Options: +1 (0xD8), +2 (0xDF), +3 (0xE6)
0xF
pad(1)
0xA78
pad(256)
audio settings
0xB78
AudioSettings
Field
Offset (relative)
Type
Comments
master volume
0x0
uint8
effects volume
0x1
uint8
music volume
0x2
uint8
enable EAX
0x3
bool
enable hardware acceleration
0x4
bool
sound quality
0x5
QualityOptions: enum(8-bit)
0x6
pad(1)
audio variety
0x7
QualityOptions: enum(8-bit)
0xB80
pad(524)
network settings
0xD8C
NetworkSettings
Field
Offset (relative)
Type
Comments
server name
0x0
UTF-16(64)
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).
0x40
pad(224)
password
0x120
UTF-16(18)
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)
0x132
pad(1)
max players
0x133
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.
0x134
pad(256)
connection type
0x234
ConnectionTypes: enum(8-bit)
Option
Value
Comments
56k
0x0
dsl-low
0x1
dsl-avg
0x2
dsl-high
0x3
t1/lan
0x4
0x235
pad(1)
server address
0x236
UTF-16(64)
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
0x276
uint16
Defaults to the value 2302
client port
0x278
uint16
Defaults to the value 2303
0x1006
pad(258)
gamepad info
0x1108
GamepadInfo[4]
Field
Offset (relative)
Type
Comments
gamepad name
0x0
UTF-16(512) LE/BE
Stores the name of the controller device seen when configuring button bindings (if configured). UTF-16 String; can be little-endian ("Xbox Controller S via XBCD") or big-endian ("Xbox 360 Controller For Windows"). The size of this buffer is unknown, so 512 bytes is assumed. When Halo detects two devices with the same name, the second one will have " (2)" appended to its name.
0x200
pad(12)
This padding size is unknown and depends on the above buffer's size.
vendor ID
0x20C
uint16
4-digit hex identifying the vendor/manufacturer of the gamepad. For example, 045E is Microsoft. This would be little-endian encoded as 5E 04. A list of hardware vendor IDs can be found here.
product ID
0x20E
uint16
4-digit hex identifying the gamepad product. For example, 0289 (89 02 little-endian) is the Xbox Controller S. Devices by vendor can be found here (Microsoft).
0x210
pad[6]
Zeroed-out values
pidvid
0x216
char[6]
An ASCII string with value "PIDVID"
dupe ID
0x21C
uint8
Distinguishes multiple gamepads with the same vendor and product ID. Takes the value 0x00, then 0x01, etc.
0x21D
pad(3)
0x1988
pad(1652)
Unknown region
crc32 hash
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.
Acknowledgements
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)
nToss (Researching offsets for profile input bindings and other fields)