Programming robots
Starting with release 011, server admins will be able to program their own robots in addition to designing their own levels. Robots will be coded in Lua, and will will have a number of special functions available to them.
Robot coding is still fluid, and everything is subject to change, but here is a list of commands being implemented for the next alpha release (see forums for the URL):
Contents
getZoneCenterXY( x, y ) - Return point representing center of zone containing point x,y
getGatewayFromZoneToZone( a, b ) - Return point representing fastest way from zone a to zone b. If zones a & b are not neighbors, returns nil
getZoneCount() - Return number of zones (returns int)
getCurrentZone() - Return current zone that robot is in (returns int)
getAngle() - Return angle robot is currently facing (returns float)
getPosXY() - Return x, y of robot (returns Point)
setAngle( ang ) - Point robot at angle (returns nothing)
setAngleXY( x, y ) - Point robot towards point x,y (returns nothing)
getAngleXY( x, y ) - Compute angle to point x, y (returns float)
hasLosXY( x, y ) - Return whether or not robot can see point x, y (returns boolean)
hasFlag() - Return whether or not robot currently has the flag
getWeapon() - Return currently selected weapon (returns WeaponType)
Example:
weap = bot:getWeapon() -- Get info about our currently active weapon weapInfo = WeaponInfo( weap ) -- Get information about it bot:logprint( weapInfo:getName().." has a range of "..weapInfo:getRange() )
activateModule(ModuleType) - Activate module, specified by ModuleType. If specified module is not included in the current loadout, this command will have no effect. (returns nothing) Example:
-- Note that this line will do nothing if we don't have shields bot:activateModule( ModuleShield ) -- Shields up!
activateModuleIndex(indx) - Activate module, specified by its index (1 or 2) (returns nothing)
Example:
-- Must specify an index, currently either 1 or 2 bot:activateModuleIndex( 1 ) -- Activate first module, whatever it is
setReqLoadout(Loadout) - Set the requested loadout to Loadout (returns nothing)
getCurrLoadout() - Returns current loadout (returns Loadout)
Example:
loadout = bot:getCurrLoadout() -- Retrieve current bot configuration weapType1 = loadout:getWeapon(1) -- Get the first weapon weapType2 = loadout:getWeapon(2) -- Get the second weapon weapType3 = loadout:getWeapon(3) -- Get the third weapon -- Check to see if the first weapon is a phaser if ( weapType1 == WeaponPhaser ) then bot:logprint("First weapon is a phaser!") end -- Print a list of our three current weapons bot:logprint( "My three weapons are: "..WeaponInfo(weapType1):getName()..", " ..WeaponInfo(weapType2):getName()..", and " ..WeaponInfo(weapType3):getName() )
getReqLoadout() - Returns requested loadout (returns Loadout)
Navigation
findObjects(ObjectType)
getWaypoint(x, y)
Ship control
setThrustAng( vel, angle ) - Set robot's velocity to vel (0-1), at angle (returns nothing)
setThrustXY( vel, x, y ) - Set robot's velocity to vel (0-1), toward coordinates x, y (returns nothing)
fire() - Fires active weapon (returns nothing)
setWeaponIndex( index ) - Activates weapon with index (1, 2, 3) (returns nothing)
setWeapon( WeaponType ) - Activates weapon type specified (does nothing if WeaponType is not in current loadout) (returns nothing)
hasWeapon (WeaponType ) - Does current configuation have specified weapon (returns boolean)
Example:
if ( bot:hasWeapon( WeaponMine ) ) then bot:setWeapon( WeaponMine ) -- Make mine layer active, if it's -- part of our current loadout bot:fire() -- Lay a mine end
globalMsg( msg ) - Send a message to all players (returns nothing)
teamMsg( msg ) - Send a message to players on the same team (returns nothing)
logprint(msg) - Print msg to game logfile
GameItems
The Lua object structure follows that used by Bitfighter. The GameItems group conisists of RepairItems, Asteroids, ResourceItems, and TestItems. These all share similar properties, and have similar methods. All of these implement the getLoc, getVel, and getRad methods for querying location, velocity, and radius respectively. Some items have additional methods that apply only to them. See below for details on these additional methods.
TestItems
Category: GameItem
getLoc() - Center of testItem (returns point)
getRad() - Radius of testItem (returns number)
getVel() - Speed of testItem (returns point)
Example:
ti = bot:findTestItem() -- Function likely to change vel = it:getVel()
Asteroids
Category: GameItem
getSize() - Index of current asteroid size (0 = initial size, 1 = next smaller, 2 = ...) (returns int)
getSizeCount() - Number of indexes of size we can have (returns int)
getLoc() - Center of asteroid (returns point)
getRad() - Radius of asteroid (returns number)
getVel() - Speed of asteroid (returns point)
Example:
asteroid = bot:findAsteroid() -- Function likely to change target = asteroid:getLoc()
ResourceItems
Category: GameItem
getLoc() - Center of ResourceItem (returns point)
getRad() - Radius of ResourceItem (returns number)
getVel() - Speed of ResourceItem (returns point)
Example:
ri = bot:ResourceItem() -- Function likely to change vel = ri:getVel()
RepairItems
Category: GameItem
getLoc() - Center of RepairItem (returns point)
getRad() - Radius of RepairItem (returns number)
getVel() - Speed of RepairItem (returns point, usually 0,0)
isVis() - Is repair item currently visible? (returns boolean)
Example:
ri = bot:findRepairItem() -- Function likely to change vel = ri:getVel()
Weapon Information
All the WeaponInfo data will remain constant throughout the game. Therefore, if you need some information about a weapon, it might make sense to retrieve it in the bot's header and store it in a local variable rather than instantiating a new WeaponInfo object during every loop of the robot's getMove() method.
Example:
weap = bot:getWeapon() -- Get bot's currently active weapon bot:logprint( weap:getName().." has a range of "..weap:getRange() )
weap = WeaponInfo( WeaponTurret ) -- Get info about those infernal turrets bot:logprint( weap:getName().." shoots with a speed of "..weap:getProjVel() )
getName() - Name of weapon ("Phaser", "Triple", etc.) (returns string)
getID() - ID of module (WeaponPhaser, WeaponTriple, etc.) (returns WeaponType)
getRange() - Get range of weapon (units) (returns integer)
getFireDelay() - Delay between shots in ms (returns integer)
getMinEnergy() - Minimum energy needed to use (returns integer)
getEnergyDrain() - Amount of energy weapon consumes (returns integer)
getProjVel() - Speed of projectile (units/sec) (returns integer)
getProjLife() - Time projectile will live (ms) (returns integer, -1 == live forever)
getDamage() - Damage projectile does (0-1, where 1 = total destruction) (returns float)
getCanDamageSelf() - Will weapon damage self? (returns boolean)
getCanDamageTeammate() - Will weapon damage teammates? (returns boolean)
WeaponType constants
WeaponPhaser | WeaponBounce |
WeaponTriple | WeaponBurst |
WeaponMine | WeaponSpyBug |
WeaponTurret |
Module Information
Example:
mod = ModuleInfo( ModuleBoost ) bot:logprint( "This is a lame example!" )
getName() - Name of module ("Shield", "Turbo", etc.) (returns string)
getID() - ID of module (ModuleShield, ModuleBoost, etc.) (returns ModuleType)
ModuleType constants
ModuleShield | ModuleBoost |
ModuleSensor | ModuleRepair |
ModuleCloak | ModuleEngineer (maybe someday) |
Loadouts
setWeapon(index, WeaponType) - Set weapon at index (returns nothing)
setModule(index, ModuleType) - Set module at index (returns nothing)
getWeapon(index) - return weapon at index (returns WeaponType)
getModule(index) - return module at index (returns ModuleType)
Example:
-- Get a new loadout (comes pre-filled with default values) loadout = Loadout() -- Configure the loadout to suit our needs loadout:setWeapon( 1, WeaponPhaser ) loadout:setWeapon( 2, WeaponBurst ) loadout:setWeapon( 3, WeaponMine ) loadout:setModule( 1, ModuleShield ) loadout:setModule( 2, ModuleCloak ) -- Set the loadout, will become active when bot hits loadout zone -- or spawns, depending on game bot:setReqLoadout( loadout ) if( loadout:getWeapon(1) == WeaponPhaser) then bot:logprintf( "This line always gets printed!" ) end
isValid() - Is loadout config valid? (returns boolean)
equals(Loadout) - is loadout the same as Loadout? (returns boolean)
GameInfo
You can get information about the current game with the GameInfo object. You only need get this object once, then you can use it as often as you like. It will always reflect the latest data.
Example:
game = GameInfo() -- Create the GameInfo object gameType = game:getGameType() if( gameType == SoccerGame ) then bot:logprint("This bot is not very good at soccer!") else gameTypeName = game:getGameTypeName() bot:logprintf("I just love playing "..gameTypeName.."!") end
Example:
-- Create the GameInfo object in header: game = GameInfo() ... -- Even though we only create our GameInfo once, it is always current ... -- Later, in getMove(): remTime = game:getGameTimeReamaining() totTime = game:getGameTimeTotal() percent = ( totTime - remTime ) / remTime bot:logprint( "Game is "..percent.."% over )
getGameType() - Return current game type (returns GameType constant)
getGameTypeName() - Return current game type (returns string)
getFlagCount() - Return the number of flags in the game (returns int)
getWinningScore() - Returns the score required to win the level (returns int)
getGameTimeTotal() - Returns the time (in seconds) that the level will be played for (returns int)
getGameTimeRemaining() - Returns the time remaining (in seconds) for this level (returns int)
getLeadingScore() - Gets score of the leading team (returns int)
getLeadingTeam() - Gets index of leading team (returns int)
getTeamCount() - Return number of teams (returns int)
Example:
-- Create the GameInfo object in header: game = GameInfo() ... -- Then later... leadingTeam = game:getLeadingTeam() team = TeamInfo( leadingTeam ) bot:teamMsg( "Hurry up! Team "..team:getName().." is winning!" )
getLevelName() - Gets the level's name (returns string)
getGridSize() - Gets the level's gridSize parameter (returns float)
getIsTeamGame() - Is this a team game? (returns boolean)
getEventScore(ScoringEvent)
GameType constants
BitmatchGame | CTFGame |
HTFGame | NexusGame |
RabbitGame | RetrieveGame |
SoccerGame | ZoneControlGame |
ScoringEvent constants
KillEnemy | KillSelf |
KillTeammate | KillEnemyTurret |
KillOwnTurret | CaptureFlag |
CaptureZone | UncaptureZone |
HoldFlagInZone | RemoveFlagFromEnemyZone |
RabbitHoldsFlag | RabbitKilled |
RabbitKills | ReturnFlagsToNexus |
ReturnFlagToZone | LostFlag |
ReturnTeamFlag | ScoreGoalEnemyTeam |
ScoreGoalHostileTeam | ScoreGoalOwnTeam |
TeamInfo
getName() - return team name (returns string)
getIndex() - return team's index, index of first team is 1 (returns int)
getPlayerCount() - return player count (returns int)
getScore() - return team score (returns int)
Example:
gameInfo = GameInfo() teams = gameInfo:getTeamCount() -- Note that while the number of teams will not change throughout the game, -- the number of players on each team might. Also, the robot may be initialized -- before the players have been added, so if you run this code in the bot header, -- it may report some teams having 0 players. for i = 1, teams do -- First team has an index of 1 team = TeamInfo( i ) bot:logprint( "Team "..i.." is called "..team:getName().. " and has "..team:getPlayerCount().." players" ) end
Misc
Some constants available in game:
Game Objects
ShipType
BarrierType
MoveableType
BulletType
ItemType
ResourceItemType
EngineeredType
ForceFieldType
LoadoutZoneType
MineType
TestItemType
FlagType
TurretTargetType
SlipZoneType
HeatSeekerType
SpyBugType
NexusType
BotNavMeshZoneType
RobotType
TeleportType
GoalZoneType
AsteroidType