forio Toggle navigation

Multiplayer World API

The Multiplayer World API allows you to link end users together. Once linked together, the end users can share a run. This means your project can be a shared world for sets of end users.

Because the Multiplayer World API links end users, it is only used with Authenticated projects, that is, projects with end users and groups.

The Multiplayer World API supports the following use cases and HTTP methods:

Working with Worlds

The world object contains metadata about the world, including the team, project, and end users.

Creating a World


Method: POST

URI: /v2/multiplayer/world

Headers: Content-Type: application/json, Authorization: Bearer{project access token}

Body: JSON object containing the account, project, and group, or an array of such objects.

Return Status: 201 (successful creation of world)

Return Body: The world record (JSON object), or an array of world records (if creating multiple world at once).


Example:

curl -X POST \
    'https://api.forio.com/v2/multiplayer/world' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"account": "acme-simulations", "project": "supply-chain-game", "group": "fall2014-seminar"}'

Example Response:

{
    "account": "acme-simulations",
    "users": [],
    "project": "supply-chain-game",
    "id": "5441648bfac2a42306000001",
    "group": "fall2014-seminar",
    "lastModified": "2014-10-17T18:48:43.000Z",
    "complete": false,
    "created": "2014-10-17T18:48:43.000Z",
    "roles": []
}

Notes:

  • In the header, the access token can be the user access token of a team member developing this project, or the project access token for the project. If the Project Settings allow it, it can also be the user access token for an end user in this group.
  • In the body, the account field is the Team ID.
  • Additional, optional fields that you can include in the request body include:

    • name: A string identifier for the linked end users, for example, "name": "Our Team".
    • roles: A list of strings. Some worlds have specific roles that must be filled by end users. Listing the roles as part of the world object allows you to autoassign users to worlds and ensure that all roles are filled in each world. If not supplied, the roles are taken from the world configuration for this project.
    • optionalRoles: A list of strings. Some worlds have specific roles that may be filled by end users. Listing the optional roles as part of the world object allows you to autoassign users to worlds and ensure that all roles are filled in each world. If not supplied, the optionalRoles are taken from the world configuration for this project.
    • minUsers: An integer. Some worlds have a specific number of end users required. Including this number in the world object allows you to autoassign users to worlds and ensure that the correct number of users are in each world.
  • The complete field indicates whether or not end users have been linked together for this world. It is true once there is an end user for every value of roles and there are minUsers in the world. Note that a world can be complete if roles are filled even if optionalRoles are not filled.

Updating a World


Method: PATCH

URI: /v2/multiplayer/world/{world id}

Headers: Content-Type: application/json, Authorization: Bearer{project access token}

Body: JSON object containing the fields to update.

Return Status: 200 (successful response)

Return Body: The updated world record (JSON object).


Example:

curl -X PATCH \
    'https://api.forio.com/v2/multiplayer/world/57ed43c0dd6fe01673000009' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"roles": ["VP Marketing", "VP Sales", "VP Engineering"]}'

Example Response:

{
    "account": "acme-simulations",
    "users": [],
    "project": "supply-chain-game",
    "id": "5441648bfac2a42306000001",
    "group": "fall2014-seminar",
    "lastModified": "2014-10-17T18:48:43.000Z",
    "complete": false,
    "roles": [
        "VP Marketing",
        "VP Sales",
        "VP Engineering"
    ],
    "created": "2014-10-17T18:48:43.000Z"
}

Notes:

  • In the header, the access token can be the user access token of a team member developing this project, or the project access token for the project. If the Project Settings allow it, it can also be the user access token for an end user in this group.
  • In the body, the fields that you can update are:
    • name: A string identifier for the linked end users, for example, "name": "Our Team".
    • roles: A list of strings. Some worlds have a specific roles that must be filled by end users. Listing the roles as part of the world object allows you to autoassign users to worlds and ensure that all roles are filled in each world. If not supplied, the roles are taken from the world configuration for this project.
    • optionalRoles: A list of strings. Some worlds have specific roles that may be filled by end users. Listing the optional roles as part of the world object allows you to autoassign users to worlds and ensure that all roles are filled in each world. If not supplied, the optionalRoles are taken from the world configuration for this project.
    • minUsers: An integer. Some worlds have a specific number of end users required. Including this number in the world objects allows you to autoassign users to worlds and ensure that the correct number of users are in each world.

