▚ BATTLE CODE ARENA // BCAS REFERENCE PLAY ▶

The language

All of BCAS 1.6 on one page. If you know a little Python, most of it will look familiar; the differences are mostly things BCAS leaves out.

The shape of a program

A program is imports, then one function. Nothing else may be at the top level.

The shape
from vehicle import drive, radar

def update(state, memory):
    radar.scan(0)
    drive.set(throttle=0.5, turn=0)

Values

Numbers3, -0.5, 140. One kind of number, with decimals.
Strings"attack". For modes and log messages; up to 256 characters.
BooleansTrue and False.
NoneNothing: what a memory field holds before it's set, and what radar.contact() returns when a scan found nothing.
RecordsWhat the game hands you: state, contacts, threats and echoes. Read their fields with a dot (contact.range). See the records.

In a condition, None, False, 0 and the empty string count as false, and a record as true, so if contact: asks whether there is one. Unlike Python, and and or always give True or False, never one of their operands.

Operators

Arithmetic+ - * / % (remainder), and a leading - or +
Comparison== != < <= > >=, one to an expression (no a < b < c)
Logicand or not
Grouping( )

From weakest to strongest: or, and, not, comparisons, + -, * / %, then signs. Use brackets whenever it isn't obvious.

Statements

Every kind of statement
range_left = contact.range - 50      # a local variable
memory.last_seen = state.time        # a memory field
debug.log("hello")                   # a call

if contact.range < 90:
    course = contact.bearing + 90
elif contact.range < 200:
    course = contact.bearing + 35
else:
    course = contact.bearing

if missiles.ammo() == 0:
    return                           # leave update early

if state.blocked:
    pass                             # a block that does nothing

Built-in functions

Seven, all about numbers and angles: abs, min, max, clamp, wrap, angle_diff and bearing_to. Everything else comes from the libraries.

Memory

memory is the only thing that lasts from one update to the next. Set a field and it keeps its value for the battle; a field never set reads as None. It holds numbers, strings, True, False and None: not records. See Memory, timers and modes.

What isn't there

BCAS refuses these before a battle, with a hint saying what to do instead:

while, forNo loops. Keep a counter in memory and carry on at the next update.
def (again), lambda, classOne function only, update.
Lists, in, len, rangeNo collections. Use separate memory fields.
try, except, raiseNo exceptions. Check values with if before using them.
printUse debug.log(value).
isUse == None or != None.
global, nonlocalUse memory.field for values that last.
int(), str(), round(), randomNo conversions or randomness: a battle is the same every time it's fought with the same seed.
Import aliases, import xOnly from vehicle import names.

Sections for classes

A vehicle promoted to a higher class gets a program section for that class: a whole program of its own, with its own imports and update. Each update, the sections run in turn from Bronze up, and a later section's orders replace an earlier one's. They have their own local variables and share memory. The editor shows each section in turn.

Limits

Program size64 KiB
Operations per update2000 (a call costs 10 operations extra)
Memory64 fields, 16 KiB in all
Local variables128
Strings256 characters
Debug messages4 an update
Nesting32 levels

Going over a limit in an update is a fault: that update's work is thrown away, and the program carries on at the next one. See faults.