A Game Server

A Game Server is a program that implements some game for other bots to play.

Code

The game servers are developed using any of the supported programming languages. The code is a single file, referencing no dependencies outside the language's standard library; it is subject to the exact same constraints as bot code. This constraint is likely to change in the future to support better developer experience.

Rules

All communication happens through standard input and output, with a text line-based interface. All lines have limited lenght (currently set to 1024).

The game server will receive vis none, vis standalone or vis inline as the first line, indicating the requested visualization mode. In the none mode, no visualization commands should be produced, in standalone mode, the previous replay (produced by the same program in the vis none mode should be parsed and the output should contain the replay combined with the visualization commands, and in inline mode, the output should have both the game communications and visualizer output. Note: currently, the only mode that is used is vis inline.

The game server will receive a param p1 p2 p3... line at the start with game-specific parameters (such as number of players). The param string template is configured in the database for each game, and is instantiated by the controller for each match. Template substitutions are applied to the line from game configuration: {num_player} is substituted by the number of players selected. If the game does not need parameters, it read the param line and ignore it.

If there are P players in the game, they are numbered from 1 to P. The game server does not know which players correspond to which bots, who their authors are or which languages they are written in. When commands like recv,playererror,send and playererror reference a player, this is the ingame player id 1<=p<=P.

When all players are ready, the game server will receive a start message from the Controller. Controller handles the ready messages that bots send, the game server doesn't need to, and can't.

After that the game server should run the game - communicate parameters to the bots, alternate turns, and handle messages from the bots

The game server will receive a recv p msg whenever a player p sends a message. The game server is responsible for dropping misbehaving players, including ones that send a message which it's not their turn.

Use send p msg or sendall msg for sending messages to players.

When the game is over, game server should produce a line with over score1 score2 score3...msg with the list of floating-point scores that each player has at the end of the game, and an arbitrary message with a reason of why the game was over.

During the game, the game server may utilize the timer id Xms command, where id is a unique positive number, and X is the number of milliseconds to set the timer for. After X millisecods elapse, the game server will receive a timeout id message. Note that there is no way to cancel a timer, and the timeout message must be handled correctly even if the timer expires way later than the players move. One way to do it is to ignore all the old timout messages, and only handle the currently active timer id. There could be arbitrarily many timers ticking at the same time.

Visualizer

Some lines that the Game Server produces might start with vis. After that a JSON (/Hjson) object follows that defines an event. Each of them must have a t field which is the time (in seconds) when the event happens. The events must come in order, i.e. the value of t must never decrease from one vis line to the next.

All coordinates are in the unit square [0..1]x[0..1], top left corner being (0,0).

Object IDs are chosen by the visualizer and must be unique, and must not be reused if deleted.

Examples

A transparent red square, outlined with a black border (the default) of width 0.006:
vis {"t":0,"create":{"id":123321,"z":3,"geom":[{"poly":{"f":"77000077","t":0.006,"vs":[[0.1, 0.1],[0.1,0.9],[0.9,0.9],[0.9,0.1]]}}]}}

A green circle with a black border of width 0.003 that will appear 1.5 seconds after the match start.
vis {"t":1.5,"create":{"id":33,"z":2,"p":[0.77,0.83],"geom":[{"circle":{"r":0.024,"f":"33cc33ff","t":0.003}}]}}

Moving the circle defined above, over the cource of 0.3 seconds, about 0.06 downward, starting at 2.3 seconds.
vis {"t":2.3,"transform":{"id":33,"d":0.3,"mv":[0,0.060000002]}}

Hjson

The visualizer also accepts Hjson, which elides quotes for fields names, making it easier to generate and read, and more compact. The examples above become:
vis {t:0,create:{id:123321,z:3,geom:[{poly:{f:"77000077",t:0.006,vs:[[0.1, 0.1],[0.1,0.9],[0.9,0.9],[0.9,0.1]]}}]}} vis {t:1.5,create:{id:33,z:2,p:[0.77,0.83],geom:[{circle:{r:0.024,f:"33cc33ff",t:0.003}}]}} vis {t:2.3,transform:{id:33,d:0.3,mv:[0,0.060000002]}}

Full Spec

See visualize.rs which contains the source code, and makes it clear what the visualizer accepts.