Get help

Be sure to join the #vindinium IRC chan on Freenode if you have any questions or if you want to geek around a little bit. Here is a direct link for people who don't have an IRC client.

There is also a vindinium subreddit.

Create a bot

First, you will need to register your AI (Artificial Intelligence) on the server using the "Create a bot" page. You just have to enter a name and we will give you a secret key. Be sure to write it down as there is no way to recover it later. This key will be used to uniquely identify your bot with the name you chose.

Once you have your key, you can already try one of the starter packs in training mode if you want. More on modes in the API section.

Starter packs

Starter packs implement a bot that is moving in a random direction at each turn. They take care of the HTTP and JSON parsing, so you can focus on game logic. Here are the available packs in alphabetical order:


C# https://github.com/ozten/vindinium-starter-csharp

C++ https://github.com/joelthelion/vindinium-cpp-sdk

Clojure https://github.com/ornicar/vindinium-starter-clojure

Common Lisp https://github.com/wizzomafizzo/vindinium-starter-cl

D https://github.com/dymk/vindinium-starter-d

Elixir https://github.com/nesQuick/vindinium-elixir-starter

Erlang https://github.com/jbcrail/vindinium-starter-erlang

F# https://github.com/Rickasaurus/FSVindinium

Go https://github.com/geetarista/vindinium-starter-go

Hack https://github.com/mcrumm/vindinium-hacklang

Haskell https://github.com/Herzult/vindinium-starter-haskell

Idris https://github.com/srenault/vindinium-starter-idris

Io https://github.com/pauldub/vindinium-starter-io

Java https://github.com/bstempi/vindinium-client

Julia https://github.com/Wieke/Vindinium-Julia-Client

Kotlin https://github.com/SoulBeaver/kindinium

Lua https://github.com/mtdowling/vindinlua

NodeJS https://github.com/stephank/vindinium-client

OCaml http://tx97.net/vindinium-starter-ocaml

PHP https://github.com/kcampion/vindinium-starter-php

Perl https://github.com/cyclotron3k/vindinium-starter-perl

Prolog https://github.com/borisvassilev/vindinium-swi

Python https://github.com/doug-letough/vindinium-curses_ui

Racket https://bitbucket.org/AlRokerInABeeCostume/vinidinium-ai-challenge-hero-bot-in-racket

Ruby https://github.com/poeks/vindinium-starter-ruby

Rust https://github.com/jxv/vindinium-starter-rust

Scala http://github.com/ornicar/vindinium-starter-scala

VB.Net https://code.google.com/p/vindinium-starter-visualbasic-master


If your language of choice does not have a starter pack yet, you will have to make it yourself. It's quite easy really; have a look at the docs below and/or take example from an existing starter.

Game architecture

             +------------+                             +-----------------+
             |            |  1)HTTP Request             |                 |
             |            | (initial state, move order) |                 |
             |   Client   +---------------------------->|                 |
             |            |                             |                 |
             | scala,     |                             |    Game server  |
             | python,    |  2)Json Response            |                 |
             | java,      |(new game state)             |                 |
             | …          |<----------------------------+                 |
             |            |                             |                 |
             |            |                             |                 |
             +------------+                             +-----------------+

As you may already have noticed with the above diagram, your bot will basically be a HTTP client. You send a HTTP request (to have the initial game state or to move your bot) and then you got a HTTP Response encoded in Json.

Ok fine, let's see what those requests look like.

API

The requests you will have to send to the server will depend on the mode you are using. You can either train your bot by using the "training mode" or play for real using the "arena mode". Each mode is using a different URL for the requests.

Game modes

Training

In training mode, you can play against some dummy bots, you can specify the number of turns you want to play and, if you want, you can provide a specific map to test your algorithms. The games played in Training mode are not scored, so feel free to use it as much as you want.

In training mode, the url you will need to use is:

http://vindinium.org/api/training

Here are the steps you need to follow to play in training mode

  1. Send a POST HTTP request to the http://vindinium.org/api/training URL to get the initial game state. Here are the parameters you can pass in the POST body:
    key (required)
    The secret key you wrote down after registering at the register page
    turns
    The number of turns you want to play. If you don't specify this parameter, 300 turns will be played.
    map
    The map id corresponding to the map you want to use. Possible values are: m1, m2, m3, m4, m5, m6. You can have a look at the maps here. If you don't specify this parameter, a random map will be generated for you.
  2. Parse the JSON you've received as a response of the first step. See Json documentation for more details.
  3. Send your move to the URL extracted from the Json (see Json urls for more details) using a POST request. Here are the parameters you need to send in the POST body:
    key (required)
    The secret key you wrote down after registering at the register page
    dir (required)
    Can be one of: 'Stay', 'North', 'South', 'East', 'West'
  4. Parse the JSON received in the same way you did in the second step. Repeat until the game is finished. See the Json documentation to know when a game is finished.

Arena

In arena mode, you will play against other players. Your games will be rated and your rank will be updated accordingly.

In arena mode, the url you will need to use is:

http://vindinium.org/api/arena

Here are the steps you need to follow to play in arena mode:

  1. Send a POST HTTP request to the http://vindinium.org/api/arena URL to get the initial game state. There is only one required parameter to this first call:
    key (required)
    The secret key you wrote down after registering at the register page
  2. Parse the JSON you've received as a response of the first step. See Json documentation for more details.
  3. Send your move to the URL extracted from the Json (see Json urls for more details) using a POST request. Here are the parameters you need to send in the POST body:
    key (required)
    The secret key you wrote down after registering at the register page
    dir (required)
    Can be one of: 'Stay', 'North', 'South', 'East', 'West'
  4. Parse the JSON received in the same way you did in the second step. Repeat until the game is finished. See the Json documentation to know when a game is finished.

