Warning!
This file is obsolete! Please refer to w3g_format.txt
and w3g_action.txt for current information on V1.6 and up!
Intro
The Warcraft 3 replay file (referred to as W3G from here on) has two
components - a header containing very basic information
and a series of compressed blocks. The real information is in
these compressed blocks - the header has minor information.
W3G Main file
Header
W3G Header Format
|
0x00 | 0x01 | 0x02 | 0x03 |
0x04 | 0x05 | 0x06 | 0x07 |
0x08 | 0x09 | 0x0A | 0x0B |
0x0C | 0x0D | 0x0E | 0x0F |
0x00 | W | a | r |
c | r | a | f | t |
| I | I | I | |
r | e | c |
0x10 | o | r | d |
e | d | | g | a | m |
e | 0x1a | 0x00 |
File offset |
0x20 | File size |
Always 0x00 |
Uncompressed size | Number
blocks |
0x30 | Minor Version |
Major Version | Build
number | 0x00 | 0x80 |
length in ms | Unknown |
- Each file starts with the identifying string "Warcraft III
recorded game\0x1a"
- File offset - this is the position within the file where
the compressed replay data starts. It has been 0x40 in
every file I've seen. 0x40 also corresponds nicely to the
size of the header!
- File size - Size of this .W3G file
- Unencrypted size - the size of the uncompressed replay
data
- Number blocks - the number of uncompressed 8k blocks which
make up this file. More on blocks below.
- Minor Version - Minor version of the War 3 program
- Major Version - This correspond to Patch1.xx so far. This
is needed as pre-1.3 replay files have a different format.
- Build Number - The build version of the War 3
program.
- Length in MS - Length of the replay in miliseconds
Body
The W3G body is comprised of blocks ~4K in size. Each block (in
test) has uncompressed to exactly 8K except for the last block
which is usually a partial block. The blocks start the File
Offset location given above and continue to the end of the
file.
The blocks are compressed using zLib so uncompress using the
same. Make sure to call inflate with the Z_SYNC_FLUSH
option for each block.
W3G Block Format
|
0x00 | 0x01 | 0x02 | 0x03 |
0x04 | 0x05 | 0x06 | 0x07 |
0x00 | Comp. size |
Uncomp. size |
Unknown |
- Comp. size - The compressed size of the block.
- Uncomp. size - The uncompressed size of the block.
- Unknown - probably a checksum - haven't figured it out
yet.
To get the real meat of the replay, just uncompress each block
in turn and put them together to get the file.
Replay File Information
The Replay File itself takes a bit of tracking to get through as
it uses a lot of variable length records so you need to pay
attention to where you are in the file.
The following table lists the high level items in the replay
file. Items in italics repesent abstract forms or
variable length records. Items printed normally take up the
actual amount of space shown in the table.
Replay File High Level
0x00 | 0x01 | 0x02 | 0x03 |
0x04 | 0x05 | 0x06 | 0x07 |
0x10 | 0x01 | 0x00 | 0x00 |
0x00 |
Player Record of Creator
|
Game Name, Null Terminated
String |
16 bytes unknown
|
Map name and creator name,
obfuscated string 0x0001 |
Number Player Slots |
4 bytes unknown |
Player Records
Array |
0x19 | Unknown |
Xtra |
Player Extra Info Array |
4 bytes
Unknown | L/C |
Start |
Player Records
The Player Record appears in two places - the very beginning of
the file where the game creator's record lives and also as an
array after the Map & Creator strings.
The only difference between the two is that in the array, each
record is preceded by a hex 0x16 and has an 0x01 0x00 0x00
0x00 following it. You know the array is done when instead of
reading an 0x16, you read instead an 0x19 which signifies that
the secondary player records follow.
The player records are different sizes depending on if the
game is an official game or custom game. I list here both
forms:
Player Record - AMS
0x00 | 0x01 | 0x02 | 0x03 |
0x04 | 0x05 | 0x06 | 0x07 |
ID | Name
(null-terminated) | 0x08 |
Unknown |
Race | 0x00 | 0x00 | 0x00 |
Player Record - Custom
0x00 | 0x01 | 0x02 | 0x03 |
0x04 | 0x05 | 0x06 | 0x07 |
ID | Name
(null-terminated) | 0x08 | 0x00 |
- ID - Player ID. This is referenced later in the Player
Extra Records. There can be holes in the numbering here.
0x0C (12) is the maximum observed value. The creator's
Player Record has always been observed to be '1'
- Name - A null-terminated string of the players name.
Maximum length is unknown.
- Race - Only stored in official AMS games, this value is
redundant as it is also specified in the Player Extra
Records. See below for possible values.
Game Name
This is a null terminated string of the game name. For AMS
games this always has the observed value of 'BNet', local custom
games has the observed value 'Local Game' and BNet custom games
have the name given to them by their creator.
Map & Creator Name
This is the most confusing part of the replay file. For some
reason, Blizzard did not put the Map & Creator Name in plain
text in the file but rather encoded them (rather simply!). The
two names are encoded as a pair with a single null-byte
separating them.
The strings are encoded by shifting selected characters down
one level in the alphabet. To determine which characters were
shifted, the 2nd byte and then every 8th afterwards contains
encoding information. The first character has not been
observed to be shifted so should always be taken as is. So
the format for the remaining characters is as follows:
Map & Creator Name Encoding
0x00 | 0x01 | 0x02 | 0x03 |
0x04 | 0x05 | 0x06 | 0x07 |
Key | Ch1 | Ch2 | Ch3 |
Ch4 | Ch5 | Ch6 | Ch7 |
And if you expand out the key as a bitmap, you get:
Key Encoding
Bit pos | 0 | 1 | 2
| 3 | 4 | 5 | 6 | 7 |
Char | xx | Ch1 | Ch2 |
Ch3 | Ch4 | Ch5 | Ch6 | Ch7 |
For example, if the Key value was 0xcd and followed by
"MosuUem" then we decode it as follows:
Map & Creator Example Encoding
Bit # | Value | Orig |
Actual |
0 | 1 | Skip |
1 | 0 | M | L |
2 | 1 | o | o |
3 | 1 | s | s |
4 | 0 | u | t |
5 | 0 | U | T |
6 | 1 | e | e |
7 | 1 | m | m |
As you can probably guess, this is for the map LostTemple.
There is one last trick here. You need to count the total
number of bytes so far (the actual character bytes plus the
key bytes). If that number mod 8 is 0 (i.e. the number
is divisible by 8) then you need to skip the next byte.
Otherwise do nothing.
Finally, the byte pair 0x01 0x00 marks the end and separates
this section from the next.
Number Player Slots
This is a 4-byte integer containing the maximum number of player
slots in the replay file. There may not be this many actual
players, but it is the maximum. It is determined in part based
on the game type:
- AMS - This is the exact number of players
- Custom - The number of slots on the Join Game screen
- Single Player Custom - This is always 12
Player Record Array
As mentioned above, the player records show up here. The
maximum number of records is given in Number Player Slots
(1 less actually because the first player record is defined at
the beginning of the file) and the actual number of records is
determined by walking through the data file until an 0x19 is
found at the start of a record.
Xtra
This is a single-byte value that states how many Player Extra
Info records there are. This is an exact number.
Player Extra Info Array
This is an array which stores extra information about each
player. The record size is 8 bytes for versions 1.3 and
greater and 7 bytes for versions less then 1.2. This is
because in version 1.3, the computer difficulty was selectable
so a new byte had to be added to mark the difficulty level of
the computer player in the replay file.
Player Extra Info Record
0x00 | 0x01 | 0x02 | 0x03 |
0x04 | 0x05 | 0x06 | 0x07 |
ID | unk1 | unk2 |
Human | Team | Color | Race |
Diff |
- ID - This is the player ID and corresponds with the Palyer
ID given in the Player Records above. Computer players have
an ID of 0x00. Unused entries also have an ID of 0x00 but
the Human field is set to 0x00.
- unk1 - Unknown value/usage. This value has been observed
to always be 0xFF in AMS games and 0x64 in custom
games.
- unk2 - Unknown value/usage. Appears to be 0x02 for used
slots and either 0x01 or 0x00 for empty slots
- Human - Set to 0x00 for human players and 0x01 for
computer players. If both ID and Human are 0x00 then this
record is not used.
- Team - Starting from 0, this is the team the player is
on. Maximum value is 0x0B (11). A value of 0x0C (12)
specifies the player as an observer.
- Color - Value from 0-11. Adding 1 to this number will
give you the corresponding color in the World Editor. A
value of 12 indicates an observer.
- Race - This is the race selected on the Join Game screen.
Currently there is no way to determine which race a random
player ends up with. Values are:
- 0x01 - Human
- 0x02 - Orc
- 0x04 - NE
- 0x08 - Undead
- 0x20 - Random
- Diff - Difficulty level of the computer player. For human
players this will be always be 0x01. For computers,
0x00=Easy, 0x01=Normal, 0x02=Insane. This field is missing
for versions less then 1.3.
L/C
This byte is set to 0xCC for AMS games and 0x00 for custom
games.
Start
This byte holds the number of start spots on the map.
Comments
Many people have asked about starting location, random race
determination or score information. Currently I do not believe
that is stored in the Replay File but rather recomputed when you
view a replay file. View the discussion on Shadowflare's site
for more info and post there or contact me if you care.
That said, I do believe you can usually determine the
winner of the game based on testing I've done.
HOWEVER, Blizzard does not always get this right as
I've got a replay file which gives the wrong winner.
To Do
- Update this file with hyperlinks
- Better examples
Last Modified: Jun 3, 2003