General Structure

This document defines the general structure of the protocol.

Test Setup

The test environment consists of 4 hosts to simulate a 4-player multiplayer game. Each host was equipped with:

  • Ubuntu 17.04

  • Age of Empires 2: The Conquerors 1.0c

  • Wine 1.8.7

  • Wireshark 2.2.6

One game was established by using the DirectPlay feature, while all other play sessions were established over LAN. There is no detectable difference for the communication protocol and DirectPlay is only used for the purpose of connecting players.

Transport Protocols

The game utilizes TCP to let players connect to a play session and UDP for all game configuration and ingame communications. This is not surprising, since UDP has the advantage of lightweight packets and therefore fast communication. This document will focus on the interesting part of the packets, i.e. the UDP data field.

Packet Types

There are 3 basic types of packets; sync packets, chat message packets and (player) action packets. Sync packets are used to synchronize communication turns, determine turn timers, calculate latency and validate the game state. Chat message packets transport everything the players type in the ingame or lobby chat over the network. The last type discussed in this documentation are the action packets which are utilized for commands from a player or an AI (e.g. movement, unit training).

Sync packets can be further categorized into periodic (sent in regular intervals) and non-periodic packets. Most of the network communication during a multiplayer game consists of synchronization data.

Packets are recognized by a one byte long “command byte” in the header. So far 12 different network commands have been identified.

Command Purpose
0x31 Sync
0x32 Sync
0x35 Sync (Lobby)
0x3e Player-issued
0x41 Sync
0x43 Chat Message
0x44 Sync
0x4d Sync
0x51 De-Sync
0x52 Readying (Lobby)
0x53 Sync
0x5a Lobby

All packets with command 0x3e have a second “command byte” after the header that represents the command a player has given ingame. To avoid confusion, we will call all player-issued commands “actions” and reserve the term “commands” for the actual network commands seen above. Furthermore, the identifier for a player’s action will be called “action byte”. 34 of these can be found in network packets.

Action Purpose
0x00 Primary Action (Attacking, Resource gathering, Boarding Transport Ship)
0x01 Stop
0x02 Primary Action (AI)
0x03 Move
0x0a Move (AI)
0x0b Resign
0x10 Set waypoint
0x12 Stance
0x13 Guard
0x14 Follow
0x15 Patrol
0x17 Formation
0x1b Save & Exit
0x1f Coordinated Move (AI)
0x64 Train unit (AI)
0x65 Research
0x66 Build
0x67 Diplomacy/Cheats/Change Speed
0x69 Build wall
0x6a Delete
0x6b Attack ground
0x6c Tribute
0x6e Repair
0x6f Unboard/Ungarrison
0x72 Toggle gate
0x73 Flare
0x75 Garrison/Stop building unit
0x77 Train unit (Human)
0x78 Rally point
0x7a Sell
0x7b Buy
0x7e Drop relic
0x7f Toggle townbell
0x80 Back to work

When the game is recorded, the UDP data stream of a 0x3e packet (without the header) is written straight into the .mgx files with few changes. Viewing the recording will therefore simulate the exact actions that were done by the players. For more information on this, check the Further Reading section below.

Much of the actions where already figured out by Stefan Kolb as part of his .mgx Specification. This analysis will use his document style (Example) as a template.

Values and Data Types

Values in the network protocol can have a length of one, two or four byte. Little endian notation is used. Therefore, values with a length of two and four bytes have to be read starting with the rightmost byte.

The data is described with few data types, which are shown in the table below.

Length Data Types
1 byte int8, (ASCII) char
2 byte int16
4 byte int32, float
other (1-dimensional) array

Most of the fields present in the network protocol have a fixed length. The use cases for variable length fields are usually lists of unit_ids or waypoints and will be handled as arrays in this documentation.

ID System

Age of Empires II uses an ID system to reference every object in the game by a unique numerical identifier with a length of 4 bytes. IDs are assigned by using a simple counter, that assigns every new object a the next unassigned number. New objects are not necessarily created by players. For example, cutting down a tree replaces a standing with a fallen tree, whereby the latter is handled as a new object. As a rule of thumb, one can assume that objects have been replaced with new ones when their sprite has changed.

The players are referenced with not less than three IDs; their network_source_id/network_dest_id (4 bytes), the player_id and the player_number (both 1 byte). network_ids are used in the header to determine from which person a packet comes from or is sent to. The reason why player_id and player_number are handled differently is due to an undocumented cooperative multiplayer mode. In this mode, which can be activated by assigning to players the same player_number, two or more players share control of units, buildings and resources. In consequence, player_id is unique for every player, player_number not necessarily.

Coordinate System

In this document, we will assume that AoC uses a carthesian coordinate system with the left corner as an origin point. Keep in mind, that AoC uses a Quadrant 4 representation for its coordinates, which means that the y-axis is represented by the edge in the bottom left and the x-axis by the top left edge.

Further Reading

To get a better understanding of the networking design and the underlying principles, it might be beneficial to read these sources.

[1] Dave Pottering, 1500 Archers on a 28.8: Network Programming in Age of Empires and Beyond, 2001 https://www.gamasutra.com/view/feature/131503/1500_archers_on_a_288_network_.php?page=1

[2] Matthew Pritchard, How to Hurt the Hackers: The Scoop on Internet Cheating and How You Can Combat It, 2000 https://www.gamasutra.com/view/feature/3149/how_to_hurt_the_hackers_the_scoop_.php

[3] Stefan Kolb, Age of Empires 2: The Conquerors — Savegame File Format Specification, https://github.com/stefan-kolb/aoc-mgx-format

[4] Renée Kooi, RecAnalyst, https://github.com/goto-bus-stop/recanalyst