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.
from vehicle import drive, radar
def update(state, memory):
radar.scan(0)
drive.set(throttle=0.5, turn=0)- Imports come first, each
from vehicle importfollowed by library names. Import only what the vehicle has the equipment for;hullanddebugneed none. - The function is always
def update(state, memory):. The game calls it 10 updates / s. - Indentation is four spaces a level. Tabs are refused.
- Comments start with
#and run to the end of the line.
Values
| Numbers | 3, -0.5, 140. One kind of number, with decimals. |
|---|---|
| Strings | "attack". For modes and log messages; up to 256 characters. |
| Booleans | True and False. |
| None | Nothing: what a memory field holds before it's set, and what radar.contact() returns when a scan found nothing. |
| Records | What 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) |
| Logic | and or not |
| Grouping | ( ) |
From weakest to strongest: or, and, not, comparisons, + -, * / %, then signs. Use brackets whenever it isn't obvious.
Statements
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- Assignment to a local name, or to
memory.field. - A call: a library function (
radar.scan(90)) or a built-in (clamp(x, -1, 1)). Arguments may be named:drive.set(throttle=1, turn=0). if/elif/else, as deep as 32 levels.returnends this update early;passdoes 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, for | No loops. Keep a counter in memory and carry on at the next update. |
|---|---|
def (again), lambda, class | One function only, update. |
Lists, in, len, range | No collections. Use separate memory fields. |
try, except, raise | No exceptions. Check values with if before using them. |
print | Use debug.log(value). |
is | Use == None or != None. |
global, nonlocal | Use memory.field for values that last. |
int(), str(), round(), random | No conversions or randomness: a battle is the same every time it's fought with the same seed. |
Import aliases, import x | Only 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 size | 64 KiB |
|---|---|
| Operations per update | 2000 (a call costs 10 operations extra) |
| Memory | 64 fields, 16 KiB in all |
| Local variables | 128 |
| Strings | 256 characters |
| Debug messages | 4 an update |
| Nesting | 32 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.