Match Schema
What is it?
A match configuration file contains everything that Get5 and your server needs to host a series. This includes locking players to their correct team and side, setting the map(s) and configuring the game rules.
Two files ship with Get5 that give a general idea of what can be included in a match config. A Valve KeyValue
format can be found here, and a JSON
format can be found here. In this
documentation, we'll go through what each value means, but do note that only the values team1
, team2
and
maplist
are required to start a match. We recommend using the JSON format whenever possible, as JSON has way
better support in various programming languages than Valve's KeyValue format (which essentially has none).
The schema
type SteamID = string // (8)
type Get5PlayerSet = { [key: SteamID]: string } | SteamID[] // (9)
interface Get5MatchTeam {
"id": string | undefined // (38)
"players": Get5PlayerSet // (24)
"coaches": Get5PlayerSet | undefined // (23)
"name": string | undefined // (16)
"tag": string | undefined // (17)
"flag": string | undefined // (18)
"logo": string | undefined // (19)
"series_score": number | undefined // (26)
"matchtext": string | undefined // (27)
"fromfile": string | undefined // (28)
}
interface Get5MapListFromFile {
"fromfile": string // (35)
}
interface Get5Match {
"match_title": string | undefined // (25)
"matchid": string | undefined // (1)
"clinch_series": boolean | undefined // (32)
"num_maps": number | undefined // (2)
"scrim": boolean | undefined // (39)
"wingman": boolean | undefined // (37)
"players_per_team": number | undefined // (3)
"coaches_per_team": number | undefined // (4)
"coaches_must_ready": boolean | undefined // (33)
"min_players_to_ready": number | undefined // (5)
"min_spectators_to_ready": number | undefined // (6)
"skip_veto": boolean | undefined // (7)
"veto_first": "team1" | "team2" | "random" | undefined // (11)
"veto_mode": ['team1_ban' | 'team2_ban'
| 'team1_pick' | 'team2_pick'] | undefined // (36)
"side_type": "standard" | "always_knife"
| "never_knife" | "random" | undefined // (12)
"map_sides": ["team1_ct" | "team1_t" | "knife"] | undefined // (31)
"spectators": { // (10)
"name": string | undefined // (29)
"players": Get5PlayerSet | undefined // (30)
"fromfile": string | undefined // (34)
} | undefined
"maplist": string[] | Get5MapListFromFile // (13)
"favored_percentage_team1": number | undefined // (14)
"favored_percentage_text": string | undefined // (15)
"team1": Get5MatchTeam // (20)
"team2": Get5MatchTeam | undefined // (21)
"cvars": { [key: string]: string | number } | undefined // (22)
}
- Optional
The ID of the match. This determines thematchid
parameter in all forwards and events. If you use the MySQL extension, you should leave this field blank (or omit it), as match IDs will be assigned automatically. If you do want to assign match IDs from another source, they must be integers (in a string) and must increment between matches.Default: ""
- Optional
The number of maps to play in the series.Default: 1
- Optional
The number of players per team. You should never set this to a value higher than the number of players you want to actually play in a game, excluding coaches.Default: 5 (2 in wingman)
- Optional
The maximum number of coaches per team.Default: 2
- Optional
The minimum number of players that must be present on a team for the!forceready
command to succeed. This should not be larger thanplayers_per_team
. If not forcing a team ready, all players must!ready
up themselves.Default: 0
- Optional
The minimum number of spectators that must be!ready
for the game to begin.Default: 0
- Optional
Whether to skip the map selection phase. Iftrue
,num_maps
are simply played in the order they appear inmaplist
, and no map selection is performed by players in-game.Default: false
- A player's Steam ID. This can be in any format, but we recommend a string representation of SteamID
64, i.e.
"76561197987713664"
. - Players are represented each with a mapping of
SteamID -> PlayerName
as a key-value dictionary. The name is optional and should be set to an empty string to let players decide their own name. You can also provide a simple string array ofSteamID
to disable name-locking.
I.e.:["76561197996426755", "76561356896422767"]
and{"76561197996426755": "PlayerName", "76561356896422767": "PlayerName"}
are both valid values. - Optional
The spectators to allow into the game. If not defined, spectators cannot join the game.Default: undefined
- Optional
The team that makes the first map selection choice. This parameter is ignored if you provide a custom veto flow viaveto_mode
.Default: "team1"
- Optional
The method used to determine sides during map selection.standard
means that the team that doesn't pick a map gets the side choice (only ifskip_veto
isfalse
).always_knife
means that sides are always determined by a knife-round.never_knife
means thatteam1
always starts on CT.random
means that teams are randomly assigned a side.
This parameter is ignored ifmap_sides
has already set the sides for a map.standard
andalways_knife
behave similarly (knife) whenskip_veto
istrue
.Default: "standard"
- Required
The map pool to pick from, as an array of strings (["de_dust2", "de_nuke"]
etc.), or ifskip_veto
istrue
, the order of maps played (limited bynum_maps
).
You can load maps from workshop collections by using the syntax"workshop/map_id/map_name"
, i.e."workshop/1193875520/de_aztec"
. The name parameter is used to present the map in the map selection phase. If you provide maps from the community workshop, you must have a Steam Web API key configured for your server, or the match config will fail to load.
Similarly to teams, you can set this to an object with afromfile
property to load a map list from a separate file.
If you use workshop maps, it is recommended that you setmp_match_end_restart 1
on your server, so a new map does not load in case it takes a long time to download a workshop map. You can also setsv_broadcast_ugc_downloads 1
andsv_broadcast_ugc_download_progress_interval 1
if you want to inform players that a workshop map is being downloaded. In the vast majority of cases, this process should only take a few seconds. - Optional
Wrapper for the server'smp_teamprediction_pct
. This determines the chances ofteam1
winning.Default: 0
- Optional
Wrapper for the server'smp_teamprediction_txt
.Default: ""
- Optional
The team's name. Setsmp_teamname_1
ormp_teamname_2
. Printed frequently in chat. If you don't define a team name, it will be set toteam_
followed by the name of the captain, i.e.team_s1mple
.Default: ""
- Optional
A short version of the team name, used in clan tags in-game (requires thatget5_set_client_clan_tags
is disabled).Default: ""
- Optional
The ISO-code to use for the in-game flag of the team. Must be a supported country, i.e.FR
,UK
,SE
etc.Default: ""
- Optional
The team logo (wrapsmp_teamlogo_1
ormp_teamlogo_2
), which requires to be on a FastDL in order for clients to see.Default: ""
- Required
The data for the first team. - Optional
The data for the second team. Not required ifscrim
istrue
. - Optional
Various commands to execute on the server when loading the match configuration. This can be both regular server-commands and anyGet5 configuration parameter
, i.e.{"mp_friendlyfire": "0", "get5_max_pauses": "2"}
.
When the match ends, these parameters will by default be reset to the value they had before the match was loaded.
You should avoid putting server-specific parameters, such asget5_server_id
, in this property, as these are all written to backups and set when restored from.
These commands are always executed after the phase configuration files, so you can also use this to override a specific parameter - such as friendly fire.Default: undefined
- Optional
Similarly toplayers
, this object maps coaches using their Steam ID and name, locking them to the coach slot unless removed usingget5_removeplayer
. Setting a Steam ID as coach takes precedence over being set as a player.
Note that ifsv_coaching_enabled
is disabled, anyone defined as a coach will be considered a regular player for the team instead.
Also note thatcoaches
is ignored ifscrim
istrue
, in which case you should put everyone inplayers
and have them use the!coach
command instead.Default: undefined
- Required
The players on the team. - Optional
Sets the server'smp_teammatchstat_txt
ConVar, but lets you use{MAPNUMBER}
and{MAXMAPS}
as variables that get replaced with their integer values. You should not setmp_teammatchstat_txt
yourself, as it will be overridden by this parameter.Default: "Map {MAPNUMBER} of {MAXMAPS}"
- Optional
The current score in the series, this can be used to give a team a map advantage or used as a manual backup method.Default: 0
- Optional
Assigns values tomp_teammatchstat_1
andmp_teammatchstat_2
, respectively. If you don't set this value in a BoX series, it is set to each team's map series score automatically.Default: ""
- Optional
Match teams can also be loaded from a separate file, allowing you to easily re-use a match configuration for different sets of teams. Afromfile
value could be"addons/sourcemod/configs/get5/team_nip.json"
, and is always relative to thecsgo
directory. The file should contain a validGet5MatchTeam
object. You are allowed to mix filetypes, so a JSON file can point to afromfile
that's a KeyValue file and vice-versa. If you provide afromfile
property, all other properties are ignored and team data is only read from the provided file. - Optional
The name of the spectator team.Default: "casters"
- Optional
The spectator/caster Steam IDs and names. Setting a Steam ID as spectator takes precedence over being set as a player or coach. - Optional
Determines the starting sides for each map. If this array is shorter thannum_maps
,side_type
will determine the side-behavior of the remaining maps.Default: undefined
- Optional
Iffalse
, the entire map list will be played, regardless of score. Iftrue
, a series will be won when the series score for a team exceeds the number of maps divided by two.Default: true
- Optional
Determines if coaches must also!ready
.Default: false
- Optional
Similarly to teams and map list, spectators may also be loaded from another file. - Required
Similarly to teams and spectators, a map list may also be loaded from another file. - Optional
Allows for a custom configuration of map picks/bans. This must be an array of strings consisting of any valid combination ofteam1_ban
,team2_ban
,team1_pick
andteam2_pick
. - Optional
Whether to configure the match for Wingman mode. If this is enabled,players_per_team
defaults to2
instead of5
.Default: false
- Optional
The ID of the team. This can be used to link the team to an external resource, such as a database ID. The ID is included in the event system for events that include a team. - Optional
Configures the match for scrim mode. In this configuration,team2
is ignored and not required, andcoaches
cannot be set forteam1
.Default: false
Team assignment priority
If you define a Steam ID in more than one location in your match configuration, it will be evaluated in this order to determine where to put the player:
- Spectator
- Coach for
team1
- Coach for
team2
- Player for
team1
- Player for
team2
If a player's Steam ID was not found in any of these locations, they will be removed from the server unless you are in scrim mode.
Examples
These examples are identical in the way they would work if loaded.
Example only
map_sides
would only work with skip_veto: true
.
{
"match_title": "Astralis vs. NaVi",
"matchid": "3123",
"clinch_series": true,
"num_maps": 3,
"wingman": false,
"players_per_team": 5,
"coaches_per_team": 2,
"coaches_must_ready": true,
"min_players_to_ready": 2,
"min_spectators_to_ready": 0,
"skip_veto": false,
"veto_first": "team1",
"side_type": "standard",
"spectators": {
"name": "Blast PRO 2021",
"players": {
"76561197987511774": "Anders Blume"
}
},
"maplist": [
"de_dust2",
"de_nuke",
"workshop/1193875520/de_aztec",
"de_inferno",
"de_mirage",
"de_vertigo",
"de_ancient",
"de_overpass"
],
"map_sides": [
"team1_ct",
"team2_ct",
"knife"
],
"team1": {
"fromfile": "addons/sourcemod/get5/team_navi.json"
},
"team2": {
"id": "3752",
"name": "Astralis",
"tag": "Astralis",
"flag": "DK",
"logo": "astr",
"matchtext": "Defending Champions",
"players": {
"76561197990682262": "Xyp9x",
"76561198010511021": "gla1ve",
"76561197979669175": "K0nfig",
"76561198028458803": "BlameF",
"76561198024248129": "farlig"
},
"coaches": {
"76561197987144812": "Trace"
}
},
"cvars": {
"hostname": "Get5 Match #3123",
"mp_friendlyfire": "0",
"get5_stop_command_enabled": "0",
"sm_practicemode_can_be_started": "0"
}
}
fromfile
example:
{
"id": "1348",
"name": "Natus Vincere",
"tag": "NaVi",
"flag": "UA",
"logo": "navi",
"players": {
"76561198034202275": "s1mple",
"76561198044045107": "electronic",
"76561198246607476": "b1t",
"76561198121220486": "Perfecto",
"76561198040577200": "sdy"
},
"coaches": {
"76561198013523865": "B1ad3"
}
}
And in TypeScript, using the above interface definition file:
const match_schema: Get5Match = {
"match_title": "Astralis vs. NaVi",
"matchid": "3123",
"clinch_series": true,
"num_maps": 3,
"wingman": false,
"players_per_team": 5,
"coaches_per_team": 2,
"coaches_must_ready": true,
"min_players_to_ready": 2,
"min_spectators_to_ready": 0,
"skip_veto": false,
"veto_first": "team1",
"side_type": "standard",
"spectators": {
"name": "Blast PRO 2021",
"players": {
"76561197987511774": "Anders Blume"
}
},
"maplist": [
"de_dust2",
"de_nuke",
"workshop/1193875520/de_aztec",
"de_inferno",
"de_mirage",
"de_vertigo",
"de_ancient",
"de_overpass"
],
"map_sides": ["team1_ct", "team2_ct", "knife"], // Example; would only work with "skip_veto": true
"team1": {
"fromfile": "addons/sourcemod/get5/team_navi.json"
},
"team2": {
"id": "3752",
"name": "Astralis",
"tag": "Astralis",
"flag": "DK",
"logo": "astr",
"matchtext": "Defending Champions",
"players": {
"76561197990682262": "Xyp9x",
"76561198010511021": "gla1ve",
"76561197979669175": "K0nfig",
"76561198028458803": "BlameF",
"76561198024248129": "farlig"
},
"coaches": {
"76561197987144812": "Trace"
}
},
"cvars": {
"hostname": "Get5 Match #3123",
"mp_friendlyfire": "0",
"get5_stop_command_enabled": "0",
"sm_practicemode_can_be_started": "0"
}
}
// And the config file could be placed on the server like this:
const json = JSON.stringify(match_schema);
fs.writeFileSync('addons/sourcemod/get5/astralis_vs_navi_3123.json', json);
All strings, no brakes
Note that false
does not exist in the KeyValue format and that all numerical values are wrapped in quotes. The
empty strings as values in dictionaries (maplist
and map_sides
) are also required.
"Match"
{
"match_title" "Astralis vs. NaVi"
"matchid" "3123"
"clinch_series" "1"
"num_maps" "3"
"wingman" "0"
"players_per_team" "5"
"coaches_per_team" "2"
"coaches_must_ready" "1"
"min_players_to_ready" "2"
"min_spectators_to_ready" "0"
"skip_veto" "0"
"veto_first" "team1"
"side_type" "standard"
"spectators"
{
"name" "Blast PRO 2021"
"players"
{
"76561197987511774" "Anders Blume"
}
}
"maplist"
{
"de_dust2" ""
"de_nuke" ""
"workshop/1193875520/de_aztec" ""
"de_inferno" ""
"de_mirage" ""
"de_vertigo" ""
"de_ancient" ""
"de_overpass" ""
}
"map_sides" // Example; would only work with "skip_veto" "1"
{
"team1_ct" ""
"team2_ct" ""
"knife" ""
}
"team1"
{
"fromfile" "addons/sourcemod/get5/team_navi.cfg"
}
"team2"
{
"id" "3752"
"name" "Astralis"
"tag" "Astralis"
"flag" "DK"
"logo" "astr"
"matchtext" "Defending Champions"
"players"
{
"76561197990682262" "Xyp9x"
"76561198010511021" "gla1ve"
"76561197979669175" "K0nfig"
"76561198028458803" "BlameF"
"76561198024248129" "farlig"
}
"coaches"
{
"76561197987144812" "Trace"
}
}
"cvars"
{
"hostname" "Get5 Match #3123"
"mp_friendlyfire" "0"
"get5_stop_command_enabled" "0"
"sm_practicemode_can_be_started" "0"
}
}
fromfile
example:
"Team"
{
"id" "1348"
"name" "Natus Vincere"
"tag" "NaVi"
"flag" "UA"
"logo" "navi"
"matchtext" "Challengers"
"players"
{
"76561198034202275" "s1mple"
"76561198044045107" "electronic"
"76561198246607476" "b1t"
"76561198121220486" "Perfecto"
"76561198040577200" "sdy"
}
"coaches"
{
"76561198013523865" "B1ad3"
}
}