Altitude Game: Forums  

Go Back   Altitude Game: Forums > Altitude Support > Dedicated Server
FAQ Community Calendar

Dedicated Server Discuss technical issues related to hosting your own servers.

Thread Tools Display Modes
Old 05-03-2014, 09:31 AM
randunel randunel is offline
Junior Member
Join Date: Apr 2014
Posts: 6
Default Decoding the protocol

I am looking for some information regarding altitude's communication protocol.

At login, the client uses some udp packets to reach the master server, which are then followed by a tcp handshake with login information, then back to udp. UDP is then used further on to gather the server list, and to ping them for additional information.

Last night, I was able to decode the "server name" part of the udp packets the client receives from servers, but it's not exact. The first character of the server name appears to have a different encoding, and the same goes for non-letter chars from what I've seen.

This is probably due to the wrong approach, so I'm wondering if anyone here knows something about the protocol, and might help. The ultimate goal is to create a proper server query tool.
Reply With Quote
Old 05-15-2014, 03:47 PM
19 cm 19 cm is offline
Join Date: Nov 2011
Posts: 73

Don't know anything about the protocol, but why don't you capture the packets sent and received by the builtin server browser?
Reply With Quote
Old 05-16-2014, 09:41 PM
randunel randunel is offline
Junior Member
Join Date: Apr 2014
Posts: 6

I captured the packets. They are encoded somehow, I managed to decode the name of the server, so far, except for the first character, so I must be doing something wrong. I was wondering if anyone else did this, or has some related knowledge.

So far, I am only able to build a tool which translates a dns/ip : port into partial server name...
Reply With Quote
Old 08-22-2015, 01:29 AM
randunel randunel is offline
Junior Member
Join Date: Apr 2014
Posts: 6

Got the initial version working. It updates on demand (on page load), and caches for a couple of seconds.

Has anyone gotten replies / protocol info regarding the master server yet?

Here's a demo of what I'm building:

Edit: takes 15 seconds to load after long idling, can be reduced to <1s.

Last edited by randunel; 08-22-2015 at 02:01 AM.
Reply With Quote
Old 08-23-2015, 05:15 PM
biell biell is offline
Senior Member
Join Date: May 2015
Posts: 168

You appear to be listing every server with players twice and empty servers once:

14/14 Official #1 - TBD - maxPing=400 tbd_underpark
14/14 Official #1 - TBD - maxPing=400 tbd_underpark
14/14 Ledow's Football Server #3 ( ball_football
14/14 Ledow's Football Server #3 ( ball_football
11/14 0xffff's bombs tbd_noname
11/14 0xffff's bombs tbd_noname
9/20 Coop Sandbox qde_coop_arkanoid
9/20 Coop Sandbox qde_coop_arkanoid
3/14 {= Coop Advanced (1de/tbd/ball) =} tbd_coop_icedive_easy
3/14 {= Coop Advanced (1de/tbd/ball) =} tbd_coop_icedive_easy
1/2 !rawr's duels qdm_asteroidsr
1/2 !rawr's duels qdm_asteroidsr
0/60 League US-West#1 lobby_league
0/60 Ranked TBD US-East#2 lobby_tbd
0/60 League US-West#2 lobby_league
Reply With Quote
Old 10-10-2015, 12:29 AM
Mango777 Mango777 is offline
Senior Member
Join Date: Sep 2014
Location: West coast
Posts: 317

Interesting, look at the FFA, its not listed twice

23/60 Ranked BALL US-East#3 ball_snow_pb
23/60 Ranked BALL US-East#3 ball_snow_pb
14/14 Ledow's Football Server #4 ( ball_football
14/14 Ledow's Football Server #4 ( ball_football
4/20 tbd Coop tbd_coop_super_mario_expert
4/20 tbd Coop tbd_coop_super_mario_expert
3/14 0xffff's bombs tbd_fun_arena
3/14 0xffff's bombs tbd_fun_arena
3/14 Ledow's Football Server #2 ( ball_football
3/14 Ledow's Football Server #2 ( ball_football
2/14 [LTTD]SYD 2 - FFA ffa_cave
1/14 Ledow's Hockey Server #9 ( ball_hockey
1/14 Ledow's Hockey Server #9 ( ball_hockey
0/60 Ranked BALL Europe#2
Reply With Quote
Old 06-07-2016, 11:53 AM
LewisH LewisH is offline
Senior Member
Join Date: Mar 2012
Location: Earth
Posts: 215

I've been working on custom server software for altitude recently, which has involved reverse engineering the protocol. I'll leave this here for anyone searching:

Bit-oriented encoding

Altitude's packets use bit-oriented encoding (also called bit packing), so values are rarely aligned to bytes. The first bit in a packet is the least significant bit of the first byte, so if for example you want to encode the value 29 (11101) using 5 bits followed by 54 (110110) in 6 bits, you would have:

least significant bit ->  10111 011011  <-most significant bit
Written with the usual convention of the least significant digit being to the right of a number:

11011101  00000110
Here's an endian-agnostic algorithm for reading bit encoded values from an array of bytes:

Also see the bit-oriented stream section of

Ranged values (integers and scaled floats) can be written/read with the fewest bits using simple helper functions.