Reading World Information for a Single World


Method: GET

URI: /v2/multiplayer/world/{world id}

Headers: Authorization: Bearer{project access token}

Return Status: 200 (successful response)

Return Body: The world record (JSON object).


Example:

curl -G \
    'https://api.forio.com/v2/multiplayer/world/57ed43c0dd6fe01673000009' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

{
    "account": "acme-simulations",
    "users": [],
    "project": "supply-chain-game",
    "id": "54418078fac2a42306000008",
    "run": "b594f009-a1d3-4ea3-979c-5511d2f17a66",
    "group": "fall2014-seminar",
    "lastModified": "2014-10-17T18:48:43.000Z",
    "complete": false,
    "created": "2014-10-17T18:48:43.000Z",
    "optionalRoles": [],
    "roles": [
        "VP Marketing",
        "VP Sales",
        "VP Engineering"
    ]
}

Notes:

Reading World Information for a Single World, with Specific Fields


Method: GET

URI: /v2/multiplayer/world/{world id}?include={field name}

Headers: Authorization: Bearer{project access token}

Return Status: 200 (successful response)

Return Body: The world record (JSON object), including the world id and the specifically requested field(s).


Example:

curl -G \
    'https://api.forio.com/multiplayer/v2/world/54418078fac2a42306000008?include=name' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

{
    "id": "54418078fac2a42306000008",
    "name": "Our Team",
    "account": "acme-simulations",
    "project": "supply-chain-game"
}

Notes:

  • In the header, the access token can be the user access token of a team member developing this project, or the project access token for the project. If the Project Settings allow it, it can also be the user access token for an end user in this group.
  • To include multiple fields, use: ?include=field1&include=field2.

Reading World Information for a Single World, without Specific Fields


Method: GET

URI: /v2/multiplayer/world/{world id}?exclude={field name}

Headers: Authorization: Bearer{project access token}

Return Status: 200 (successful response)

Return Body: The world record (JSON object), with all fields except those listed in the URI.


Example:

curl -G \
    'https://api.forio.com/v2/multiplayer/world/54418078fac2a42306000008?exclude=users' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

{
    "account": "acme-simulations",
    "project": "supply-chain-game",
    "id": "54418078fac2a42306000008",
    "run": "b594f009-a1d3-4ea3-979c-5511d2f17a66",
    "group": "fall2014-seminar",
    "lastModified": "2014-10-17T18:48:43.000Z",
    "complete": false,
    "created": "2014-10-17T18:48:43.000Z"
}

Notes:

  • In the header, the access token can be the user access token of a team member developing this project, or the project access token for the project. If the Project Settings allow it, it can also be the user access token for an end user in this group.
  • To exclude multiple fields, use: ?exclude=field1&exclude=field2.
  • This is most useful for excluding the users field, which can be quite long.
  • The run field contains the current run id, and is only present if a run has been started for this world.

Reading World Information for All Worlds in this Group


Method: GET

URI: /v2/multiplayer/world?account={team id}&project={project id}&group={group name}

Headers: Authorization: Bearer{project access token}

Return Status: 200 (successful response)

Return Body: An array of world records (JSON objects).


Example:

curl -G \
    'https://api.forio.com/v2/multiplayer/world?account=acme-simulations&project=supply-chain-game&group=fall2014-seminar' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

[
    {
        "account": "acme-simulations",
        "users": [
            {
                "index": 3,
                "role": "VP Sales",
                "status": "new",
                "lastName": "Smith",
                "userId": "b6b313a3-ab84-479c-baea-206f6bff337f",
                "userName": "jsmith"
            },
            // other users, if any
        ],
        "roles": [],
        "optionalRoles": [],
        "project": "supply-chain-game",
        "id": "54418078fac2a42306000008",
        "run": "b594f009-a1d3-4ea3-979c-5511d2f17a66",
        "group": "fall2014-seminar",
        "lastModified": "2014-10-17T18:48:43.000Z",
        "complete": false,
        "created": "2014-10-17T18:48:43.000Z"
    },
    // other worlds in this group and project, if any
]

Notes:

Reading World Information for All World for a Specific End User


Method: GET

URI: /v2/multiplayer/world?account={team id}&project={project id}&group={group name}&userId={user id}

