This page defines the planned Quagents3 protocol. 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. == Overview == 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 * where A is either a 't' or 'n' character, for 'then' or 'now', specifying scheduling (see below). * where BB is the opcode of the instruction (always 2 characters). * 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. * 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. * and \n is a newline. A carriage-return will work just as well. Examples (each of these entries ought to be terminated by a newline): * t ju 653 0 1 * 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". * The server will respond after some time "cp ju 653 done". * n po 0 * This command means: "immediately pop what you're doing, this is command id=0". * 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"). * t mf 350 0 180 0.4 * 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". * The server might eventually respond "cp mf 350 blocked". Quagents model their behavior in the form of a double-ended queue that has a maximum capacity of 128 commands. Commands can be pushed onto either the front ("now" commands) or the end ("then" commands). 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. == Brief Specification == '''INITIAL COMMANDS''' * ''name'' - "set name", sets what the name of the bot will be when it spawns. Takes one argument: * string name * ''botfile'' - "set botfile", sets the botfile of the bot. Among other things, this determines the bot's in-game model. See [[botfiles]] for a list of options. FIXME: problem loading bot models? * string filename * ''skill'' - "set skill", sets the skill level of the bot, which selects subsections from the botfiles. * integer skill * ''team'' - "set team" sets the team of the bot ("red" or "blue") in CTF or team deathmatch mode. * string team * ''ready'' - "ready", spawns the bot. Takes no arguments. Responds with "id X" where X is the unique integer id number of the bot. '''LIVE COMMANDS''' * Movement: * ''[[mf]]'' - "Move Forever". Takes three arguments: * int obstacles * float direction * float speed * ''[[mb]]'' - "Move By". Takes four arguments: * int obstacles * float direction * float speed * float distance * ''[[mt]]'' - "Move To". Takes four arguments: * int obstacles * float speed * float X * float Y * ''[[ju]]'' - "JUmp once". Takes two arguments: * float direction * float speed * ''[[ro]]'' - "ROtate". Takes two arguments: * float yaw * float pitch * Basic Actions * ''[[fw]]'' - "Fire Weapon". Takes no arguments. * Basic Queries * ''[[hc]]'' - "Health, Current". Takes no arguments. * ''[[hm]]'' - "Health, Maximum". Takes no arguments. * ''[[ac]]'' - "Armor, Current". Takes no arguments. * ''[[am]]'' - "Armor, Maximum". Takes no arguments. * ''[[lc]]'' - "Location, Current". Takes no arguments. * ''[[fc]]'' - "Facing, Current". Takes no arguments. * ''[[cs]]'' - "Can See". Takes one argument. * int entityid * ''[[rf]]'' - "RangeFinder". Takes three arguments. * int range * float yaw * float pitch * Command Queue Management * ''[[po]]'' - "POp". Takes no arguments. * ''[[pa]]'' - "PAuse". Takes no arguments. * ''[[fa]]'' - "Forget All tasks". Takes no arguments. * ''[[sk]]'' - "SKip". Takes no arguments. * ''[[pk]]'' - "PeeK". Takes one argument. * int depth '''GOD''' * God Actions * ''wiki:sh'' - "Set Health". Takes two arguments: * long botid * int newhealth * ''wiki:sg'' - "Set Gravity". Takes one argument: * float gravity * ''wiki:sa;; - "Set Armor". Takes two arguments: * long botid * int newarmor * God Queries * ''wiki:gh'' - "Get Health". Takes one argument: * long botid * ''wiki:ga'' - "Get Armor". Takes one argument: * long botid * ''wiki:gg;; - "Get Gravity". Takes no arguments. * ''wiki:gp'' - "Get Position". Takes one argument: * long botid * ''wiki:fd'' - "Find Distance". Takes four arguments: * double x1 * double y1 * double x2 * double y2 * ''wiki:li'' - "LIsten". Takes two arguments: * double x * double y == Example Quagent Session == 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. * User connects using telnet to open a connection to socket 6000. * User types: "name ExampleBot" * User types: "ready" * Quake spawns the bot in a spawn location and names it "ExampleBot". * Quake responds: "id 1" * User types: "n mf 1 0 0 1" * ExampleBot starts moving forever directly forward at full speed. * User types: "n pa 2" * ExampleBot pauses motion. * User types: "n hc 3" * Quake responds: "rs hc 3 100" * Quake responds: "cp hc 3 done" * User types "n po 4" * Quake responds: "cp po 4 done" * Quake responds: "cp pa 2 popped" * ExampleBot resumes motion. == Not Yet Implemented Commands == '''INITIAL COMMANDS''' * General management * initialPosition [LOCATION] - selects where the bot will start '''LIVE COMMANDS''' * Basic robot-like functions for users who want low-level fine control. (Implement first) * move [LOCATION] - bot moves to specified location. uses native pathfinding. It would be nice if along the way it used Quake's goal system. That would give us free puzzle-solving/button-pushing/surfacing-for-air. * move [OBJECT] - finds the location of specified object, and pathfinds to it using move[LOCATION]. * echo [STRING] - reports a string back over the socket to the user * jump [VOID] - makes the Quagent jump in place. * crouch [VOID] - makes the Quagent crouch in place. * fireWeapon [VOID] - makes the Quagent fire the currently equipped weapon. * changeWeapon [WEAPON] - Quagent equips the given weapon, if possible. * say [STRING] - Quagent "speaks" the STRING aloud. Has limited range. Possible implementation for user with speech synth. Used during Quagent collaboration. * look [VOID] - sends an image over the socket back to the user representing what the agent can see. * canSee [INT] - asks if there exists line of sight between a bot and another bot. * listen [TIME] - sends sounds back to the user for the specified time. This seems like it might be Hard. * zoom [VOID] - sends an image that zooms on the Quagent's current view. Uses quake zoom func. * More complex robot-like functions. (Implement next) * follow [ENTITY] [DIST] - Bot moves toward/away from entity until it is at the given distance, if possible, and attempts to maintain that. * track [ENTITY] - Bot rotates to face entity. * Invokable Quake Behavior (Implement last) * whereareyou? - returns what the bot usually says if you ask it that in a team game ("I'm by the rail gun in the blue base." sort of things). * followsmart [ENTITY] - smartly follows the given character using Quake's follow chat command. * playQuake - activates Deathmatch AI? * Sensors * currentItem - returns description of currently held items. * The following are booleans constructed from other protocol functions. They are implemented in the API for convenience. * isDead? - returns true if agent is dead * hasAmmo? - true if agent has > 0 ammo. * hasArmour? - true if agent has > 0 armour. * hasItem? - true if agent is carrying an item. '''GOD''' * getPositions [VOID] - returns list of all Quagent positions. * setGravity [GRAVITY] - sets global gravity. * slomo [SLOW_FACTOR] - slows down all game actions by SLOW_FACTOR. * speedup [SPEED_FACTOR] - speeds up all game actions by SPEED_FACTOR. * drop[ITEM,LOCATION] - places ITEM at LOCATION. * move[BOT,LOCATION] - moves specified Quagent to specified LOCATION. * look[POSITION,DIRECTION] - produces a snapshot taken from POSITION facing DIRECTION. * findDist [POSITION1, POSITION2] - returns the distance between two points. * setHealth [BOT,HEALTH] - sets Quagent's health to HEALTH. * setArmor [BOT,ARMOR] - sets Quagent's armor to ARMOR. * isWithin [BOT,SPACE] - determines if Quagent is within the specified SPACE. * listen [POSITION] - listens for Quagent communications at the given POSITION. * pause [VOID] - global pause. calling this while paused acts as a resume. == WalterAPI == Walter mentioned to me that he would like implementations of the following functions (which we haven't done yet): * SENSORS * current_item * ACTIONS * player_use * player_crouch * weapon_fire * weapon_alternate * weapon_switch [WEAPON]