Scenario rotation

Have an Arma Reforger server move to the next scenario by itself when a match ends.

An Arma Reforger server runs one scenario at a time, and the game has no rotation of its own. A server here can be given a list instead: when a match ends, it restarts on the next scenario in it.

This page is for Arma Reforger servers only. The per-endpoint schemas are in the API Reference; this is the part the schemas cannot say.

Static and dynamic

A server's scenario is in one of two modes.

ModeThe server runs
StaticOne scenario, until you change it. Every server starts here.
DynamicA list. Each match end moves it to another scenario from the list.

In the portal this is the Scenario setting on the server's Settings page. It has a Static / Dynamic switch; in Dynamic you add scenarios, drag them into order, and choose how the list is played:

  • In order plays the list from the top and starts again after the last entry.
  • At random picks any entry except the one that just finished, so the same scenario never runs twice in a row unless it is the only one.

What a rotation does to a running server

Every move to the next scenario is a server restart. Players are disconnected and have to rejoin once the server is back.

That is a property of the game, not a shortcut taken here: a running Reforger server cannot be told to load a different scenario.

  • Saving a rotation restarts nothing. It takes effect when the current match ends.
  • Only a match ending moves the rotation on. A crash, a restart you ask for and a scheduled restart all bring the server back on the scenario it was already on.
  • The pause on the scoreboard is yours to set. The server waits its Auto Restart Seconds setting before restarting. With that setting empty it waits 30 seconds; the most it will wait is 10 minutes.
  • A mode with no end never moves on. Game Master and other open-ended scenarios do not finish a match, so a rotation that reaches one stays there until you change the scenario yourself.
  • Do not count on saved progress surviving. A persistent scenario's save is the game's to keep or discard when its match ends. A rotation does nothing to preserve it.

The list and the scenario the server is on

The rotation always continues from the scenario the server is really on.

  • If that scenario is in the list you save, the server carries on from its place in the list.
  • If it is not, the server is set to the first entry, and loads it the next time it starts.
  • Picking a different scenario by hand does not confuse the rotation. The next match end moves on from whatever you picked.

Switching back to Static keeps your list for later and leaves the server on the scenario it is on.

Which scenarios you can use

The scenarios on offer are the base game's plus those provided by the mods enabled on the server. A scenario from a mod you have not installed is not something the server can load.

The list of mod scenarios is read from the Workshop when you ask for it. If a mod's Workshop entry cannot be read at that moment, its scenarios are simply missing from the list for a while. A rotation keeps its own copy of each scenario's name, so a gap like that does not empty a list you have already saved.

If you remove a mod whose scenario is still in a rotation, the entry stays in the list and the portal marks it Not on this server. Take it out: a server cannot start on a scenario it does not have.

From a script

Scenarios sit behind the settings abilities, because that is what a scenario is — a startup setting.

AbilityReaches
game-servers.settings.readthe scenario list, and reading the rotation
game-servers.settings.managesetting the rotation

A server that is not Arma Reforger answers 422 with Scenarios are only available for Arma Reforger servers.

List what the server can run

Reference: GET …/scenarios.

curl https://one.terabit.io/api/v1/game-servers/$SERVER/scenarios \
  -H "Authorization: Bearer tbk_..."
{
  "data": [
    {
      "id": "{ECC61978EDCC2B5A}Missions/23_Campaign.conf",
      "name": "Conflict - Everon",
      "game_mode": "Conflict",
      "player_count": null,
      "group": "Base game"
    }
  ]
}

id is what a rotation entry takes. group is Base game or the name of the mod that provides the scenario.

Read the rotation

Reference: GET …/scenario-rotation.

curl https://one.terabit.io/api/v1/game-servers/$SERVER/scenario-rotation \
  -H "Authorization: Bearer tbk_..."
{
  "data": {
    "mode": "dynamic",
    "order": "sequential",
    "scenarios": [
      { "id": "{ECC61978EDCC2B5A}Missions/23_Campaign.conf", "name": "Conflict - Everon", "group": "Base game" },
      { "id": "{C41618FD18E9D714}Missions/23_Campaign_Arland.conf", "name": "Conflict - Arland", "group": "Base game" }
    ],
    "current_scenario_id": "{ECC61978EDCC2B5A}Missions/23_Campaign.conf",
    "next_scenario_id": "{C41618FD18E9D714}Missions/23_Campaign_Arland.conf",
    "last_rotated_at": null
  }
}

current_scenario_id is the scenario the server is on. next_scenario_id is where the next match end takes it, and is null for a random rotation, because the next scenario is drawn when the match ends.

Set the rotation

Reference: PUT …/scenario-rotation.

The request replaces the rotation: the list you send is the list that is kept, in that order. An entry needs only its id; the name and group are filled in from the server's scenario list.

curl -X PUT https://one.terabit.io/api/v1/game-servers/$SERVER/scenario-rotation \
  -H "Authorization: Bearer tbk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "dynamic",
    "order": "sequential",
    "scenarios": [
      { "id": "{ECC61978EDCC2B5A}Missions/23_Campaign.conf" },
      { "id": "{C41618FD18E9D714}Missions/23_Campaign_Arland.conf" }
    ]
  }'

order is sequential or random, and sequential if you leave it out. A list holds at most 50 scenarios, each once.

To stop rotating, send "mode": "static". Send the list along with it if you want it kept; an empty scenarios clears it.

A request that could not run is refused whole, with the entry at fault named:

{
  "message": "That is not a scenario id.",
  "errors": {
    "scenarios.1.id": ["That is not a scenario id."]
  }
}

On this page