Headers: Authorization: Bearer{project access token}

Return Status: 200 (successful response)

Return Body: An array of world records (JSON objects).


Example:

curl -G \
    'https://api.forio.com/v2/multiplayer/world?account=acme-simulations&project=supply-chain-game&group=fall2014-seminar&userId=b6b313a3-ab84-479c-baea-206f6bff337f' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

[
    {
        "account": "acme-simulations",
        "users": [
            {
                "index": 3,
                "role": "VP Sales",
                "status": "new",
                "lastName": "Smith",
                "userId": "b6b313a3-ab84-479c-baea-206f6bff337f",
                "userName": "jsmith"
            },
            // other users in this world, if any
        ],
        "project": "supply-chain-game",
        "id": "54418078fac2a42306000008",
        "run": "b594f009-a1d3-4ea3-979c-5511d2f17a66",
        "group": "fall2014-seminar",
        "lastModified": "2014-10-17T18:48:43.000Z",
        "complete": false,
        "created": "2014-10-17T18:48:43.000Z"
    },
    // other worlds in this group and project, if any, 
    // in which this user is a part
]

Notes:

Removing a World


Method: DELETE

URI: /v2/multiplayer/world/{world id}

Headers: Authorization: Bearer{project access token}

Return Status: 204 (successful deletion of world)


Example:

curl -X DELETE \
    'https://api.forio.com/v2/multiplayer/world/5441648bfac2a42306000001' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

There is no response body for a DELETE request.

Removing All Worlds in a Group


Method: DELETE

URI: /v2/multiplayer/world?account={team id}&project={project id}&group={group name}

Headers: Authorization: Bearer{project access token}

Return Status: 204 (successful deletion of all worlds in group)


Example:

curl -X DELETE \
    'https://api.forio.com/v2/multiplayer/world?account=acme-simulations&project=supply-chain-game&group=fall2014-seminar' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

There is no response body for a DELETE request.

Working with Worlds and End Users

Once you've created a world, the next step is to add end users to it.

Adding an End User to a World


Method: POST

URI: /v2/multiplayer/world/{world id}/users

Headers: Content-Type: application/json, Authorization: Bearer{project access token}

Body: JSON object containing the userId and optionally the role and team, or an array of such objects.

Return Status:

  • 201: Successful creation of end user within the world
  • 400: Invalid end user, e.g. end user does not exist or is not in group

Return Body: The end user record (JSON object), as it is now stored in the world record, or an array of such records (if adding multiple end users for this world at once).


Example:

curl -X POST \
    'https://api.forio.com/v2/multiplayer/world/54419115fac2a4cb4f000001/users' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"userId": "b6b313a3-ab84-479c-baea-206f6bff337f", "role": "VP Sales"}'

Example Response:

{
    "index": 0,
    "role": "VP Sales",
    "status": "new",
    "lastName": "user1",
    "userId": "b6b313a3-ab84-479c-baea-206f6bff337f",
    "userName": "user1"
}

Notes:

  • In the header, the access token can be the user access token of a team member developing this project, or the project access token for the project. If the Project Settings allow it, it can also be the user access token for an end user in this group.
  • Important: In the body, the userId must be in the group that was used to create the world.
  • In the body, including the role and team are optional.
    • The role is one of the roles or optionalRoles specified for this world.
    • The team is a string used to identify this user as part of a set within with world. For example, if your project uses only one world (and one run) for all end users, but you want sets of end users to compete in that world, you can use this field to identify the sets of end users.
  • It is up to the caller to ensure, if needed, that the role passed in to this request is an element of the roles or optionalRoles arrays in the world record.
  • The user status can be:
    • new: Just created.
    • active: Recently active.

Adding an End User to a World and Automatically Assigning a Role


Method: POST

URI: /v2/multiplayer/world/{world id}/users

Headers: Content-Type: application/json, Authorization: Bearer{project access token}

Body: JSON object containing the userId and the field autoAssignRole with value true, or an array of such objects.

Return Status:

  • 201: Successful creation of end user within the world
  • 400: Invalid request

Return Body: The end user record (JSON object), as it is now stored in the world record, or an array of such records (if adding multiple end users for this world at once).


Example:

