The newest version of the Xpilot-AI bindings for Chicken Scheme has marked differences from the previous version. Code using the old API will have to be changed to fit the new version. This API change was done to make Xpilot-AI more comfortable to work with in a scheme environment.
1. General Functions
These functions allow general control of the Xpilot client application.
; Parses the command line arguments to join the desired server
(xpilot "-join" (car (command-line-arguments))
"-port" (cadr (command-line-arguments))
"-name" (caddr (command-line-arguments)))
- function (xpilot-bg . args) → #<thread>
-
Analogous to xpilot, with the exception that the xpilot-process in launched in a background thread, allowing the user to enter commands at the repl.
#;1> (xpilot-bg "-join localhost -name Bill") #<thread> #;2> (x-pos) 82
See also: xpilot
- function (AI_main) → #<void>
-
Xpilot-AI will call the function AI-main exactly once for every frame of gameplay. Bots are generally written by redefining this function to perform actions based on current conditions.
- function (press-key key) → #<void>
-
Simulates a key press. release-key must be called to complete the key stroke.
; A ship that tries to fire a laser every ; frame (if lasers are enabled by server (define (AI-main) (press-key KEY_FIRE_LASER))
Here is a complete list of all the possible keys to press.
-
KEY_DUMMY
-
KEY_LOCK_NEXT
-
KEY_LOCK_PREV
-
KEY_LOCK_CLOSE
-
KEY_CHANGE_HOME
-
KEY_SHIELD
-
KEY_FIRE_SHOT
-
KEY_FIRE_MISSILE
-
KEY_FIRE_TORPEDO
-
KEY_TOGGLE_NUCLEAR
-
KEY_FIRE_HEAT
-
KEY_DROP_MINE
-
KEY_DETACH_MINE
-
KEY_TURN_LEFT
-
KEY_TURN_RIGHT
-
KEY_SELF_DESTRUCT
-
KEY_LOSE_ITEM
-
KEY_PAUSE
-
KEY_TANK_DETACH
-
KEY_TANK_NEXT
-
KEY_TANK_PREV
-
KEY_TOGGLE_VELOCITY
-
KEY_TOGGLE_CLUSTER
-
KEY_SWAP_SETTINGS
-
KEY_REFUEL
-
KEY_CONNECTOR
-
KEY_INCREASE_POWER
-
KEY_DECREASE_POWER
-
KEY_INCREASE_TURNSPEED
-
KEY_DECREASE_TURNSPEED
-
KEY_THRUST
-
KEY_CLOAK
-
KEY_ECM
-
KEY_DROP_BALL
-
KEY_TRANSPORTER
-
KEY_TALK
-
KEY_FIRE_LASER
-
KEY_LOCK_NEXT_CLOSE
-
KEY_TOGGLE_COMPASS
-
KEY_TOGGLE_MINI
-
KEY_TOGGLE_SPREAD
-
KEY_TOGGLE_POWER
-
KEY_TOGGLE_AUTOPILOT
-
KEY_TOGGLE_LASER
-
KEY_EMERGENCY_THRUST
-
KEY_TRACTOR_BEAM
-
KEY_PRESSOR_BEAM
-
KEY_CLEAR_MODIFIERS
-
KEY_LOAD_MODIFIERS_1
-
KEY_LOAD_MODIFIERS_2
-
KEY_LOAD_MODIFIERS_3
-
KEY_LOAD_MODIFIERS_4
-
KEY_SELECT_ITEM
-
KEY_PHASING
-
KEY_REPAIR
-
KEY_TOGGLE_IMPLOSION
-
KEY_REPROGRAM
-
KEY_LOAD_LOCK_1
-
KEY_LOAD_LOCK_2
-
KEY_LOAD_LOCK_3
-
KEY_LOAD_LOCK_4
-
KEY_EMERGENCY_SHIELD
-
KEY_HYPERJUMP
-
KEY_DETONATE_MINES
-
KEY_DEFLECTOR
-
KEY_UNUSED_65
-
KEY_UNUSED_66
-
KEY_UNUSED_67
-
KEY_UNUSED_68
-
KEY_UNUSED_69
-
KEY_UNUSED_70
-
KEY_UNUSED_71
-
NUM_KEYS
-
KEY_MSG_1
-
KEY_MSG_2
-
KEY_MSG_3
-
KEY_MSG_4
-
KEY_MSG_5
-
KEY_MSG_6
-
KEY_MSG_7
-
KEY_MSG_8
-
KEY_MSG_9
-
KEY_MSG_10
-
KEY_MSG_11
-
KEY_MSG_12
-
KEY_MSG_13
-
KEY_MSG_14
-
KEY_MSG_15
-
KEY_MSG_16
-
KEY_MSG_17
-
KEY_MSG_18
-
KEY_MSG_19
-
KEY_MSG_20
-
KEY_ID_MODE
-
KEY_TOGGLE_OWNED_ITEMS
-
KEY_TOGGLE_MESSAGES
-
KEY_POINTER_CONTROL
-
KEY_TOGGLE_RECORD
-
KEY_PRINT_MSGS_STDOUT
-
KEY_TALK_CURSOR_LEFT
-
KEY_TALK_CURSOR_RIGHT
-
KEY_TALK_CURSOR_UP
-
KEY_TALK_CURSOR_DOWN
-
KEY_SWAP_SCALEFACTOR
See also: release-key
- function (release-key key) → #<void>
-
Simulates a key release. Call to release a key pressed by press-key. See [press-key] for a complete list of keys.
See also: press-key
- parameter max-turn → degrees
-
SRFI-39 parameter object. Sets the maximum turn for self in degrees per frame.
;; Set the maximum turning speed to 26 degrees per frame #;1> (max-turn 26) ;; Get the current value of max-turn #;2> (max-turn) 26
2. Self Control
Functions to control the ship and perform various actions.
;; a ship that thrusts every frame (define (AI-main) (thrust)) ;; Or, more tersely, (define AI-main thrust)
- function (turn deg) → #<void>
-
Turns the ship deg degrees (out of 360). Negative degrees are clockwise, positive degrees are counter-clockwise. The ship will turn no more than the value of (max-turn) and no less than 0 - (max-turn).
; a ship that turns 15 degrees clockwise every frame (define (AI-main) (turn -15))
Note: Servers limit the shot rate and the number of shots, so the ship may not always fire. Use reload to check the number of frames remaining before it is possible to shoot again.
;; a ship that waits until reload before firing (define (AI-main) (shoot (zero? (reload))))
- function (shield #!optional bool) → #<void>
-
Turns the ship’s shield on or off. Use shield? to see the status of the shield.
3. Game state access
Functions that retrieve the values of variables concerning all ships. In general, these functions take any number of arguments. If no arguments are supplied, they return the value corresponding to self’s ship. If n index values are supplied, n values are returned, each corresponding to the respective value of the ship at each index. Note that some values do not apply to both self’s ship and other ships: the argument lists change accordingly.
Other ships are indexed by their position on the screen. The closest ship will always be denoted by index 0, the second closest will be denoted by index 1, and so on.
3.1 Functions for accessing self or ship state
- function (id . ships) → id1 id2 …
-
Retreive the unique id of a ship, according to the server. This id will not change even if a ship changes its nickname. If no arguments are supplied, self’s id is returned. For each index given as an argument, id will return the server identification number of the ship at the index, or #f if the ship is not on screen.
;; Get self's id #;1> (id) 3 ;; Get closest ship's id #;2> (id 0) 7
- function (pos . ships) → p1 p2 …
-
For each ship, return a list whose first element is the x-position of the ship, and whose second element is the y-position of the ship. If the ship is not on screen, return #f. If no arguments are given, self’s position is returned.
- function (vel . ships) → v1 v2 …
-
Ships' velocity in number of pixels moved per frame, or #f if ship is not on screen. If no arguments are supplied, self’s velocity is returned.
;; Check if a ship is friendly (define (friendly? ship) (= (team) (team ship))) ;; Check if a ship is hostile (define hostile? (complement friendly?))
See also: teamplay?
- function (life . ships) → l1 l2 …
-
Ships' remaining lives on server, or #f if ship is not on screen. If no arguments are supplied, self’s remaining lives is returned.
- function (shield? . ships) → s1 s2 …
-
Status of ships' shields. #t if shield is on, #f if shield is off or ship is not on screen. The existance of a ship should be checked first with the function on-screen?.
See also: on-screen?, on-radar?, shield
3.2 Functions for accessing self state only
3.3 Functions for accessing other ships' state
See also: on-radar?
See also: vel
;; Self always points at nearest on screen ship
(define (AI-main)
(when (on-screen? 0)
(turn (anglediff (heading)
(xdir 0)))))
(use srfi-1)
;; Get a list of ships that satisfy a predicate
(define (ships pred)
(filter pred (unfold on-screen?
identity add1 0)))
;; Get a list of friendly on-screen ships
(ships friendly?)
;; Get a list of enemy on-screen ships
(ships hostile?)
See also: xdir
function (aimdir ship1 . ships) → d1 d2 … Calculates the direction self would need to point to hit the ship, according to track and velocity of self and target. Returns #f if ship is not on screen.
;; bot that aims and shoots at nearest ship
(define (AI-main)
(when (on-screen? 0)
(turn (anglediff (heading) (aimdir 0)))
(shoot)))
4. Radar
Functions returning information about other ships on the radar. The ships are sorted from nearest to furthest.
See also: x-pos
See also: y-pos
;; self always points at second-nearest radar ship
(define (AI-main)
(when (on-radar? 1)
(turn (anglediff (heading)
(radar-xdir 1)))))
5. Shots
Functions returning information about the shots on the screen.
See also: shot-track
See also: ship-dist, radar-dist
- function (shot-imaginary ship1 . ships) → i1 i2 …
-
Imaginary shots are calculated for every ship on screen. If a ship were to shoot this frame, imaginary bullets tell that shot’s attributes. Returns #f if ship is not on screen.
- function (shot-xdir shot1 . shots) → d1 d2 …
-
Direction of shot from self, or #f if shot is not on the screen.
See also: shot-idir
;; self turns away from intercept dir and thrusts
(define (AI-main)
(when (shot-x 0)
(turn (anglediff (heading)
(angleadd (idir 0) 180)))
(thrust)))
See also: shot-idist, shot-itime
- function (shot-idist shot1 . shots) → d1 d2 …
-
Number of frames until the nearest intercept will occur, if both self velocity and bullet velocity remain constant. Returns #f if shot is not on screen.
- function (shot-alert shot1 . shots) → a1 a2 …
-
A value derived from idist and itime . An alert between 0 and 30 means that self will probably be killed by the shot, 30 to 120, that it is a dangerous shot and should be avoided, and above 120, it’s not very dangerous. This variable is just for convience, and should probably not be used in more advanced controllers.
6. Walls and Map
Functions to check for walls and to look at map tiles
- function (wall-between x1 y1 #!optional x2 y2) → bool, x, y
-
This function checks for walls in a straight line starting from point (x1, y1) and ending at point (x2, y2). If it finds a wall, it returns the distance in pixels from (x1, y1) to that point, and the x and y position of the point as secondary values. Otherwise, it returns #f. If x2 and y2 are not supplied, then wall-between looks for a wall between self’s position and x1, y1.
;; this checks for a wall 200 pixels
;; in front of the ships track
(define (wall-ahead)
(wall-between
(+ (x-pos)
(* 200 (cos (deg->rad (track)))))
(+ (y-pos)
(* 200 (sin (deg->rad (track)))))))
;; Display position of wall ahead of track
(use srfi-11) ; for let-values
(let-values ((wall x y) (wall-ahead))
(when wall
(printf "Wall ~A px ahead at (~A,~A)"
x y)))
- function (tile #!optional x y) → unsigned int
-
The map consists of tiles which are 35x35 pixels each. Each tile contains information about that spot on the map, and can have multiple values. For instance, a square block tile may have 5 bit flags set; one for each side, and one to indicate it is a wall tile. The possible flags are listed below. Use the bitwise "and" operator to check the tiles for the flags. This function returns the value stored in the tile containing the point (x, y). If x and y are not supplied, self’s position is used.
;; checks to see if the map tile to the right of the player
;; contains a wall of some sort
(when (positive?
(bitwise-and (tile (+ (pos-x) 20) (pos-y))
BLUE_BIT))
(print "To the right is a wall tile!"))
Here is a list of tile types.
SETUP_SPACE 0 SETUP_FILLED 1 SETUP_FILLED_NO_DRAW 2 SETUP_FUEL 3 SETUP_REC_RU 4 SETUP_REC_RD 5 SETUP_REC_LU 6 SETUP_REC_LD 7 SETUP_ACWISE_GRAV 8 SETUP_CWISE_GRAV 9 SETUP_POS_GRAV 10 SETUP_NEG_GRAV 11 SETUP_WORM_NORMAL 12 SETUP_WORM_IN 13 SETUP_WORM_OUT 14 SETUP_CANNON_UP 15 SETUP_CANNON_RIGHT 16 SETUP_CANNON_DOWN 17 SETUP_CANNON_LEFT 18 SETUP_SPACE_DOT 19 SETUP_TREASURE 20 ; + team number (10) SETUP_BASE_LOWEST 30 ; lowest base number SETUP_BASE_UP 30 ; + team number (10) SETUP_BASE_RIGHT 40 ; + team number (10) SETUP_BASE_DOWN 50 ; + team number (10) SETUP_BASE_LEFT 60 ; + team number (10) SETUP_BASE_HIGHEST 69 ; highest base number SETUP_TARGET 70 ; + team number (10) SETUP_CHECK 80 ; + check point number (26) SETUP_ITEM_CONCENTRATOR 110 SETUP_DECOR_FILLED 111 SETUP_DECOR_RU 112 SETUP_DECOR_RD 113 SETUP_DECOR_LU 114 SETUP_DECOR_LD 115 SETUP_DECOR_DOT_FILLED 116 SETUP_DECOR_DOT_RU 117 SETUP_DECOR_DOT_RD 118 SETUP_DECOR_DOT_LU 119 SETUP_DECOR_DOT_LD 120 SETUP_UP_GRAV 121 SETUP_DOWN_GRAV 122 SETUP_RIGHT_GRAV 123 SETUP_LEFT_GRAV 124 SETUP_ASTEROID_CONCENTRATOR 125 BLUE_UP 0x01 BLUE_RIGHT 0x02 BLUE_DOWN 0x04 BLUE_LEFT 0x08 BLUE_OPEN 0x10 ; diagonal botleft -> rightup BLUE_CLOSED 0x20 ; diagonal topleft -> rightdown BLUE_FUEL 0x30 ; when filled block is fuelstation BLUE_BELOW 0x40 ; when triangle is below diagonal BLUE_BIT 0x80 ; set when drawn with blue lines DECOR_LEFT 0x01 DECOR_RIGHT 0x02 DECOR_DOWN 0x04 DECOR_UP 0x08 DECOR_OPEN 0x10 DECOR_CLOSED 0x20 DECOR_BELOW 0x40
See also: tile-set!
- function (tile-set! x y val) → #<void>
- function (tile-set! val) → #<void>
-
The map tiles in Xpilot-AI are 32 bits. Only the lowest order bits are used for Xpilot, so the other bits can be set as desired. If an x and y argument are not supplied, the tile containing self’s position is used. Otherwise, the tile containing (x, y) is used.
;; Sets a bit flag on the map tile underneath self (tile-set! (bitwise-ior (tile) 0x1000))
7. Messages
Write and recieve messages using the player-to-player messaging system in Xpilot
function (talk . messages) → #<void> Say a message through the player-to-player talk system in Xpilot. Arguments may be of any type, and are concatenated together to form a string.
Note: Sometimes xpilot servers kick out players that type too much, or send two messages in on frame. Because of this, if talk is called more than once per frame, it will automatically spread sending the messages over several frames.
;; Writes a message to everyone
(talk "Hello everyone!")
;; Writes a private message to "Jimmy"
(talk "Jimmy: hello I'm at" (pos))
;; Change to team of closest ship
(when (on-screen? 0)
(talk "/team" (team 0)))
;; cycles through all the messages recieved
;; every frame and prints the body
(use srfi-1)
(define (print-bodies)
(for-each print
(unfold msg-body
msg-body add1 0)))
8. HUD
The HUD is the informative box around the self’s ship. These functions access various information from the HUD, like the info about who killed who (Useful for determing kills).
- function (HUD-name index1 . idx) → n1 n2…
-
Look at a HUD slot’s name field. Returns #f if there is no name in that slot.
- function (HUD-score index1 . idx) → s1 s2…
-
Look at a HUD slot’s score field. It is best to check for empty slots using [AIself.HUD.time?] . Returns #f if slot does not exist.
- function (HUD-time index1 . idx) → t1 t2…
-
Number of frames that the HUD message has been on the HUD slot. When a score first appears it will have a value of 0, then increase each frame thereafter until it gets to about 99.
(use srfi-1)
;; Return a list of all HUD messages
(define (HUD-list field)
(unfold HUD-time field add1 0))
;; Return a list of HUD messages with positive scores
(define (HUD-gains)
(filter positive?
(HUD-list HUD-score)))
9. Arithmetic functions
Useful math functions
#;1> (anglediff 90 70) -20 #;2> (anglediff 350 10) 20
#;1> (angleadd 90 70) 160 #;2> (angleadd 350 40 10) 40