JavaScript and TypeScript

JavaScript and TypeScript

> Programming

 

Since version 2.49, besides LeekScript, you can write your leeks' artificial intelligences on Leek Wars in JavaScript, TypeScript or Python. AIs run in a secure and deterministic environment, with access to the whole combat API of the game, and can fight AIs written in any other language.

Choosing the language

The language of an AI is determined by its file extension:

| Language | Extension | |----------|-----------| | LeekScript | (none) | | JavaScript | .js or .mjs | | TypeScript | .ts or .mts | | Python | .py |

You pick the language when creating a file ("New AI" button in the editor) or as the default language of your first AI when signing up. Renaming a file with a different extension changes its language.

Entry point: turn()

Each turn, the engine runs your AI. Two ways to write it:

Simple AI: write your code directly, it runs every turn (in a fresh scope, no state is kept):

Stateful AI: define a turn() function. The file body runs only once (declare your classes and persistent variables there), then turn() runs every turn:

The combat API

The game API is exposed in an object-oriented form. There is no global me variable: get your entity via Fight.me.

Unlike LeekScript, there are no global functions and no "flat" constants (getNearestEnemy(), WEAPON_PISTOL…): the whole API goes through the objects below.

Class tree

Entities returned by the API are typed: enemy instanceof Leek, enemy instanceof Bulb

| Class | Main members | |-------|--------------| | Entity | life, maxLife, tp, mp, strength, agility, wisdom, resistance, science, magic, level, name, cell, weapon, weapons, chips, effects, states, summons, alive, dead, isAlly(), isEnemy(), distance(target) | | Me | everything from Entity, plus the actions: moveToward(target), moveAwayFrom(target), useWeapon(target), useChip(chip, target), setWeapon(weapon), say(message), summon(chip, cell, ai), canUseWeapon(target), weaponCell(target), chipCells(chip, target), weaponTargets(cell)… | | Cell | x, y, empty, obstacle, entity, distance(target), pathLength(target), lineOfSight(target), path(target) | | Weapon / Chip | cost, minRange, maxRange, area, launchType, maxUses, needsLos, features (plus cooldown and currentCooldown for Chip) | | Effect | type, value, caster, turns, critical, item, target | | Feature | type, minValue, maxValue, turns, targets |

Alongside the classes, four singletons:

| Singleton | Role | Main members | |-----------|------|--------------| | Fight | the fight | me, turn, getNearestEnemy(), getFarthestEnemy(), getEnemies(), getAliveEnemies(), getAllies(), getAlliedTurret()… | | Field | the field | cellFromXY(x, y), getObstacles(), distance(a, b), pathLength(a, b), lineOfSight(a, b), path(a, b) | | Registers | storage persisted between fights | get(key), set(key, value), delete(key), all() | | Debug | field visualization | mark(cells, color), markText(cells, text), show(cell), clearMarks(), pause() |

Constants

Constants are grouped by family, in two forms:

The editor's autocompletion (Weapon., Effect., Entity.Stat.…) lists all available members.

Multiple files

Split your AI into ES modules (import / export):

Only your own files are accessible: no disk, network or system access.

TypeScript

In .ts files, the editor checks your types live: the whole combat API is typed (classes, methods, constants), with full autocompletion. At fight time, TypeScript is transpiled to JavaScript by the official tsc compiler, then run by the same engine. A type error makes the AI invalid, just like a LeekScript compilation error.

Execution environment

See also