The behavior of an add-on after it's connected to a session reflects the player type of the add-on. An "observer" type add-on monitors the packet stream and doesn't send packets unless prompted by a query, such as QUERY_PLAYER_TYPE. A "player" type add-on responds to packets and sends location updates (POSITION_LLAPBH or POSITION_VELOCITY) to all players in the session at the rate of four packets per second. Both players and observers must monitor POSITION_LLAPBH and POSITION_VELOCITY packets to track other players.
All of the packets sent by the multiplayer system have a standard header; for more information, see the MULTIPLAYER_PACKET_HEADER structure in the topic Packet Structures. The first element in the structure (packet_id) is a 32-bit number that designates the ID of the packet; for more information, see the topic Packet IDs. The second element in the structure (data_size) specifies the size of the data block that follows the header. The third element in the structure (data[ ]) is a placeholder that indicates where extra packet data will begin. It's possible that a packet will contain only a packet ID and size fields; the data size can be 0.
The following table includes the packets encountered during the course of a normal session. The table also describes what action (if any) the add-on takes when the packet is received and information about the packet data.
Packet | Description |
ADD_PLAYER_REQUEST | If an add-on receives this packet, it should be ignored. An add-on sends this packet to all players when joining the session as a player. Send this packet with guaranteed messaging. Contains no extra data. |
ADD_OBSERVER_REQUEST | If an add-on receives this packet, it should be ignored. An add-on sends this packet to all players when joining the session as an observer. Send this packet with guaranteed messaging. Contains no extra data. |
CHANGE_TO_PLAYER | When received by an add-on, the player_id field in the data structure contains a DirectPlay player ID. The player associated with this ID is identified as a "player" for the remainder of the session. If the player ID matches the ID of the player created by the add-on, the add-on has been successfully added to the session as a player. At this point, the add-on must send location update information. An add-on sends this packet in response to a QUERY_PLAYER_TYPE packet. |
CHANGE_TO_OBSERVER | When received by an add-on, the player_id field in the data contains a DirectPlay player ID. The player associated with this ID is identified as an "observer" for the remainder of the session. If the player ID matches the ID of the player created by the add-on, the add-on has been successfully added to the session as an observer. The add-on doesn't send location update information. An add-on must send this packet as a response to a QUERY_PLAYER_TYPE packet. This response is sent only if the add-on has successfully joined a session as an observer (see QUERY_PLAYER_TYPE). |
ADD_PLAYER_REFUSED | Indicates that the add-on hasn't been successfully added to the session. The add-on notifies the user and ends the DirectPlay connection. An add-on should never send this packet. |
ADD_OBSERVER_REFUSED | Indicates that the add-on hasn't been successfully added to the session. The add-on notifies the user and ends the DirectPlay connection. An add-on should never send this packet. |
QUERY_PLAYER_TYPE | Indicates that the remote machine doesn't know the player type ("player" vs. "observer") of an add-on. An add-on should only respond to this packet after it has received a confirmation CHANGE_TO_PLAYER or CHANGE_TO_OBSERVER packet. At this point, the add-on responds to the QUERY_PLAYER_TYPE packet with either CHANGE_TO_PLAYER or CHANGE_TO_OBSERVER, as appropriate. An add-on sends this packet to a new player after receiving notification from DirectPlay that a new player has been created. If a player has joined a game, but a CHANGE_TO_PLAYER or CHANGE_TO_OBSERVER message hasn't arrived, a QUERY_PLAYER_TYPE message is sent to that player every 30 seconds until a confirmation arrives. |
RETRANSMIT_ JOIN_PLAYER | If an add-on receives this packet, it should be ignored. An add-on sends this packet to all players if it has sent an ADD_PLAYER_REQUEST, but has not received a CHANGE_TO_PLAYER or an ADD_PLAYER_REFUSED response within 30 seconds. The add-on continues to broadcast this packet every 30 seconds until it receives either a CHANGE_TO_PLAYER or an ADD_PLAYER_REFUSED packet. |
RETRANSMIT_ JOIN_OBSERVER | If an add-on receives this packet, it should be ignored. An add-on sends this packet to all players if it has sent an ADD_OBSERVER _REQUEST, but hasn't received a CHANGE_TO_OBSERVER or an ADD_OBSERVER_REFUSED response within 30 seconds. The add-on continues to broadcast this packet every 30 seconds until it receives either a CHANGE_TO_OBSERVER or an ADD_OBSERVER_REFUSED packet. |
REQUEST_OBSERVER | If an add-on receives this packet, it should be ignored. An add-on sends this packet to all players to change its player type from "player" to "observer" during a session. If the add-on doesn't receive either an OBSERVER_CHANGE_OK or an OBSERVER_CHANGE_REFUSED packet within 30 seconds, it sends a RETRANSMIT_GO_OBSERVER packet. An add-on can change from a player to an observer, but not from an observer to a player. |
RETRANSMIT_ GO_OBSERVER | If an add-on receives this packet, it should be ignored. An add-on sends this packet to all players at 30 second intervals if it has sent a REQUEST_OBSERVER packet, but hasn't received an OBSERVER_CHANGE_OK or an OBSERVER_CHANGE_REFUSED response. |
OBSERVER_CHANGE_OK | Indicates that the add-on has been changed from a "player" to an "observer" and will be recognized as such for the remainder of the session. An add-on should never send this packet. |
OBSERVER_CHANGE_REF | Indicates that the add-on hasn't been allowed to change from a "player" to an "observer." An add-on should never send this packet. |
CHANGE_PLAYER_PLANE | Indicates that a player has changed to a new plane. The engine_type field contains one of the following values: ENGINE_TYPE_PISTON = 0 ENGINE_TYPE_JET = 1 ENGINE_TYPE_NONE = 2 ENGINE_TYPE_HELO_TURBINE = 3 The aircraft_name field contains a null-terminated string that indicates the name of the aircraft. An add-on shouldn't need to send this packet, but can do so to change the visual model of the plane that represents the add-on on other machines. When constructing this packet, ensure that the packet properly accounts for the null termination required at the end of the aircraft name. |
QUERY_PLAYER_PLANE | Indicates that a remote player wants to find out the type of aircraft that the add-on is flying. The add-on can ignore this packet or send a CHANGE_PLAYER_PLANE response indicating the aircraft that will represent the add-on when it has successfully joined as a player. An add-on sends this packet only to find out the type of aircraft that a remote player is flying. |
REMOTE_PLANE_ UNKNOWN | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
PLAYER_CRASH | Indicates that a remote player has registered a collision with the add-on. The add-on then processes the collision. An add-on sends this packet to another player (not observer) only if it has registered a collision with that player. |
HOST_QUIT | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
REQUEST_SITUATION | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
SITUATION_DATA | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
TEXTURE_REQUEST_LIST | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
LEAVE_SESSION | Indicates that the host wants to remove the add-on from the session. The add-on responds by closing its connection to the session. An add-on should never send this packet. |
SYNC_INFORMATION | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
POSITION_LLAPBH | Indicates the location of a remote player. Receiving this packet also implies that the remote player is in a paused state and their plane shouldn't be collided with for at least 10 seconds. Each time this packet is received from a player, the collision avoidance time should be reset to 10 seconds. The reduced (that is, uses only the 10 most significant bits of pitch, bank, and heading) LLAPBH data contents of this packet are as follows: application_time Field is ignored. packet_index Contains an indexing ID that indicates the ordering of location packets. The index of the last received location packet is stored on a player-by-player basis. A new packet's contents is considered valid only if it has a higher packet index than the last packet index received from a player. pbh Contains a fractional representation of the pitch, bank, and heading of the remote plane. The pitch is found in the most significant 10 bits, bank is found in the second most significant 10 bits, and heading is found in the third most significant 10 bits. The least significant 2 bits aren't used. lat_I Contains the high-order 32 bits of latitude. lon_hi Contains the high-order 32 bits of longitude. alt_I Contains the high-order 32 bits of altitude. lat_f Contains the low-order 16 bits of latitude. lon_lo Contains the low-order 16 bits of longitude. alt_f Contains the low-order 16 bits of altitude. An add-on sends this packet to change its location in the world without colliding with other players. |
POSITION_VELOCITY | Indicates the location of a remote player. The data contents of this packet are as follows: packet_index See POSITION_LLAPBH. application_time Field is ignored. lat_velocity Contains the latitude component of the plane's current velocity. lon_velocity Contains the longitude component of the plane's current velocity. alt_velocity Contains the altitude component of the plane's current velocity. ground_velocity Contains the net ground velocity of the remote plane. reduced_llapbh See POSITION_LLAPBH packet. All velocities are 16-bit integer,16-bit fractional values with units of feet/second. An add-on sends this packet to change its location in the world in manner that enables positional extrapolation; that is, the packet contains location information and velocity vectors on which any change in position can be based. |
INITIALIZE_AIRCRAFT_ SEND | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
AIRCRAFT_SEGMENT | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
AIRCRAFT_CANCEL | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
INITIALIZE_TEXTURE_SEND | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
TEXTURE_SEGMENT | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
TEXTURE_CANCEL | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |
CHAT_TEXT | Represents a chat message. The chat_data field is a null-terminated string containing the chat message. An add-on must include the null termination on the message when sending this packet. |
PARAMS | If an add-on receives this packet, it should be ignored. An add-on should never send this packet. |