Skip to main content

External Game Backend integration

What is the purpose of External Game Backend?

If you want to add player progression, play-to-earn functionality or smart contract integration to your game, you have to somehow exchange information about matches running on Elympics with your own backend.

To make that straightforward, we have implemented a feature to enable additional callbacks to your API from our services.

At the moment, there are four possible callbacks that you can configure at different stages of the match flow. All of them will be described on this page.

  • OnQueueJoin
  • OnQueueLeave
  • OnMatchCreate
  • OnMatchFinish

If you want to use OnMatchCreate and/or OnMatchFinish you need to have an external game backend that will implement both of those endpoints.

OnQueueJoin and OnQueueLeave are independent from each other, and can be used separately.

How to turn it on?

Using Web Panel

All you have to do is define endpoints in the game settings (don't forget to click the "Save" button):

For OnMatchCreate and OnMatchFinish:

External game backend setup in Elympics web panel

And accordingly for OnQueueJoin and OnQueueLeave:

QueueEvents

Using Elympics CLI

You can use the Elympics CLI Tool to manage queues by following CLI documentation.

OnMatchCreate and OnMatchFinish events can be modified with the --external-backend argument, while OnQueueJoin and OnQueueLeave are modified through --queue-join-url and --queue-leave-url respectively.

Endpoints to implement

Match create: /elympics/match/create

A request to /elympics/match/create is sent after a match is created in our database, but before bootstrapping real game on one of our game servers. It could be used to:

  • insert information about the match in your database e.g. for statistical / progression purposes,
  • verify player-provided data for match initiation,
  • add and/or replace players initial data using one stored in your database,
  • block some players, game versions, etc.
Response format

Response values in all fields but GameEngineData and MatchmakerData must stay the same as in the request.

{
"MatchId": "d060f00d-0000-0000-0000-1d0000001234",
"GameId": "d060f00d-0000-0000-0000-1d0000006a3e",
"GameVersion": "1.2.3",
"UserDatas": [
{
"UserId": "d060f00d-0000-0000-0000-1d0000085e70",
"IsBot": false,
"BotDifficulty": 0,
"GameEngineData": "eyJlcXVpcG1lbnQiOlsia2F0YW5hIl0sImRvY3MtZXhhbXBsZSI6dHJ1ZX0=",
"MatchmakerData": [
1.0
]
},
{
"UserId": "d060f00d-0000-0000-0000-1d0000000b07",
"IsBot": true,
"BotDifficulty": 6.62607,
"GameEngineData": null,
"MatchmakerData": null
}
]
}

Match finish: /elympics/match/finish

A request to /elympics/match/finish is made after a match is finished. It contains the information about match results that can be e.g. inserted into your database.

{
"MatchId": "d060f00d-0000-0000-0000-1d0000001234",
"GameId": "d060f00d-0000-0000-0000-1d0000006a3e",
"GameVersion": "1.2.3",
"UserDatas": [
{
"UserId": "d060f00d-0000-0000-0000-1d0000085e70",
"IsBot": false,
"BotDifficulty": 0,
"GameEngineData": "",
"MatchmakerData": [0.0, 3.0]
},
{
"UserId": "d060f00d-0000-0000-0000-1d0000000b07",
"IsBot": true,
"BotDifficulty": 6.62607,
"GameEngineData": "eyJkb2NzLWV4YW1wbGUiOnRydWV9",
"MatchmakerData": [1.0, -1.0]
}
]
}

OnQueueJoin

The OnQueueJoin endpoint is activated before a player physically joins the matchmaking queue. The external backend could:

  • overwrite the player's GameEngineData and MatchmakerData.
  • prevent player from joining the queue and pass a RejectionCause.
  • collect information about actual matchmaking process
{
"UserId": "d060f00d-0000-0000-0000-1d0000001234",
"GameId": "d060f00d-0000-0000-0000-1d0000006a3e",
"QueueName": "Training",
"GameVersion": "1.2.3",
"RegionName": "warsaw",
"GameEngineData": "eyJlcXVpcG1lbnQiOlsia2F0YW5hIl0sImRvY3MtZXhhbXBsZSI6dHJ1ZX0=",
"MatchmakerData": [
1.0
]
}

OnQueueLeave

The OnQueueLeave endpoint is activated just before a player leaves the matchmaking queue. There are many different reasons why this might occur, and an Enum is provided with all possible cases. This endpoint is only informational for your backend, you can't alter the player state using the response.

This endpoint can be used to unblock a player on your backend, check how long people waited in the queue before leaving, what is the average time for finding a match, and other purposes.

This endpoint can be enabled by adding the EventQueueLeaveUrl to the game configuration.

{
"UserId": "d060f00d-0000-0000-0000-1d0000001234",
"GameId": "d060f00d-0000-0000-0000-1d0000006a3e",
"QueueName": "Training",
"GameVersion": "1.2.3",
"RegionName": "warsaw",
"GameEngineData": "eyJlcXVpcG1lbnQiOlsia2F0YW5hIl0sImRvY3MtZXhhbXBsZSI6dHJ1ZX0=",
"MatchmakerData": [
1.0
],
"Reason": "MatchmakingFinished"
}

Request verification

JWT tokens used by Elympics in External Game Backend requests can be verified using the "internal" public key available through Elympics CLI.

Besides the standard not-before (nbf), expiration (exp) and issued-at (iat) times, each token provides hash and hash-alg claims that can be used to ensure the integrity of request body.

hash stores a checksum calculated using hashing algorithm described by hash-alg. The checksum is based solely on the contents of HTTP message body.

By validating both the token and the content hash you ensure that the request was indeed sent by us and no one tampered with the contents.

Checksum

If you want to calculate checksum for comparison on your end, you have to use the original content string of HTTP message. Hashing parsed JSON objects makes no sense as it is completely non-portable.

Player UserData Model

Each player's UserData model, which is sent to all configured endpoints, contains two important fields: MatchmakerData and GameEngineData. These fields allow data to be passed from your backend to the game server. The OnQueueJoin and OnMatchCreate functions can override the values that were sent to them. Lets say that you want to track the win streak of each player and view it in the game. To do so, you need to enrich the GameEngineData with that information using your backend which track all win streaks by collecting MatchmakerData results on the OnMatchFinish. Possibilities are endless.

GameEngineData

GameEngineData is a byte array represented as a base64-encoded string. It can be used to enrich the initial player data. This value can be decoded on your backend, modified, and then re-encoded.

The most common and convenient way to store data in this field is using a markup language, such as JSON or YAML. Here's an example utility function written in Python that shows how to decode and encode this data:

import base64
import json

from typing import Any


def decode_game_engine_data(game_engine_data: str | None) -> dict[str, Any]:
if game_engine_data is None:
return {}
return json.loads(base64.b64decode(game_engine_data.encode("utf8")))


def encode_game_engine_data(game_engine_data: dict[str, Any]) -> str:
json_data = json.dumps(game_engine_data)
base64_data = base64.b64encode(json_data.encode("utf8"))
return base64_data.decode("utf8")

MatchmakerData

MatchmakerData is a float array intended to represent the initial setup of the player if it's critical for matchmaking. For duel games, this data is utilized by our machine learning service to provide enhanced matchmaking that takes into account not only player skill, but also additional features.

At the conclusion of a match (OnMatchFinish), the first value of the array should represent the player's score for that game (the higher the better). This score is used in player ranking calculations, our leaderboard service, and for training and evaluating our smart matchmaking models. If you don't pass any number in it or something that will not represent the player score, all mentioned features will not take this match into account.

Additional endpoints

Your backend can provide an arbitrary number of additional endpoints to be utilized by game code. Those functions are not handled by Elympics in any way – you have to send web requests manually from your code.

When performing such requests, you can use a JWT authentication token granted to each user by Elympics. The token is accessible through Authenticated event of ElympicsLobbyClient singleton. You can find more information in the article about matchmaking.

Example cURL:

curl --location --request POST 'https://{YOUR_BACKEND_URL}/arbitrary/endpoint' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiJ0ZXN0LXVzZXIiLCJuYmYiOjE2NjQ1MzkxMDcsImV4cCI6MTk3OTg5OTEwNywiaWF0IjoxNjY0NTM5MTA3fQ.bBJmzPrybXDZMrwP9u9oWKs8v-6dRYhT-mLwnNJY3i6V4FdbceCZIb_IJYTHTKtCixHRAjG1--fvBYKt5zJRqfKlD6ic4VQajN0TVCljREHxHtEdtKcZSEKl9syyUpVDOnork77m3wgAUAagd7BDjuN6fXXmX_U0g0r4S-QAZdwsrSEMBrHJjJXw3cQ222pl4pR6JmWpV5gxeB_VIwLbLU-mLSvJZWDQa49t4lx2o0DM0_HcoKuVMjW-_LwtQusCl140PFJI18ecP3CAYFyAUgwcSH7OBw_VbWpu6-MVXLgRqJaovVEIibHXok26C9_3LjULlx_VaeuYncR-eAJ_A9qsCUlI77xuA0Azm3GoguUUdnbXN3UPOeBKx4q92HWD9gI9fFHiBDaRYoW7OqyckytHiu1wTMCAnF_UbRrwMQJrM6bJSp5rM6CfZanYuyvglD9KX5dWPMjaWDfyctKKHQ8nRy1ZZ45aBgIjzw-TioaNgDHDx0BMGvdRRohNYCTQQOZ7vToSebAMuyD9UDRZXGfq_u6XWabayE0OnxTXhn7QfMu2jm5_5MbgbBvk4uqPC1TETzo8Te2aCZLLXPO2YlW683gja7GGaNG-9xT9kb294dLJMD6hvUa96DK0h_XISG5iE1sM3B7MG1BU4iy-JGkkffDwK7hbhzODV2pFhFE' \
--header 'Content-Type: application/json' \
--data-raw '{
"ExampleField": "Example data"
}'

Request verification

JWT tokens granted to users can be verified using the "users" public key available through Elympics CLI.

These tokens contain additional nameid claim storing the ID of a player.