HTTP response codes

When you issue a call to the server, it will respond using normal HTTP codes:

  • 200: Everything went well, good job!
  • 4xx (400, 404, …): You did something wrong (wrong secret key, trying to play when the game is already finished, too slow to send the move, …). Be sure to check the response body to know what the exact error is.
  • 500: Something went wrong on the server side. How could it be possible? ;)

Timeout

You have a maximum of 1 second to play a move. If you exceed this limit, your bot is marked as "crashed". The game is over for you, you can't issue any move anymore. You should be aware that you can still be the winner of the game if nobody is able to earn more gold than the gold you had when your bot crashed.

Json Documentation

Below is a full sample of the Json that the server will send to your client. Each object is described in details later in the documentation.

{
   "game":{
      "id":"s2xh3aig",
      "turn":1100,
      "maxTurns":1200,
      "heroes":[
         {
            "id":1,
            "name":"vjousse",
            "userId":"j07ws669",
            "elo":1200,
            "pos":{
               "x":5,
               "y":6
            },
            "life":60,
            "gold":0,
            "mineCount":0,
            "spawnPos":{
               "x":5,
               "y":6
            },
            "crashed":true
         },
         {
            "id":2,
            "name":"vjousse",
            "userId":"j07ws669",
            "elo":1200,
            "pos":{
               "x":12,
               "y":6
            },
            "life":100,
            "gold":0,
            "mineCount":0,
            "spawnPos":{
               "x":12,
               "y":6
            },
            "crashed":true
         },
         {
            "id":3,
            "name":"vjousse",
            "userId":"j07ws669",
            "elo":1200,
            "pos":{
               "x":12,
               "y":11
            },
            "life":80,
            "gold":0,
            "mineCount":0,
            "spawnPos":{
               "x":12,
               "y":11
            },
            "crashed":true
         },
         {
            "id":4,
            "name":"vjousse",
            "userId":"j07ws669",
            "elo":1200,
            "pos":{
               "x":4,
               "y":8
            },
            "lastDir": "South",
            "life":38,
            "gold":1078,
            "mineCount":6,
            "spawnPos":{
               "x":5,
               "y":11
            },
            "crashed":false
         }
      ],
      "board":{
         "size":18,
         "tiles":"##############        ############################        ##############################    ##############################$4    $4############################  @4    ########################  @1##    ##    ####################  []        []  ##################        ####        ####################  $4####$4  ########################  $4####$4  ####################        ####        ##################  []        []  ####################  @2##    ##@3  ########################        ############################$-    $-##############################    ##############################        ############################        ##############"
      },
      "finished":true
   },
   "hero":{
      "id":4,
      "name":"vjousse",
      "userId":"j07ws669",
      "elo":1200,
      "pos":{
         "x":4,
         "y":8
      },
      "lastDir": "South",
      "life":38,
      "gold":1078,
      "mineCount":6,
      "spawnPos":{
         "x":5,
         "y":11
      },
      "crashed":false
   },
   "token":"lte0",
   "viewUrl":"http://localhost:9000/s2xh3aig",
   "playUrl":"http://localhost:9000/api/s2xh3aig/lte0/play"
}

Game object

   "game":{
      "id":"s2xh3aig",
      "turn":1100,
      "maxTurns":1200,
      "heroes":[...],
      "board":{
         "size":18,
         "tiles":"##############        ############################        ##############################    ##############################$4    $4############################  @4    ########################  @1##    ##    ####################  []        []  ##################        ####        ####################  $4####$4  ########################  $4####$4  ####################        ####        ##################  []        []  ####################  @2##    ##@3  ########################        ############################$-    $-##############################    ##############################        ############################        ##############"
      },
      "finished":true
      }
id
Unique identifier of the game
turn
Current number of moves since the beginning. This is the total number of moves done at this point. Each turn contains 4 move (one for each player). So if you want to know the "real" turn number, you need to divide this number by 4.
maxTurns
Maximum number of turns. Same as above, you may need to divide this number by 4.
heroes
An array of Hero objects.
board
A Json object with two values. size is the size of the map: the number of horizontal/vertical tiles. As the map is always a square, this number is the same for X and Y. tiles is a string representing the map. Each tile is coded using two chars (see the rules legend for more information). As you may already have noticed, to get each line of the map, you just have to use a %size (modulo) on the tiles.
finished
If the game is finished or not.

Hero object

         {
            "id":1,
            "name":"vjousse",
            "userId":"j07ws669",
            "elo":1200,
            "pos":{
               "x":5,
               "y":6
            },
            "lastDir": "South",
            "life":60,
            "gold":0,
            "mineCount":0,
            "spawnPos":{
               "x":5,
               "y":6
            },
            "crashed":true
         }

Nothing special here, pos represents your initial position on the map. spawnPos represents the position where you will respawn when you die. For now, it's the same position. elo is the current rating of the player (the higher the better). lastDir is the last order this hero issued (if any).

Urls

   "viewUrl":"http://localhost:9000/s2xh3aig",
   "playUrl":"http://localhost:9000/api/s2xh3aig/lte0/play"
viewUrl
An URL that you can open in your browser to view a replay of the game.
playUrl
The URL you need to use to send your move orders to the server.