▚ BATTLE CODE ARENA // BCAS REFERENCE PLAY ▶

Functions and records

Everything a program can call and read, as the game defines it. A library is imported by name (from vehicle import drive, radar), and most need the equipment that provides them fitted to the vehicle.

Built-in functions

Always there: no import needed.

abs(value)
Absolute value.
min(a, b)
The smaller of two numbers.
max(a, b)
The larger of two numbers.
clamp(value, low, high)
Keeps value within low..high. low must not exceed high.
wrap(angle)
Normalises an angle to 0..360 (360 excluded).
angle_diff(target, current)
Shortest signed turn from current to target, -180..180. Positive is clockwise.
bearing_to(x1, y1, x2, y2)
Absolute bearing from the first point to the second.

drive

Needs a fitted drive unit. from vehicle import drive

drive.set(throttle, turn)→ None
Persistent. throttle -1..1 is a fraction of the drive's effort, forwards or (negative) in reverse, where steering swaps over; turn -1..1 is a fraction of the turn rate (positive is clockwise). The last call in an update wins.
drive.charge()→ None
One-off request to start charging at a charging point: the vehicle must be stopped within reach of one, and its tank not full. It then charges until full, or until it moves off. It works during a power failure. Energy comes back nowhere else. Find charging points with radar.echo().

radar

Needs a fitted radar. from vehicle import radar

radar.scan(bearing)→ None
One-off request to scan an absolute bearing in degrees. It does NOT return the result: read radar.contact() on the next update. The last call in an update wins.
radar.contact()→ contact or None
The result of the most recent completed scan: a contact record, or None if it found nothing. A rejected scan leaves the old result in place, so check seen_at.
radar.track()→ None
One-off request to a tracking radar (Silver) to lock onto what its last scan found, if that scan was this update's or the last one's. Once locked, radar.tracked() reports it every update without scanning. The lock holds until the target leaves the radar's range or its line of sight, the radar loses power, or the target is a decoy that fades. It draws energy all the time it is locked. Any other radar rejects it.
radar.tracked()→ contact or None
What a tracking radar is locked onto, as of this update: a contact record, with its heading and speed as well, or None if there is no lock. Costs nothing beyond the lock's energy.
radar.echo()→ echo or None
What the most recent completed scan ran into along its bearing: the nearest obstacle, arena wall, stocked supply crate, charging point or stocked repair depot within the radar's range, as an echo record, or None if there was nothing. The opponent is not an echo: that is the contact. Costs nothing: it comes with every scan. A rejected scan leaves the old echo in place.

missiles

Needs a fitted missile launcher. from vehicle import missiles

missiles.ready()→ True or False
True when loaded, not reloading, not overheated, with power and with energy for one shot, as of this update. Advisory only: it reserves nothing.
missiles.aim(bearing)→ None
Persistent. Turns the turret towards an absolute bearing in degrees. The turret takes time to get there: it turns at the launcher's traverse rate. missiles.turret() says where it points now. The last call in an update wins.
missiles.fire()→ None
One-off request to launch an unguided missile along the turret as it points now (missiles.turret()), wherever it has been told to aim. It can be rejected: weapon reloading, no ammunition, overheated or insufficient energy.
missiles.reload()→ None
One-off request to reload the launcher from a supply crate: the vehicle must be stopped within reach of a stocked crate, and the launcher not full. It takes time, and moving off cancels it; meanwhile missiles.ready() is False. It empties the crate until it restocks. Find crates with radar.echo().
missiles.turret()→ degrees
The absolute bearing the turret points along now, as of this update. A missile leaves on this bearing.
missiles.ammo()→ a number
Missiles left in the launcher. missiles.reload() at a supply crate fills it again.

shield

Needs a fitted shield generator. from vehicle import shield

shield.set_level(level)→ None
Persistent. level 0..1; 0 is off. Drains energy and adds heat in proportion while powered.
shield.level()→ 0 to 1
The shield setting last committed. It says nothing of whether the shield has power.

warning

Needs a fitted missile warning sensor. from vehicle import warning

warning.threat()→ threat or None
The incoming missile that will arrive soonest, as of this update: a threat record, or None if nothing is coming for you. A threat is an opponent's missile within the sensor's range, closing, and set to pass close by if neither of you changes course, with no obstacle in the way. None during a power failure.
warning.count()→ a number
How many incoming missiles the sensor reports as threats, as of this update.