curl -X POST \
    'https://api.forio.com/v2/multiplayer/world/54419115fac2a4cb4f000001/users' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '[{"userId": "b6b313a3-ab84-479c-baea-206f6bff337f", "autoAssignRole": true}, {"userId": "1518569c-1615-4384-b413-a6c448e32627", "autoAssignRole": true}]'

Example Response:

[
    {
        "index": 0,
        "lastName": "user2",
        "status": "new",
        "role": "VP Marketing",
        "userId": "74605352-0819-43a7-a83b-eb7b5a9adc9d",
        "userName": "user2"
    },
    {
        "index": 1,
        "lastName": "user1",
        "status": "new",
        "role": "VP Sales",
        "userId": "b6b313a3-ab84-479c-baea-206f6bff337f",
        "userName": "user1"
    }
]

Notes:

  • In the header, the access token can be the user access token of a team member developing this project, or the project access token for the project. If the Project Settings allow it, it can also be the user access token for an end user in this group.
  • Autoassigning sets each end user's role to one of the roles or optionalRoles (from the world object) that is not already used.
  • The user status can be:
    • new: Just created.
    • active: Recently active.
  • Examples of invalid requests (400 return status code) include:
    • An end user that does not exist
    • An end user is not in the group
    • The autoAssignRole is passed in as true but all roles and optionalRoles are already assigned

Updating an End User's Role in a World


Method: PATCH

URI: /v2/multiplayer/world/{world id}/users/{user id}

Headers: Content-Type: application/json, Authorization: Bearer{project access token}

Body: JSON object with field role and the new value for the role.

Return Status: 200 (successful response)

Return Body: The updated end user record (JSON object), as it is now stored in the world record.


Example:

curl -X PATCH \
    'https://api.forio.com/v2/multiplayer/world/54419115fac2a4cb4f000001/users/74605352-0819-43a7-a83b-eb7b5a9adc9d' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"role": "VP Engineering"}'

Example Response:

{
    "index": 0,
    "lastName": "user2",
    "status": "new",
    "role": "VP Engineering",
    "userId": "74605352-0819-43a7-a83b-eb7b5a9adc9d",
    "userName": "user2"
}

Notes:

  • In the header, the access token can be the user access token of a team member developing this project, or the project access token for the project. If the Project Settings allow it, it can also be the user access token for an end user in this group.
  • In the body, including the role and team are optional.
    • The role is one of the roles or optionalRoles specified for this world.
    • The team is a string used to identify this user as part of a set within with world. For example, if your project uses only one world (and one run) for all end users, but you want sets of end users to compete in that world, you can use this field to identify the sets of end users.
  • It is up to the caller to ensure, if needed, that the role passed in to this request is an element of the roles or optionalRoles arrays in the world record.
  • Although autoassigning guarantees that only one user is assigned to each role for this world, a PATCH request does not make this check. It is up to the caller to ensure, if needed, that roles are not duplicated in this world.

Reading End User Information


Method: GET

URI: /v2/multiplayer/world/{world id}/users

Headers: Authorization: Bearer{project access token}

Return Status: 200 (successful response)

Return Body: The array of end users (JSON objects) in this world.


Example:

curl -G \
    'https://api.forio.com/v2/multiplayer/world/54418078fac2a42306000008/users' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

[
    {
        "index": 0,
        "lastName": "user2",
        "status": "new",
        "role": "VP Sales",
        "userId": "74605352-0819-43a7-a83b-eb7b5a9adc9d",
        "userName": "user2"
    },
    // other end users in this world, if any
]

Notes:

  • In the header, the access token can be the user access token of a team member developing this project, or the project access token for the project. If the Project Settings allow it, it can also be the user access token for an end user in this group.
  • You can also retrieve the end users for a world as part of the complete world object, see above.

Removing an End User from a World


Method: DELETE

URI: /v2/multiplayer/world/{world id}/users/{user id}

Headers: Authorization: Bearer{project access token}

Return Status: 204 (successful deletion of end user from world)


Example:

curl -X DELETE \
    'https://api.forio.com/v2/multiplayer/world/54419115fac2a4cb4f000001/users/b6b313a3-ab84-479c-baea-206f6bff337f' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

There is no response body for a DELETE request.

Notes:

  • Optionally, you can append the query parameter deleteWorld=true to the URI, for example https://api.forio.com/v2/multiplayer/world/54419115fac2a4cb4f000001/users/b6b313a3-ab84-479c-baea-206f6bff337f?deleteWorld=true. In this case, if removing this end user from the world means that there are now no more end users in the world, then the world is also removed.

