1 | | This page defines the planned Quagents3 protocol. |
2 | | |
3 | | ProtocolZero is the command protocol used for directly talking to wiki:Quagents. (The naming convention adopted here is that ProtocolOne is the protocol (or API) between the thing that sits on top of Quake and deals with socket I/O and whatever more abstract structure exists above that; ProtocolTwo would be two levels removed.) In particular, ProtocolZero is for the agent-based communication, not for the experimental control. |
4 | | |
5 | | In addition to the command protocol, there is also a protocol which is used exclusively for the automatic periodic transmission of data from the server to the client. This wiki:DataProtocol is enabled by sending the server a list of query opcodes for which the client desires automatic updates. |
6 | | |
7 | | == Overview == |
8 | | ProtocolZero commands are sent as plaintext over a TCP/IP socket to Quake on port 6000. Currently, any new connections to this port result in the creation of a new bot. Initial commands are simply ASCII strings of the form CMD PARAM. The final initial command given is "ready", after which the bot is spawned, and live commands become usable. Live command format is of the form A BB IDNUM PARAM_1 PARAM_2 PARAM_3 PARAM_4... \n |
| 1 | ProtocolZero is the command protocol used for directly talking to quagents. All commands and responses are sent as ASCII text on top of TCP. ProtocolZero is for agent-based communication, not for the experimental control. |
| 2 | |
| 3 | The lifecycle of a connection has two phases: an "initial" phase where the user can enter various setup commands, and a "live" phase, where the user is interacting with a bot in the environment. |
| 4 | |
| 5 | You should probably read [[TutorialTelnet]] before reading this document. |
| 6 | |
| 7 | == Command Channel vs Event Channel == |
| 8 | ProtocolZero communications are split over two different channels (which are implemented by two different sockets). The primary channel is the "command channel". The user sends commands on the command channel and receives responses. The command channel's responses are generally very predictable: every command responds and reports in order of execution, and no unexpected messages should ever arrive. (Though some commands make a variable number of responses, a set of responses is always terminated by a final report when the command ends.) Every quagent is required to have a command channel connection. Any connections to port 6000 while URCS Quagents3 is running will result in a new command channel and (eventually) the creation of a new quagent. |
| 9 | |
| 10 | The secondary channel is the "event channel". Use of this channel is optional. It is used for two purposes: first, for event-based data that has nothing to do with any particular command on the command channel (for example, if another bot executes a [[sy|say]] command, it will generate an event on all nearby quagents' event channels, even though they had no command tied to that particular event). Like command channels, event channels have a one-to-one mapping to quagents, but they must be setup after the command channel is. To get an event channel connection, connect to port 6001 while URCS Quagents3 is running (you must have a simultaneous connection to port 6000 as well). More on this below. |
| 11 | |
| 12 | == Client to Server Messages== |
| 13 | Commands sent in the initial phase are simply ASCII strings of the form CMD PARAM. The final initial command given is "ready", after which the bot is spawned, and the connection enters the live phase. Live commands are in the format A BB IDNUM PARAM_1 PARAM_2 PARAM_3 PARAM_4... \n |
11 | | * where IDNUM is a sequence of numeric characters representing an unsigned 32-bit integer. This code will be returned on completion, for the client's convenience. We imagine that users will typically make this a sequence number, but we do not require or enforce uniqueness. |
12 | | * where P1... are parameters for the instruction, and may be any length. They are delimited by spaces, and therefore cannot contain spaces (even if explicitly quoted or escaped). Parameters should be printed in ASCII, so 253 is '2','5','3', not '\253'. Floats are interpreted by the atof() function. |
13 | | * and \n is a newline. A carriage-return will work just as well. |
14 | | |
15 | | Examples (each of these entries ought to be terminated by a newline): |
16 | | * t ju 653 0 1 |
17 | | * This command means: "after you do everything I've told you to do, jump. This is command id=0, and you should jump in direction 0 degrees at speed 1". |
18 | | * The server will respond after some time "cp ju 653 done". |
19 | | * n po 0 |
20 | | * This command means: "immediately pop what you're doing, this is command id=0". |
21 | | * The server will respond (almost instantly in this case) "cp po 0 done" then some other message about the previous command (say, "cp ju 653 popped"). |
22 | | * t mf 350 0 180 0.4 |
23 | | * This command means: "after you do everything I've told you to do, walk forever, this is command id=350, direction=180 degrees, speed=0.4". |
24 | | * The server might eventually respond "cp mf 350 blocked". |
25 | | |
26 | | Quagents model their behavior in the form of a double-ended queue that has a maximum capacity of 1024 commands. Commands can be pushed onto either the front ("now" commands) or the end ("then" commands). Additionally, the top command can be atomically replaced by a new command ("replace" commands). |
27 | | |
28 | | In addition to individual Quagents, there is also the possibility of commanding a wiki:GOD (Global Overview Descriptor) structure, which collects and returns macroscopic game data. The idea is that there are two types of connection permissions - GOD and Quagent. The GOD entity connects to the game server through port 6010. |
29 | | |
30 | | == Brief Specification == |
31 | | |
32 | | '''INITIAL COMMANDS''' |
| 16 | * where IDNUM is a sequence of numeric characters representing an unsigned 32-bit integer. This code will be stated as part of the command's report, but is otherwise unused. |
| 17 | * where P1... are parameters for the instruction, and may be any length. They are delimited by single spaces. Parameters should be printed in ASCII, so 253 is '2','5','3', not '\253'. Floats are interpreted by the atof() function. |
| 18 | * and \n is a newline. I think carriage returns will work just as well. |
| 19 | |
| 20 | Quagents model their behavior in the form of a double-ended queue that has a maximum capacity of 1024 commands. Commands can be pushed onto either the front ("now" commands) or the end ("then" commands). Additionally, the front command can be atomically replaced by a new command ("replace" commands). |
| 21 | |
| 22 | == Server to Client Messages== |
| 23 | In the initial phase of a connection, the server never sends messages back to the client until the final step: when the client issues a "ready" on the command stream, it responds "id X" where X is the entitynum of the quagent that belongs to that command stream. The same is true on the event stream: when the client issues an "identity X" (where X is the entitynum of the quagent), the server will respond "ready" on a successful connection (or give an error message if there is a problem). |
| 24 | |
| 25 | In the live phase of a connection, there are four kinds of messages the server sends back over the channel: "er" (system error), "cp" (completion reports, hereafter called "reports"), "rs" (responses), and "ev" (events). The general idea of these messages is: |
| 26 | * "er" only appears if there is a serious problem that will circumvent one or more of the below contracts. For example, if the user issues too many commands to the quagent, the quagent's command queue may fill up which will result in further commands not being added but an "er [opcode] [idnum] queueful" reply. |
| 27 | * "rs" appears when a command asks for information. The information is always carried in an rs, rather than a cp. |
| 28 | * "cp" only appears once a command is completely done sending any information back (so all "rs"s or "ev"s have been sent). Each command will either eventually reply with a "cp" or will never reply because it never completes execution (for example, it is interrupted by some other command that takes infinite time to complete, such as [pa]). |
| 29 | * "ev" only appears in the event channel, and is prompted by the actions of other quagents or the environment. |
| 30 | |
| 31 | |
| 32 | == Example Quagent Session == |
| 33 | All strings here are terminated in a newline. In a program like telnet, this will typically be automatic for you, but if you're writing your own socket code, be sure to separate commands with newlines. |
| 34 | * User connects using telnet to open a connection to socket 6000. |
| 35 | * User types: "name !ExampleBot" |
| 36 | * User types: "ready" |
| 37 | * Quake spawns the bot in a spawn location and names it "!ExampleBot". |
| 38 | * Quake responds: "id 1" |
| 39 | * User types: "n mi 1 0 0 1" |
| 40 | * !ExampleBot starts moving forever directly forward at full speed. |
| 41 | * User types: "n pa 2" |
| 42 | * !ExampleBot pauses motion. |
| 43 | * User types: "n hc 3" |
| 44 | * Quake responds: "rs hc 3 100" |
| 45 | * Quake responds: "cp hc 3 done" |
| 46 | * User types "n po 4" |
| 47 | * Quake responds: "cp po 4 done" |
| 48 | * Quake responds: "cp pa 2 popped" |
| 49 | * !ExampleBot resumes motion. |
| 50 | |
| 51 | == List of Commands == |
| 52 | '''INITIAL PHASE''' |
151 | | |
152 | | == Example Quagent Session == |
153 | | All strings here are terminated in a newline. In a program like telnet, this will typically be automatic for you, but if you're writing your own socket code, be sure to separate commands with newlines. |
154 | | * User connects using telnet to open a connection to socket 6000. |
155 | | * User types: "name !ExampleBot" |
156 | | * User types: "ready" |
157 | | * Quake spawns the bot in a spawn location and names it "!ExampleBot". |
158 | | * Quake responds: "id 1" |
159 | | * User types: "n mi 1 0 0 1" |
160 | | * !ExampleBot starts moving forever directly forward at full speed. |
161 | | * User types: "n pa 2" |
162 | | * !ExampleBot pauses motion. |
163 | | * User types: "n hc 3" |
164 | | * Quake responds: "rs hc 3 100" |
165 | | * Quake responds: "cp hc 3 done" |
166 | | * User types "n po 4" |
167 | | * Quake responds: "cp po 4 done" |
168 | | * Quake responds: "cp pa 2 popped" |
169 | | * !ExampleBot resumes motion. |