Strings are encoded in UTF-8, the first two bytes of a string give it's length in bytes. Strings can include null (but they probably never do), they're not null terminated.

Packet headers - A simple transport protocol

Altitude uses UDP, which has the advantage over TCP of speed, but the disadvantage that there's no guarantee that packets will be delivered or be in the correct order. Some things in altitude need these guarantees, so it uses a simple transport protocol which has optional delivery and order guarantees. Packets are sent with unique IDs, when a client receves a packet it sends an acknowlagement, the server will continue sending the packet untill it gets this acknowlagement, other packets can still be sent at the same time. This is called Go-Back-N ARQ (

The packet header looks something like this:

guarantee level (2 bits) | routing number (6 bits) | guarantee data (0-53 bits)
The first two bits of each packet give the guarantee level for that packet:

0 -> No guarantee
1 -> Guaranteed delivery
2 -> Guaranteed delivery and order

The next 6 bits are a routing header, which I'll talk about later.

After this is the data needed for the transport protocol (sequencing numbers and sender IDs) which is between 0 and 53 bits long.

If the guarantee level is 1 or 2, guarantee data is read. Otherwise, the rest of the packet is the payload.

Transport protocol data

The guarantee data starts with 2 bytes giving the type of packet it is:

0 -> Open (53)
1 -> Open ack (34)
2 -> Data (18)
3 -> Data ack (18)

The values in parentheses are the length of that type of transport protocol data, including the two bits which give the type (so if you wanted to, say, skip this data when parsing a packet, you'd read the two bits for the type, then ignore the number of bits in parentheses minus two).

Here's an implementation of reading and writing the guarantee level and data:

And an implementation of the guarantee system itself:

Routing Header

The 6 bit routing header in the packet header is used to decide which parts of the game/server the packet should be passed to:

0 - Friend messages & status
1 - Authentication
2 - Validation
3 - Server list
4 - Server list handler (?)
5 - Versioning
6 - Firewall checker
7 - Server info
8 - Ping (one of many :3)
9 - Game storage (?)
10 - Hardware report

70 - Join request & response
71 - Game messages (events, entity updates)
72 - Map downloading
73 - Pings (yeah, more of them :3)

74 - Multicast IP request & response (to find LAN servers)
75 - Another multicast thing ?

Packet payload

After the header, there's not much of a defined protocol, different parts of the client/server read and write bits as they please. There's often a lot of state involved in reading packets properly, which is making it difficult to reverse engineer.

There is somewhat of a system for the game packets (header 71):

Game packets are sent regularly, (about every 20-30ms), even when there is no new information to be sent.

Information is split into two types, events and nuons. Events include individual things which happen in the game world: a plane spawning, crashing, using abilities, catching and using powerups, and so on, as well as metadata about the game: players joining, ping updates, game mode updates, etc. These events need to have guaranteed order and delivery, the system for this is different to and a little more complex than the guarantee system in the packet header, it's an instance of selective repeat ARQ ( Events are split into sequenced event groups, which the sender keeps for a while. If the receiver gets an event group but it's missing the one before it, the next time the receiver sends a game message to the sender, it will give a list of event groups that it's missing, the original sender will then re-send these event groups (if it still has them cached).

Game messages also include updates for all the dynamic entities in the game, planes, projectiles, etc. These are referred to as "nuons" by debug messages in the decompiled (still obfuscated) altitude source code, so I'll use that term (I'm not sure if it refers to the information used to update the entity or the entities themselves, I'll use the former - entities which are updated like this are called nuons). This data needs no guarantees, as only the most recent data is ever relevant.

I'll probably write about the implementation of this at some point, for now:

Server Info messages

Since this is what this thread's about, I suppose I should quickly go over server info messages (header 7).

Server info messages can be either a request or a response. It's assumed that a client will only send a request, and a server will only send a response, so the only way to differentiate between them without knowing who sent it is by it's size. Requests have no extra information, so the packet size is just the size of the header, which is no more than 8 bytes long.

Responses contain, in this order:

- A single bit with the value 0 *
- An unknown 16 bit value (some sort of ID?)
- The server's IP address (a bool, if true IPv4 otherwise IPv6, then the values (4 or 16 bytes respectively)
- The map name (a string)
- The maximum players (8 bits) (only used for display, the client will try to join a full server anyway)
- The current players (8 bits)
- The server name (a string)
- A bool, true if the server requires a password
- A bool, false (?) if the server bouncy walls
- The minimum level (1-60)
- The maximum level (1-60)
- A bool, false if demo users can join (no longer applicable?)
- The server's altitude version (a string, currently "0.0.374")

* The same code is used for other packet types which can have multiple types of data, this code looks at all the possible types of data and uses the minimum amount of data to distinguish between them, server info messages only contain one type of data, information about a server, but it still uses a single bit to say that that's what's in the packet.

I haven't looked into the vapor protocol yet, so querying the server list is a little beyond what I know ^^

Last edited by LewisH; 07-05-2016 at 05:38 PM. Reason: Updated URL
Reply With Quote

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Query Protocol, Rcon Commands Sonderfall Dedicated Server 4 05-29-2010 06:39 PM

All times are GMT. The time now is 05:59 AM.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
2008 Nimbly Games LLC