decoys

Needs a fitted decoy launcher. from vehicle import decoys

decoys.launch()→ None
One-off request to drop a decoy (Silver). It drifts behind the vehicle for a few seconds; to the opponent's radar and guided missiles it is a target, and whichever is nearest is the one they take. A radar locked onto you follows the decoy instead. It can be rejected: none left, launcher cooling down, power failure or insufficient energy.
decoys.left()→ a number
Decoys left, as of this update. There is no restocking them.
decoys.ready()→ True or False
True when a decoy can be launched now: one left, not cooling down, with power and energy for it. Advisory only.

close

Needs a fitted close-combat weapon. from vehicle import close

close.fire()→ None
One-off request to the close-combat weapon (Silver), which points where the hull does. An autocannon fires one shot straight ahead if it is ready; a flamethrower burns until the next update; a ram plate does nothing (it rams when you drive into the opponent). It does nothing while overheated, without power, or without the energy for it.
close.ready()→ True or False
True when the weapon would act on close.fire() now: not overheated, with power and energy, and an autocannon's next shot due. A ram plate is always ready. Advisory only.
close.kind()→ a string
What is fitted: "cannon", "flame" or "ram".

hull

Always available: needs no equipment. from vehicle import hull

hull.repair()→ None
One-off request to repair at a repair depot: the vehicle must be stopped within reach of a stocked depot, and damaged. It then repairs a share of its full health over a few seconds; moving off stops it, keeping what was done. The depot is then empty until it restocks. Every vehicle has a hull. Find depots with radar.echo().

debug

Always available: needs no equipment. from vehicle import debug

debug.log(value)→ None
Attaches a number, string, boolean or None to the replay timeline. The first 4 messages in an update are kept.

The state record

What your vehicle knows about itself at this update: the first argument of update(state, memory). Read a field as state.energy.

FieldUnitWhat it is
timesecondsSimulated time at this update.
tickintegerPhysics tick, starting at 0.
dtsecondsTime between updates (0.1).
xmetresYour centre. 0 is the left wall.
ymetresYour centre. 0 is the top wall; y grows downwards.
headingdegreesYour absolute heading: 0 north, 90 east.
speedm/sSpeed along the heading: negative in reverse.
health0-100Remaining health, as a percentage. A repair depot gives some back (hull.repair()).
energyunitsEnergy available. Nothing gives it back but a charging point (drive.charge()).
energy_maxunitsEnergy capacity.
heat0-100Current heat.
overheatedbooleanTrue during thermal lockout: weapons and shield are offline.
power_outbooleanTrue during a power failure: you ran out of energy, and drive, shield, radar and launcher are offline until it recovers.
blockedbooleanTrue if you touched a wall, an obstacle or a vehicle since the last update.
arena_widthmetresWidth of the arena.
arena_heightmetresHeight of the arena.

Contact records

What radar.contact() (and a tracking radar's radar.tracked()) returns when a scan found the opponent; None when it found nothing.

FieldUnitWhat it is
bearingdegreesObserved absolute bearing from you to the target.
rangemetresObserved distance between centres.
xmetresEstimated target x, from the same observation.
ymetresEstimated target y, from the same observation.
seen_atsecondsWhen the scan observed the target.

Threat records

What warning.threat() returns: the opponent's missile that will reach you soonest; None when none is coming your way.

FieldUnitWhat it is
bearingdegreesAbsolute bearing from you to the missile.
rangemetresHow far off the missile is.
headingdegreesThe missile's course: the way it is flying.
etasecondsHow long until it passes nearest, if neither of you changes course.
seen_atsecondsWhen the sensor reported it.

Echo records

What radar.echo() returns: what the last scan ran into along its bearing, other than the opponent. This is how a program finds walls, obstacles, supply crates, charging points and repair depots.

FieldUnitWhat it is
bearingdegreesThe bearing that was scanned.
rangemetresHow far the scan went before something stopped it.
xmetresWhere it stopped, from the same bearing and range.
ymetresWhere it stopped, from the same bearing and range.
wallbooleanTrue if it was an arena wall; False if an obstacle or a crate.
supplybooleanTrue if it was a stocked supply crate. x and y are then the crate's middle.
chargerbooleanTrue if it was a charging point. x and y are then its middle.
repairbooleanTrue if it was a stocked repair depot. x and y are then its middle.
seen_atsecondsWhen the scan was made.