Dig deeper into the Hexiscript programming language.

Hexiscript is a programming language designed for BotBattle. It provides a simple syntax with support for variables, control structures (conditionals and loops), and functions. Hexiscript programs execute from top to bottom, starting with the first statement. The language uses integer-only arithmetic and supports both global and local variable scoping.
Hexiscript is case-sensitive and uses a structured syntax with explicit block endings (e.g., end if, end while, end function). This makes the code more readable and helps prevent common programming errors.
Hexiscript uses a straightforward syntax where statements are written one per line. Variables are created implicitly when first assigned a value. The language supports decimal, binary, and hexadecimal number formats.
Variable names must start with a letter or underscore, followed by any combination of letters, digits, or underscores. Examples of valid variable names:
x
my_variable
value123
Value123 -- different variable from value123!
_counterHexiscript supports three number formats:
42, 100, 00b1010 (prefix with 0b)0x1A (prefix with 0x)Comments start with double dashes (--) and continue to the end of the line:
-- This is a comment
x = 10 -- This is also a commentHexiscript is case-sensitive, meaning myVar and myvar are different variables. Whitespace (spaces and tabs) is generally ignored except where it's needed to separate tokens.
x + y are valid, but chained operations like x + y + z are not. To compute complex expressions, break them into multiple statements using intermediate variables.Hexiscript supports a variety of operators for arithmetic, bitwise operations, and comparisons.
Binary operators perform operations on two values:
| Operator | Description |
|---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division (integer division, truncates toward zero) |
% | Modulus (remainder after division) |
& | Bitwise AND |
^ | Bitwise XOR |
| | Bitwise OR |
Unary operators operate on a single value:
| Operator | Description |
|---|---|
- | Negation (unary minus) |
+ | Positive (absolute value) |
~ | Bitwise NOT |
! | Logical NOT (returns 1 if value is 0, otherwise 0) |
Comparison operators are used in conditions and return 1 for true, 0 for false:
| Operator | Description |
|---|---|
== | Equal to |
!= | Not equal to |
> | Greater than |
< | Less than |
>= | Greater than or equal to |
<= | Less than or equal to |
Variables in Hexiscript are created implicitly when first assigned a value. There is no need to declare variables before using them.
Basic assignment uses the = operator:
x = 10
y = 20
result = x + yHexiscript supports compound assignment operators that combine an operation with assignment:
x = 10
x += 5 -- x is now 15 (equivalent to x = x + 5)
x -= 3 -- x is now 12 (equivalent to x = x - 3)
x *= 2 -- x is now 24 (equivalent to x = x * 2)
x /= 4 -- x is now 6 (equivalent to x = x / 4)Unary operations can also be used in assignments:
x = 10
y = -x -- y is -10
z = !x -- z is 0 (because x is not zero)
w = ~x -- w is bitwise NOT of xBinary operations combine exactly two values. You cannot chain multiple operations in a single statement:
x = 10
y = 5
sum = x + y -- 15 (valid: two operands)
diff = x - y -- 5 (valid: two operands)
prod = x * y -- 50 (valid: two operands)
quot = x / y -- 2 (integer division, valid: two operands)
mod = x % y -- 0 (valid: two operands)
and_result = x & y -- bitwise AND (valid: two operands)
or_result = x | y -- bitwise OR (valid: two operands)
xor_result = x ^ y -- bitwise XOR (valid: two operands)a * b * c, you would write:temp = a * b
result = temp * cHexiscript has two scopes: global and local. Variables assigned outside of any function are global. Variables assigned inside a function are local to that function, unless a global variable with the same name already exists.
When you assign a variable inside a function, Hexiscript checks in this order:
This means that functions can read and modify global variables, and new variables created inside a function are private to that function call:
score = 0 -- global variable
function add_score(points) do
score = score + points -- updates the global
temp = score * 2 -- temp is local, not visible outside
end function
add_score(10)
println(score) -- prints 10Conditional statements allow your program to execute different code based on conditions. The basic syntax is:
if (x == 10) then
print(x)
end ifYou can add an else clause for when the condition is false:
if (x > 10) then
print(1) -- print 1 to indicate "greater"
else
print(0) -- print 0 to indicate "not greater"
end ifMultiple conditions can be chained using else if:
if (x > 10) then
print(1) -- greater than 10
else if (x == 10) then
print(0) -- equal to 10
else
print(-1) -- less than 10
end ifWhile loops execute a block of code repeatedly as long as a condition is true:
x = 0
while (x < 10) do
print(x)
x = x + 1
end whileThe condition is checked before each iteration. If the condition is false initially, the loop body will never execute.
For loops iterate over a range of values:
for (i = 0 to 10) do
print(i)
end forThe loop variable (in this case i) is automatically incremented after each iteration. The loop runs from the start value (inclusive) to the end value (inclusive). If the start value is greater than the end value, the loop body never executes.
You can use variables or numbers for the start and end values:
start = 5
end = 15
for (i = start to end) do
print(i)
end forFunctions allow you to organize code into reusable blocks. Functions can take arguments and return values.
Functions are defined using the function keyword, followed by the function name, parameters in parentheses, and the function body:
function add(a, b) do
result = a + b
return result
end functionFunctions can take multiple parameters, separated by commas. To compute expressions with multiple operations, you must break them into multiple statements:
function multiply(a, b, c) do
temp = a * b
result = temp * c
return result
end functionFunctions can return multiple values. Note that return statements can only contain variables or numbers, not expressions:
function divide_and_mod(a, b) do
quotient = a / b
remainder = a % b
return quotient, remainder
end functionreturn a + b is invalid; you must write result = a + b followed by return result.Functions can be called without capturing return values:
print(42)
my_function(x, y)Or you can capture return values using assignment:
result = add(5, 3)
-- result is now 8When a function returns multiple values, you can capture them all:
q, r = divide_and_mod(10, 3)
-- q is 3, r is 1Functions cannot be defined inside other functions. All functions are defined at the top level of your program and can be called from anywhere.
a[i]. You cannot nest calls or pass expressions: foo(bar(1)) and min(a + b, 3) are syntax errors, even when bar and min are built-ins. Compute into a temporary variable first:t = bar(1)
x = foo(t)
s = a + b
m = min(s, 3)The same restriction applies to array indices: a[i] is valid, a[i + 1] is not.Arrays are lists of integers, useful for keeping scores, paths, maps of the board, or any collection of related values. Create one with an array literal (an empty array starts a list you build up with push):
scores = [3, 1, 4, 1, 5]
path = []Read and write elements with square brackets. The index can be a number or a variable (not a general expression, just like every other operand in HexiScript):
i = 2
x = scores[i] -- x is 4
scores[i] = 10 -- scores is now [3, 1, 10, 1, 5]
scores[0] += 7 -- compound assignment works tooArrays can change size. Four builtins work on them:
push(a, v) appends v to the end of ainsert(a, i, v) puts v at index i, shifting later elements upx = pop(a) removes the last element and returns it (error on an empty array)x = drop(a, i) removes the element at index i and returns itarrayLen(a) returns the number of elements, so the idiomatic loop over an array is:
total = 0
n = arrayLen(scores)
n1 = n - 1
for (i = 0 to n1) do
total = total + scores[i]
end forIndexed elements work anywhere a value can be read: in assignments, conditions, while loops, and as function arguments. Passing an array variable to a function shares it: the function sees (and can change) the same array.
Functions can also return arrays, on their own or mixed with scalars in the usual tuple style:
function neighbours(q, r) do
nb = [q, r]
nq = q + 1
push(nb, nq)
return nb
end function
p, d = someOtherFunction() -- p may be an array, d a numberHexiScript is a tick-based interpreter. Each game tick, your bot executes exactly one statement (an assignment, a condition check, a loop check, or a function call). The game then advances to the next tick.
In Hexidor, the game runs at 5,000 ticks per second, and each player has a 60 second turn clock (300,000 ticks). Your bot keeps executing statements every tick, also during the opponent's turn, but only your own clock counts down while it is your turn.
x = 5, y = x + 1): 1 tickif, else if, while condition, for condition): 1 tickEvery function has a tick cost. When your bot calls a function, it is paused for that many ticks. For example, in Hexidor, calling getSurroundings() costs 100 ticks and makeMove() costs 1,000 ticks.
Built-in language functions have the following costs:
| Function | Tick cost |
|---|---|
print(), println() | 0 (free) |
min(), max(), abs(), rand(), square(), pow(), sqrt(), root(), exp2(), gcd(), lcm(), is_prime(), reverse(), arrayLen() | 1 |
push(), pop(), insert(), drop() | 5 |
wait(n) | n (variable) |
User-defined functions cost 1 tick to enter (the function call itself), plus whatever ticks the function body uses.
print) do not consume a tick. Execution immediately continues to the next statement without advancing the game.while (1) do ... end while). If your code reaches the end and stops executing, your bot dies immediately. Use wait() to skip ticks without doing anything if you have no more work to do before the next move.While Hexiscript doesn't enforce a specific coding style, following these conventions will make your code more readable and maintainable:
my_variable, calculate_sum).--.x = y + z is clearer than x=y+z.Example of well-formatted code:
-- Calculate the sum of numbers from 1 to n
function sum_to_n(n) do
total = 0
for (i = 1 to n) do
total = total + i
end for
return total
end function
-- Main program
max_value = 10
result = sum_to_n(max_value)
print(result)Note that in the loop, total = total + i is valid because it uses exactly two operands (total and i). The assignment operator = is separate from the binary + operator.
Here you find an extended description of the built-in functions available in HexiScript.