Protocol Description

The BZRC protocol is a simple, text-based, line-oriented, command-response protocol which runs over TCP. The server in this protocol is bzrflag, a simple clone of BZFlag. The client in the protocol is referred to as the remote agent.

General Practices

A newline is “\n”. Any additional whitespace, including “\r”, is ignored. Within a line, any positive amount of whitespace is equivalent to a single space character. Blank lines are ignored.


The bzrflag program listens on a specified TCP port for an incoming connection. Once a connection has been accepted, it will not accept another connection until the first is closed. BZRFlag immediately introduces itself by saying, “bzrobots 1\n” (1 being the protocol version). The remote agent then responds with a similar introduction: “agent 1\n”. The session is now initiated.

Command and Response Syntax

Once the session has been initiated, bzrflag listens for commands from the remote agent. It will issue exactly one response for each command. Responses will always be returned in the same order as the corresponding commands.

The single exception to this general rule is low-level errors, in which case an error message will be sent by bzrflag. See below for more details.


A command consists of a command name followed by a space-delimited list of arguments and ending with a newline. A command is always a single line. The following are sample commands:

shoot 0
speed 3 -0.241


A response consists of an acknowledgment line followed by a value, which may be several lines long. The acknowledgment line begins with a timestamp (a number of seconds) within brackets and ends with the command being responded to. For example:

ack 128.2342 speed 3 -0.241

Note that the acknowledgment line is not a character-by-character copy. It's more like the conversational, “If I understood you correctly, you're saying…” For example, if the request specifies robot 17, but no such tank exists, bzrobots will respond with -1 for the tank index. (I just checked this response and it's wrong. BZRFlag returns robot 17 in the ack, but then replies with “fail Invalid tank ID: 17”. I'm not sure if this is necessary anymore. -Matt)

The value is either a simple value or a list. A simple value is a single line. A list is more than one line. The first line of a list is “begin”, and the last line is “end”. In between are simple values. If the value line of a response does not start with “begin”, then it will always be a simple response and therefore will fit on a single line. A simple value may look like:

ok Success

A list may look like:

line 1
line 2
line 3
line 4

A full response line might look like:

ack 169.43 shoot abc
fail Invalid parameter


ack 66.155 obstacles
obstacle 100 20 100 40 80 40 80 20
obstacle -30 0 0 0 0 50 -30 50
obstacle 22 17 4 -2 10 -8


The single exception to the general behavior is low-level errors. It is possible for bzrflag to send an “error” response at any time. This can even happen in the middle of another response. For example, if the remote agent sends a large number of requests but neglects to read the responses, bzrflag's buffer will fill up and data will be dropped. When the agent finally catches up, bzrflag will send an “error” response to say what happened. Since the truncation could have happened anywhere, the remote agent should always look for an “error” response. Incidentally, the agent should also make sure not to ask questions without listening for the answers.

Error messages may happen in less drastic situations as well. For example, if the agent sends a command that bzrflag doesn't understand, the request will be ignored, and the response will be an error message. (Currently this is simply by sending “fail invalid command”.)


A remote agent may close the connection simply by closing the TCP session. BZRFlag will then wait for a connection from another agent.

Command List

The following list describes common BZRC requests and their associated responses:


shoot [index]

Request the tank indexed by the given parameter to fire a shot. Returns either:

ok [Comment]


fail [Comment]

where the comment is optional.

speed [index] [speed]

Request the tank indexed by the given parameter to accelerate as quickly as possible to the specified speed, given as a multiple of maximum possible speed (1 is full throttle). A negative parameter will cause the tank to go in reverse. Returns a boolean (“ok” or “fail” as described above).

angvel [index] [angvel]

Request the tank indexed by the given parameter to begin angular acceleration with the specified target angular velocity. The parameter is given as a multiple of maximum possible angular velocity, where positive values indicate counter-clockwise motion, and negative values indicate clockwise motion. The sign is consistent with the convention used in angles in the circle. Returns a boolean (“ok” or “fail” as described above).

accelx and accely
accelx [index] [accel]
accely [index] [accel]

Request the specified tank to accelerate in the x or y dimension. The value ranges between -1 and 1. Returns a boolean (“ok” or “fail” as described above).



