The control file

Sample control file

Here is a sample control file, illustrating most of the available settings for a playoff:

competition_type = 'playoff'

description = """
This is a sample control file.

It illustrates most of the available settings for a playoff.

record_games = True
stderr_to_log = False

players = {
    # GNU Go level 1
    'gnugo-l1' : Player("gnugo --mode=gtp --chinese-rules "
                        "--capture-all-dead --level=1"),

    # GNU Go level 2
    'gnugo-l2' : Player("gnugo --mode=gtp --chinese-rules "
                        "--capture-all-dead --level=2"),

    # Fuego at 5000 playouts per move
    'fuego-5k' : Player("fuego --quiet",
                            "go_param timelimit 999999",
                            "uct_max_memory 350000000",
                            "uct_param_search number_threads 1",
                            "uct_param_player reuse_subtree 0",
                            "uct_param_player ponder 0",
                            "uct_param_player max_games 5000",

board_size = 9
komi = 6

matchups = [
    Matchup('gnugo-l1', 'fuego-5k', board_size=13,
            handicap=2, handicap_style='free', komi=0,
            scorer='players', number_of_games=5),

    Matchup('gnugo-l2', 'fuego-5k', alternating=True,

    Matchup('gnugo-l1', 'gnugo-l2',

File format

The control file is a plain text configuration file.

It is interpreted in the same way as a Python source file. See the Sample control file above for an example of the syntax.

The control file is made up of a series of top-level settings, in the form of assignment statements: setting_name = value.

Each top-level setting should begin on a new line, in the leftmost column of the file. Settings which use brackets of any kind can be split over multiple lines between elements (for example, lists can be split at the commas).

Comments are introduced by the # character, and continue until the end of the line.

See Data types below for the representation of values. See the Python language reference for a formal specification.

The settings for use in playoffs are listed below. Note that competition_type must come first.


while the ringmaster will give error messages for unacceptable setting values, it will ignore attempts to set a nonexistent setting (this is because you’re allowed to define variables of your own in the control file and use them in later setting definitions).

If you wish, you can use arbitrary Python expressions in the control file; see Control file techniques below.


all Python code in the control file will be executed; a hostile party with write access to a control file can cause the ringmaster to execute arbitrary code. On a shared system, do not make the competition directory or the control file world-writeable.

Data types

The following data types are used for values of settings:


A literal string of characters in single or double quotes, eg 'gnugo-l1' or "free".

Strings containing non-ASCII characters should be encoded as UTF-8 (Python unicode objects are also accepted).

Strings can be broken over multiple lines by writing adjacent literals separated only by whitespace; see the Player definitions in the example above.

Backslash escapes can be used in strings, such as \n for a newline. Alternatively, three (single or double) quotes can be used for a multi-line string; see description in the example above.

A (short) string made up of any combination of ASCII letters, numerals, and the punctuation characters - ! $ % & * + - . : ; < = > ? ^ _ ~.
A truth value, written as True or False.
A whole number, written as a decimal literal, eg 19 or -1.
A floating-point number, written as a decimal literal, eg 6 or 6.0 or 6.5.
A sequence of values of uniform type, written with square brackets separated by commas, eg ["max_playouts 3000", "initial_wins 5"]. An extra comma after the last item is harmless.
An explicit map of keys of uniform type to values of uniform type, written with curly brackets, colons, and commas, eg {'p1' : True, 'p2' : False}. An extra comma after the last item is harmless.

File and directory names

When values in the control file are file or directory names, non-absolute names are interpreted relative to the competition directory.

If a file or directory name begins with ~, home directory expansion is applied (see os.path.expanduser()).

Playoff settings

The following settings can be set at the top level of the control file, for competitions of type playoff.

For the differences in tuning events, See The Monte Carlo tuner and The cross-entropy tuner.

The only required settings are competition_type, players, and matchups.


String: "playoff", "mc_tuner", or "ce_tuner"

Determines whether the competition is a playoff or a specific kind of tuning event. This must be set on the first line in the control file (not counting blank lines and comments).


String (default None)

A text description of the competition. This will be included in the competition report file. Leading and trailing whitespace is ignored.


Boolean (default True)

Write SGF game records.


Boolean (default True)

Redirect all players’ standard error streams to the event log. See Players’ standard error.


Dictionary mapping identifiers to Player definitions (see Player configuration).

Describes the GTP engines that can be used in the competition. If you wish to use the same program with different settings, each combination of settings must be given its own Player definition. See Control file techniques below for a compact way to define several similar Players.

The dictionary keys are the player codes; they are used to identify the players in Matchup definitions, and also appear in reports and the SGF game records.

It’s fine to have player definitions here which aren’t used in any matchups. These definitions will be ignored, and no corresponding engines will be run.


List of Matchup definitions (see Matchup configuration).

This defines which engines will play against each other, and the game settings they will use.

In addition to these, all matchup settings (except id and name) can be set at the top of the control file. These settings will be used for any matchups which don’t explicitly override them.

Player configuration

A Player definition has the same syntax as a Python function call: Player(arguments). Apart from command, the arguments should be specified using keyword form (see Sample control file).

All arguments other than command are optional.


For results to be meaningful, you should normally configure players to use a fixed amount of computing power, paying no attention to the amount of real time that passes.

The arguments are:


String or list of strings

This is the only required Player arguments. It can be specified either as the first argument, or using a keyword command="...". It specifies the executable which will provide the player, and its command line arguments.

The player subprocess is executed directly, not run via a shell.

The command can be either a string or a list of strings. If it is a string, it is split using rules similar to a Unix shell’s (see shlex.split()).

In either case, the first element is taken as the executable name and the remainder as its arguments.

If the executable name does not contain a /, it is searched for on the the PATH. Otherwise it is handled as described in file and directory names.


Player("~/src/fuego-svn/fuegomain/fuego --quiet")

String (default None)

The working directory for the player.

If this is left unset, the player’s working directory will be the working directory from when the ringmaster was launched (which may not be the competition directory). Use cwd="." to specify the competition directory.


If an engine writes debugging information to its working directory, use cwd to get it out of the way:

Player('mogo', cwd='~/tmp')

Dictionary mapping strings to strings (default None)

This specifies environment variables to be set in the player process, in addition to (or overriding) those inherited from its parent.

Note that there is no special handling in this case for values which happen to be file or directory names.


Player('goplayer', environ={'GOPLAYER-DEBUG' : 'true'})

Boolean (default False)

Redirect the player’s standard error stream to /dev/null. See Players’ standard error.


Player('mogo', discard_stderr=True)

List of strings, or list of lists of strings (default None)

GTP commands to send at the beginning of each game. See Playing games.

Each command can be specified either as a single string or as a list of strings (with each argument in a single string). For example, the following are equivalent:

Player('fuego', startup_gtp_commands=[
                    "uct_param_player ponder 0",
                    "uct_param_player max_games 5000"])

Player('fuego', startup_gtp_commands=[
                    ["uct_param_player", "ponder", "0"],
                    ["uct_param_player", "max_games", "5000"]])

Dictionary mapping strings to strings (default None)

This is a map of GTP command names to command names, eg:

Player('fuego', gtp_aliases={'gomill-cpu_time' : 'cputime'})

When the ringmaster would normally send gomill-cpu_time, it will send cputime instead.

The command names are case-sensitive. There is no mechanism for altering arguments.


Boolean (default True)

If the scorer setting is players, the ringmaster normally asks each player that implements the final_score GTP command to report the game result. Setting is_reliable_scorer to False for a player causes that player never to be asked.


Boolean (default False)

Permits the player to claim a win (using the GTP extension gomill-genmove_ex). See Claiming wins.

Matchup configuration

A Matchup definition has the same syntax as a Python function call: Matchup(arguments).

The first two arguments should be the player codes for the two players involved in the matchup. The remaining arguments should be specified in keyword form. For example:

Matchup('gnugo-l1', 'fuego-5k', board_size=13, komi=6)

Defaults for matchup settings (other than id and name) can be specified at the top level of the control file.

The board_size and komi arguments must be given for all matchups (either explicitly or as defaults); the rest are all optional.


a default komi or alternating setting will be applied even to handicap games.

The arguments are:



A short string (usually one to three characters) which is used to identify the matchup. Matchup ids appear in the game ids (and so in the SGF filenames), and are used in the result-retrieval API.

If this is left unspecified, the matchup id will be the index of the matchup in the matchups list (formatted as a decimal string, starting from "0").



A string used to describe the matchup in reports. By default, this has the form player code vs player code; you may wish to change it if you have more than one matchup between the same pair of players (perhaps with different komi or handicap).



The size of Go board to use for the games (eg 19 for a 19x19 game). The ringmaster is willing to use board sizes from 2 to 25.



The komi to use for the games. You can specify any floating-point value, and it will be passed on to the GTP engines unchanged, but normally only integer or half-integer values will be useful. Negative values are allowed.


Boolean (default False)

If this is True, the players will swap colours in successive games. Otherwise, the first-named player always takes Black.


Integer (default None)

Number of handicap stones to give Black at the start of the game. See also handicap_style.

See the GTP specification for the rules about what handicap values are permitted for different board sizes (in particular, values less than 2 are never allowed).


String: "fixed" or "free" (default "fixed")

Determines whether the handicap stones are placed on prespecified points, or chosen by the Black player. See the GTP specification for more details.

This is ignored if handicap is unset.


Integer (default 1000)

Maximum number of moves to allow in a game. If this limit is reached, the game is stopped; see Playing games.


String: "players" or "internal" (default "players")

Determines whether the game result is determined by the engines, or by the ringmaster. See Scoring and is_reliable_scorer.


Integer (default None)

The total number of games to play in the matchup. If you leave this unset, there will be no limit; see Stopping competitions.

Changing number_of_games to 0 provides a way to effectively disable a matchup in future runs, without forgetting its results.

Changing the control file between runs

Changing the control file between runs of the same competition (or after the final run) is allowed. For example, it’s fine to increase a completed matchup’s number_of_games and set the competition off again.

The intention is that nothing surprising should happen if you change the control file; of course if you change settings which affect player behaviour then result summaries might not be meaningful.

In particular:

  • if you change a Player definition, the new definition will be used when describing the player in reports; there’ll be no record of the earlier definition, or which games were played under it.
  • if you change a Matchup definition, the new definition will be used when describing the matchup in reports; there’ll be no record of the earlier definition, or which games were played under it.
  • if you change a Matchup definition to have different players (ie, player codes), the ringmaster will refuse to run the competition.
  • if you delete a Matchup definition, results from that matchup won’t be displayed during future runs, but will be included (with some missing information) in the report and show output.

If you add a Matchup definition, put it at the end of the list (or else explicitly specify the matchup ids).

In practice, you shouldn’t delete Matchup definitions (if you don’t want any more games to be played, set number_of_games to 0).

If you change descriptive text, you can use the report command line action to remake the report file.

Control file techniques

As the control file is just Python code, it’s possible to use less direct methods to specify the values of settings.

One convenient way to define a number of similar players is to define a function which returns a Player object. For example, the player definitions in the sample control file could be rewritten as follows:

def gnugo(level):
    return Player("gnugo --mode=gtp --chinese-rules "
                  "--capture-all-dead --level=%d" % level)

def fuego(playouts_per_move, additional_commands=[]):
    commands = [
        "go_param timelimit 999999",
        "uct_max_memory 350000000",
        "uct_param_search number_threads 1",
        "uct_param_player reuse_subtree 0",
        "uct_param_player ponder 0",
        "uct_param_player max_games %d" % playouts_per_move,
    return Player(
        "fuego --quiet",

players = {
    'gnugo-l1' : gnugo(level=1),
    'gnugo-l2' : gnugo(level=2),
    'fuego-5k' : fuego(playouts_per_move=5000)

If you assign to a setting more than once, the final value is the one that counts. Settings specified above as having default None can be assigned the value None, which will be equivalent to leaving them unset.

Importing parts of the Python standard library (or other Python libraries that you have installed) is allowed.