Warlight AI Challenge

Do you want to join the fray?

Getting started with the Warlight AI Challenge is easy as pie. Just download one of the starter bots from the list to the right, change its behaviour and upload your code to The AI Games.

Is the language you’re looking for not listed or do you want to start from scratch? No problem! Look at the Languages page for a list of all available languages to code your bot in.

All communication between your bot and the engine works through the standard input and output channels. In the section "Communicating with the game engine" you can find a detailed explanation regarding the protocol all bots should implement to communicate with the game server.

We've also made our engine source code available for you. Use this for testing your bots locally for instance. Source code can be found on Github

Starter bots

C#Created by Fizzer
C++Created by MasterJos
ScalaCreated by ramn

A simple example

import java.util.Scanner;

public class MyBot {

    private Scanner scan = new Scanner(System.in);

    public void run()
        while(scan.hasNextLine()) {
            String line = scan.nextLine();

            if(line.length() == 0) {

            String[] parts = line.split(" ");

            if(parts[0].equals("pick_starting_regions")) {
                System.out.println( "give me randomly" );
            else if(parts.length == 3 && parts[0].equals("go")) {
                String output = "";

                if(parts[1].equals("place_armies")) {

                    for(int i=1; i<=42; i++) {
                        output.concat("myBot place_armies " + i + " 1,");
                else if(parts[1].equals("attack/transfer")) {
                    for(int i=1; i<=41; i++) {
                        output.concat("myBot attack/transfer " + i + " " + i+1 + " 1,");


    public static void main(String[] args) {
        (new MyBot()).run();

This is a simple example of a working bot. However, as the output for selecting the starting regions is not according to the required format, random regions will be picked by the engine. The bot will try to place 1 army on each region of the map and then try to attack/transfer 1 army from each region to the next neighbouring region.

Communicating with the game engine

Output from engineDescription
setup_map super_regions [-i -i ...]The superregions are given, with their bonus armies reward, all separated by spaces. Odd numbers are superregion ids, even numbers are rewards.
setup_map regions [-i -i ...]The regions are given, with their parent superregion, all separated by spaces. Odd numbers are the region ids, even numbers are the superregion ids.
setup_map neighbors [-i [-i,...] ...]The connectivity of the regions are given, first is the region id. Then the neighbouring regions' ids, separated by commas. Connectivity is only given in one way: 'region id' < 'neighbour id'.
pick_starting_regions -t [-i ...]Starting regions to be chosen from are given, request to return 6 region ids.
settings your_bot -bThe name of your bot is given.
settings opponent_bot -bThe name of your opponent bot is given.
settings starting_armies -iThe amount of armies your bot can place on the map at the start of this round.
update_map [-i -b -i ...]Visible map for the bot is given like this: region id; player owning region; number of armies.
opponent_moves [‑m ...]all the visible moves the opponent has done are given in consecutive order. -m can be any move and has the same format as in the table below
go place_armies -tRequest for the bot to return his place armies moves.
go attack/transfer -tRequest for the bot to return his attack and/or transfer moves
Output from botDescription
[-i -i -i -i -i -i]Six starting region ids to be returned after request.
[-b place_armies -i -i, ...]Place armies moves, returned after request. With bot name, region id and number of armies.
[-b attack/transfer -i -i -i, ...]Attack/transfer moves, returned after request. With bot name, source region, target region, number of armies.
No movesreturn this if you want the bot to do nothing at all

Note: If the output for the preferred starting regions is not correct, the engine will pick random ones. If a bot's output for a move is not correct, the engine will do nothing and skip the move.

Each "-i" you see in the lines above can be any positive integer and each "-b" represents the name of the bot (as far as the engine is concerned) and can be either player1 or player2. "-t" represents the time in milliseconds the bot has to respond to the engine, currently set to 2000, which is a pretty long amount of time. "-m" is a move and has a format as seen in the bot output table. Pay attention to the way the arguments are separated. This is mostly done by spaces, however "setup_map neighbors" and the bot's moves are comma separated.

By example

Below you find a simplified example of how communication goes between the engine and a bot.

At game start:

settings your_bot player1
settings opponent_bot player2
setup_map super_regions 1 2 2 5
setup_map regions 1 1 2 1 3 2 4 2 5 2
setup_map neighbors 1 2,3,4 2 3 4 5

A simple map has been set up, and the bot names have been given to the bot. In this case we have 2 super regions: the first one has a bonus value of 2, the second one a bonus value of 5. Also, there are 5 regions: the first two are part of super region 1, the last three are part of super region 2. Finally we can see that regions 1, 2 and 3 are all connected to each other. Region 4 is only connected to region 1 and 5. Both region 3's neighbours are given, so it's left out in the line, continuing with region 4.

pick_starting_regions 2000 1 7 12 13 18 15 24 25 29 37 42 41

Then the engine will ask for the bot to return his preferred starting regions. This is an example from a real game. Twelve regions are semi-randomly picked. The bot can return with this for example:

1 7 24 25 41 42

Now the game has been set up, the starting regions are distributed; the game rounds can start. The following is a simplified example of what the engine output will look like each round:

settings starting_armies 7
update_map 1 player1 2 2 player1 4 3 neutral 2 4 player2 5
go place_armies 2000
go attack/transfer 2000

The first line is pretty simple: the bot starts with 7 armies. That's 5 by default and 2 as a bonus because he completely owns super region 1 (continue reading to see why). In the second line we can see that player1 (our bot) has region 1 with 2 armies on it and region 2 with 4 armies on it, so super region 1 is fully owned by our bot. Region 3 is neutral and region 4 is owned by the opponent. Keep in mind that the game has fog of war! So our bot cannot see what is on region 5, because he doesn't own a neighbouring region of region 5. The opponent bot would get input like this, because he cannot see regions 2 and 3:

update_map 1 neutral 2 4 player2 5 5 neutral 2

Then the bot could respond to line 3 like this:

player1 place_armies 1 2, player1 place_armies 2 5

He will place 2 armies on region 1 and 5 armies on region 2. After the bot has responded to line 3, the engine will output line 4. Then our bot can respond like this:

player1 attack/transfer 1 2 3, player1 attack/transfer 2 3 8

First the bot will transfer 3 armies from region 1 to region 2. Both regions are owned by our bot, player1, so it's automatically a transfer. He moves the maximum amount, because 1 army must remain on region 1. Then the bot attacks the neutral region 3 with 8 armies. This is also the maximum amount, because transferred armies cannot be used in the same round.