Admin Panel

Events

Events are a piece of structured information that your application or application backend sends to SCILL. Those events are processed in real-time to drive challenges and battle passes that you setup in the Admin Panel and that you activate for your users. Events are also stored in the SCILL backend to drive game analytics.

Tip

We have predefined event names for many different applications and game genres. Please see possible event names and meta data structure for each event in our events reference.

Base URL

https://ep.scill.4players.io

Sending Events From Backend

An event is a simple data object and consists of

  • event type
  • meta data

If possible, you should send events from your application backend, otherwise it’s easy for everyone to send events and completing challenges by just sending events using a REST-API client or short script. However, of course there are scenarios where you need to send events from clients, in this case see below Sending Events from Clients.

URL api/v1/events?auth=api_key
Method POST
Authentication API Key
Payload
{
  "event_name": "reach-checkpoint",
  "event_type": "single",
  "session_id": "Session",
  "user_id": "1607084651822",
  "team_id": "Skudz",
  "meta_data": {
    "checkpoint_id": "Charlie",
    "armor": 95,
    "health": 67
  }
}
Payload Parameters

user_id string REQUIRED

This is your user id. You can set this to whatever you like, either your real user id or an obfuscated user id. However you need to be consistent here. Events linked to this user id only track if challenges or battle passes are unlocked with the same user id.

event_name string REQUIRED

This is the event type as a string. These have predefined event names for many games and applications. It’s wise to use those as this allows us to analyse data and help you balancing your application or game.

team_id string OPTIONAL

If you have a team based game or application, you can use this team_id to set the team of the user. As it’s a string, it’s up to you to set any value you like. This setting will be used in Leaderboards to generate team based rankings.

event_type string OPTIONAL

This is either single or group. Sending single events will make our backend increment the counters of the current state of active challenges (if they apply to this event). Using group will allow you to set the counter yourself, i.e. in this case you can group events yourself and then set the counter accordingly. You can mix group events with single events. You could set the number of kills by sending a kill-enemy event with amount in meta_data of 3 to 3 kills. Then, you can send a single event with amount of 1 and user will end with 4 as the counter of his activated kill challenge.

session_id string OPTIONAL

This is required if event_type is single and identifies a session. This can be anything used to group events together. For example this can be a level or a match id. If you change the session for a user and the event_name then the counter of active challenges linked to this event type will reset.

metadata object OPTIONAL

This holds metadata and is optional. However, you can use this to send additional info, like a weapon in a kill event. This way you can build more elaborate challenges like Kill 10 enemies with AK47 and with no armor protection.

Sending events
const SCILL = require("@scillgame/scill-js");

// In Backend code use your API-Key
const eventsApi = SCILL.getEventsApi("__YOUR_API_KEY__");

// In frontend code you need to generate an access token before
// See SCILL.getAuthApi for more info on that
const eventsApi = SCILLClient.getEventsApi(accessToken);

eventsApi.sendEvent({
    event_name: 'reach-checkpoint',
    event_type: 'single',
    session_id: Game.CurrentSession,
    user_id: Game.UserId,
    meta_data: {
        checkpoint_id: "Charlie",
        armor: Player.Armor,
        health: Player.Health
    }
}).then((response) => {
    console.log("Event send successfully", response);
}).catch(error => {
    console.warn("Event could not be sent", error);
});
// In Backend code, you can create instances via API-Key
var scill = new SCILLBackend("__YOUR_API_KEY__");

// In Frontend code, you should use the access token
var scill = new SCILLClient("__ACCESS_TOKEN__");

// Create Metadata object
var metaData = new EventMetaData();
metaData.checkpoint_id = "Charlie";
metaData.armor = Player.Armor;
metaData.health = Player.Health;

// Create Event payload
var payload = new EventPayload(Game.UserId, Game.CurrentSession, "reach-checkpoint", "single", metaData);

// Send the events
var response = await scill.SendEventAsync(payload);
if (response.status < 300) {
    // Event has been sent
}
The Send Event Response
{
  "status": 200,
  "message": "OK"
}

Sending Events From Clients

An event is a simple data object and consists of

  • event type
  • meta data

The preferred way is to send events from the backend. If this is not possible in your application, you can send events directly from the client. In this case, the access token is used to authenticate the user.

URL api/v1/events?auth=access_token
Method POST
Authentication Access token
Payload
{
  "event_name": "reach-checkpoint",
  "event_type": "single",
  "session_id": "Session",
  "meta_data": {
    "checkpoint_id": "Charlie",
    "armor": 95,
    "health": 67
  }
}
Payload Parameters

event_name string REQUIRED

This is the event type as a string. These have predefined event names for many games and applications. It’s wise to use those as this allows us to analyse data and help you balancing your application or game.

event_type string OPTIONAL

This is either single or group. Sending single events will make our backend increment the counters of the current state of active challenges (if they apply to this event). Using group will allow you to set the counter yourself, i.e. in this case you can group events yourself and then set the counter accordingly. You can mix group events with single events. You could set the number of kills by sending a kill-enemy event with amount in meta_data of 3 to 3 kills. Then, you can send a single event with amount of 1 and user will end with 4 as the counter of his activated kill challenge.

team_id string OPTIONAL

If you have a team based game or application, you can use this team_id to set the team of the user. As it’s a string, it’s up to you to set any value you like. This setting will be used in Leaderboards to generate team based rankings.