Request a list of teams. The response will be a list, whose elements are of the form:

team [color] [playercount]

Color is the identifying team color/team name. Playercount is the number of tanks on the team.


Request a list of obstacles. The response will be a list, whose elements are of the form:

obstacle [x1] [y1] [x2] [y2] ...

where (x1, y1), (x2, y2), etc. are the corners of the obstacle in clockwise order. Depending on runtime configuration, visibility may be limited, so the list of obstacles will not always be complete.


Request a list of bases. The response will be a list, whose elements are of the form:

base [team color] [x1] [y1] [x2] [y2] ...

where (x1, y1), (x2, y2), etc. are the corners of the base in clockwise order.


Request a list of visible flags. The response is a list of flag elements:

flag [team color] [possessing team color] [x] [y]

The team color is the color of the owning team, and the possessing team color is the color of the team holding the flag. If no tanks are carrying the flag, the possessing team is “none”. The coordinate (x, y) is the current position of the flag. Note that the list may be incomplete if visibility is limited.


Request a list of visible shots. The response is a list of shot lines:

shot [x] [y] [vx] [vy]

where (x, y) is the current position of the shot and (vx, vy) is the current velocity.


Request the status of the tanks controlled by this connection. The response is a list of tanks:

mytank [index] [callsign] [status] [shots available] [time to reload] [flag] [x] [y] [angle] [vx] [vy] [angvel]

Index is the 0 based index identifying this tank. This index is used for instructions. The callsign is the tank's unique identifier within the game. The status is a string like “alive,” “dead,” etc. Shots available is the number of shots remaining before a reload delay. Flag is the color/name of the flag being held, or “-” if none is held. The coordinate (x, y) is the current position. Angle is the direction the tank is pointed, between negative pi and pi. The vector (vx, vy) is the current velocity of the tank, and angvel is the current angular velocity of the tank (in radians per second).


Request the status of other tanks in the game (those not controlled by this connection). The response is a list of tanks:

othertank [callsign] [color] [status] [flag] [x] [y] [angle]

where callsign, status, flag, x, y, and angle are as described under mytanks and color is the name of the team color.


Request a list of constants. These constants define the rules of the game and the behavior of the world. The response is a list:

constant [name] [value]

Name is a string. Value may be a number or a string. Boolean values are 0 or 1.

 occgrid [index]

Request the occupancy grid visible by the tank indexed by the parameter. The occupancy grid is a matrix of 0's and 1's, where each element in the matrix represents a discretized portion of the world space. A 0 means that the space is unoccupied by an obstacle, a 1 means that than space is occupied. The response is:

at [x],[y]
size [xdim]x[ydim]

where (x,y) is the top left corner of the grid, xdim and ydim are the dimensions of the grid, and the grid is a sequence of zeros and ones that indicate whether or not a space is deemed occupied by the reading (which may be noisy). Both x and y increase as the rows and column increase. Note that this means that the top left corner of the grid corresponds to the bottom left corner of the world. In grid coordinates, the top left corner is 0,0. When you send an occgrid command, the first line of the response will tell you in world coordinates the location of the top left corner of the grid (grid coordinates 0,0). (it's confusing, and we should fix it, but not in the middle of a semester). As long as you read in the (x, y) values as the protocol says they come, you'll be ok. Also, the occupancy grid only gives information about obstacles, not about tanks (the reason is because tanks are not stationary, and the grid filter that we talk about in class only works with stationary objects).

An example (albeit small) response is the following:

at 20,20
size 5x4

As you can see, rows correspond to x values, and columns correspond to y values (sorry if that's counter-intuitive, that's the way it is). The ending (x, y) value (for the bottom right corner) is (24, 23).

If you ask for the occgrid for a tank that is dead, you will get a fail in return.

Note also that occgrid sends a begin to start and an end to finish, as all other commands that request information from the server. It's not a list, so it technically doesn't need the begin and end, but for consistency we send them.

cs-470/bzrc_protocol.txt · Last modified: 2015/01/06 21:46 by ryancha
Back to top
CC Attribution-Share Alike 4.0 International = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0