Removing All End Users from a World


Method: DELETE

URI: /v2/multiplayer/world/{world id}/users/

Headers: Authorization: Bearer{project access token}

Return Status: 204 (successful deletion of end user from world)


Example:

curl -X DELETE \
    'https://api.forio.com/v2/multiplayer/world/54419115fac2a4cb4f000001/users/' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

There is no response body for a DELETE request.

Notes:

  • Optionally, you can append the query parameter deleteWorld=true to the URI, for example https://api.forio.com/v2/multiplayer/world/54419115fac2a4cb4f000001/users?deleteWorld=true. In this case, there are now no more end users in the world, and the world is also removed.

Working with Worlds and Runs

Once you've created a world and added end users to it, you can start a run for this world. Remember that a run is a collection of user interactions with your project and its model. In the case of multiplayer worlds, all of the end users that are part of the world share the same run (and model state).

Starting a Run for a World


Method: POST

URI: /v2/multiplayer/world/{world id}/run

Headers: Authorization: Bearer{project access token}

Body: JSON object with the name of the model, e.g. {"model": "myModel.py"}.

Return Status:

  • 200: Run successfully associated with world
  • 400: Invalid request, e.g. no model field in the world object

Return Body: The run id.


Example:

curl -X POST \
    'https://api.forio.com/v2/multiplayer/world/54419115fac2a4cb4f000001/run' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"model": "myModel.py"}

Example Response:

"2e7927be-668c-4a5b-8e7e-f0f7064a24bb"

Notes:

  • In the header, the access token can be the user access token of a team member developing this project, or the project access token for the project.
  • In the body, the model field is the name of the primary model file — the one file in your project's Model folder that explicitly exposes variables and methods. For example, this might be "myModel.vmf" or "supply-chain-game.jl".
  • IMPORTANT: This POST request has the side effect of updating the run record with the world id.
  • The response is the current run id for this world.
    • If there was not already a run in progress for this world, a new run is created and associated with the world.
    • If there is already a run in progress for this world, but it is not currently in memory, it is automatically replayed. (See more on run persistence.)

Reading Run Information for a World


Method: GET

URI: /v2/multiplayer/world/{world id}/run

Headers: Authorization: Bearer{project access token}

Return Status: 200 (successful response)

Return Body: The run id (string).


Example:

curl -G \
    'https://api.forio.com/v2/multiplayer/world/54418078fac2a42306000008' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

"b594f009-a1d3-4ea3-979c-5511d2f17a66"

Notes:

Reading All Runs for a World


Method: GET

URI: /v2/model/run?account={account id}&project={project id}&scope.group={group name}&scope.worldId={world id}

Headers: Authorization: Bearer{project access token}

Return Status: 200 (successful response)

Return Body: An array of run records (JSON objects) matching the query.


Example:

curl -G \
    'https://api.forio.com/v2/model/run?account=acme-simulations&project=supply-chain-game&scope.group=fall2014-seminar-&scope.worldId=54453bf7fac2a4fb26000002' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

[
    {
        "id": "b594f009-a1d3-4ea3-979c-5511d2f17a66",
        "model": "supply-chain-game.jl",
        "project": "supply-chain-game",
        "initialized": false,
        "created": "2014-10-20T16:45:02.161Z",
        "lastModified": "2014-10-20T16:45:02.161Z",
        "scope": {
            "worldId": "54453bf7fac2a4fb26000002",
            "group": "fall2014-seminar"
        },
        "account": "acme-simulations",
        "saved": false
    },
    // other run records, if any
]

Notes:

Removing a Run from a World


Method: DELETE

URI: /v2/multiplayer/world/{world id}/run

Headers: Authorization: Bearer{project access token}

Return Status: 204 (successful deletion of run from world)


Example:

curl -X DELETE \
    'https://api.forio.com/v2/multiplayer/world/54419115fac2a4cb4f000001/run' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

There is no response body for a DELETE request.

Notes:

  • In the header, the access token can be the user access token of a team member developing this project, or the project access token for the project.
  • The world id remains part of the run record, indicating that the run was formerly an active run for the world. See above for accessing all runs with this world id.