session_id string OPTIONAL

This is required if event_type is single and identifies a session. This can be anything used to group events together. For example this can be a level or a match id. If you change the session for a user and the event_name then the counter of active challenges linked to this event type will reset.

metadata object OPTIONAL

This holds metadata and is optional. However, you can use this to send additional info, like a weapon in a kill event. This way you can build more elaborate challenges like Kill 10 enemies with AK47 and with no armor protection.

Sending events
const SCILL = require("@scillgame/scill-js");

// In Backend code use your API-Key
const eventsApi = SCILL.getEventsApi("__YOUR_API_KEY__");

// In frontend code you need to generate an access token before
// See SCILL.getAuthApi for more info on that
const eventsApi = SCILLClient.getEventsApi(accessToken);

eventsApi.sendEvent({
    event_name: 'reach-checkpoint',
    event_type: 'single',
    session_id: Game.CurrentSession,
    user_id: Game.UserId,
    meta_data: {
        checkpoint_id: "Charlie",
        armor: Player.Armor,
        health: Player.Health
    }
}).then((response) => {
    console.log("Event send successfully", response);
}).catch(error => {
    console.warn("Event could not be sent", error);
});
// In Backend code, you can create instances via API-Key
var scill = new SCILLBackend("__YOUR_API_KEY__");

// In Frontend code, you should use the access token
var scill = new SCILLClient("__ACCESS_TOKEN__");

// Create Metadata object
var metaData = new EventMetaData();
metaData.checkpoint_id = "Charlie";
metaData.armor = Player.Armor;
metaData.health = Player.Health;

// Create Event payload
var payload = new EventPayload(Game.UserId, Game.CurrentSession, "reach-checkpoint", "single", metaData);

// Send the events
var response = await scill.SendEventAsync(payload);
if (response.status < 300) {
    // Event has been sent
}
The Send Event Response
{
  "status": 200,
  "message": "OK"
}

How events relate to challenges

Challenges (if activated) react to incoming events in real time by the event_name set in the Challenge settings in Admin Panel.

For example, think about this simple challenge: Make 4 or more goals in a match and you set achieve-score as the event name for this challenge. If the user (or the developer automatically) activates the challenge, the challenge will “listen” to achieve-score events. Depending on the content of the event payload of achieve-score the counter of the challenge will increment in real-time.

Once the match starts, your game sends achieve-score events of type single (we’ll come to that later) and in the meta_data object you set amount: 1. This way, the counter of the challenge (and a nice looking progress bar for example) will be incremented in real-time for each incoming event. Now, let’s assume the player only made 2 goals. He did not achieve the challenge. Challenge counter is at 2 of 4. Now, the player tries again, as this is the reason to implement challenges: Increasing the stickyness of the game! Player achieves the next goal, now, if we would not prevent that, the challenge counter would advance to 3 of 4.

But this is not what we want to have! We want the challenge counter to start from scratch. To achieve that, you now send an achieve-score event of type group and set amount: 0 as the event_type. Using group events lets you reset the counter of (active) challenges to the value you like.

One more thing: Events also allow you to set a session_id. This is used to group events to sessions. A session can be anything, but in this example the session would be a match. So, for each match you would create another session id. This can be randomly generated based on time for example, or if you store matches in your database, this can also be a primary id or key of your database.

Whenever the session changes for a specific user_id and event_name the counter starts from scratch. Understanding that know might make you think why we sent that group event to reset the counter of the challenge before, as it would reset for the next match automatically. You are right, but only once the player would score a goal. In this experience the player would see challenge 2 of 4 until he scores the first goal, then it would reset to 1 of 4 after sending the event with a new session id. Depending on the game this might be what you want, sometimes it might not make any difference as the sessions you create a not matches with a lot of time in between, but perhaps in a Hack & Slay with checkpoints it does not make much difference as challenge counter changes very quickly all the time.

In a nutshell:

  • Use single event types for incremental updates to the counter of (active) challenges
  • Use session_id to group single events into sessions. If the session of changes for an event_name and a user_id the counter is reset automatically.
  • Use group event types to set the counter of (active) challenges to the amount given in the meta_data object

Known issues and limitations

Thinking of above example: Make 4 goals in a match. You could also think of a challenge: Make 1.000 goals in a match. Those two challenges are mutally exclusive in our current system. Let’s dig into that to understand:

The first challenge, as said before requires you to send events of type achieve-score and you need to either reset the counter after each match or it will automatically be reset once you change the session_id. Now, the other challenge would require you to send 1.000 events of type achieve-score. You can do that of course if you never change the session_id you could count goals forever. For example you could set the session_id to 1 or the user_id. But having both challenges active at the same time would not be possible.

Why this limitation?

We want to build a system that encourages players to stay in the game and try one more time. We know, that it’s better to provide more granular, incremental goals rather then having that big targets. You quickly forget about them and if players don’t make much progress it’s rather demotivating then motivating. Therefore it’s better to have more short living challenges and than to have a couple of long living challenges.

The idea behind battle passes is the same: Give players many smaller things to complete and reward them afterwards to keep them motivated and to “just do that other thing before going to bed”. Having 101 of 1000 goals will not make most players stay out of bed to come closer, but winning a game with 4 goals might keep them playing.