JS

How to integrate the javascript plugin.

You can use this plugin for all browser-based games.

Connecting plugin to your project.

To obtain the plugin please connect with us.

If you are using react, then just import these:

import { service, ESCSButton, ESCSWebView } from '@escs/react-escs-plugin' 
import '@escs/react-escs-plugin/dist/styles.css'

You can use ESCSButton and ESCSWebView as your regular react components in JSX like this:

<ESCSWebView></ESCSWebView>
<ESCSButton visible={true}></ESCSButton>

Otherwise, if you are using plain vanilla js or any other js framework, you need to use vanilla js imports:

import { service, renderReact } from '@escs/react-escs-plugin' 
import '@escs/react-escs-plugin/dist/styles.css'

Then in your main js file you need to initialize react render:

renderReact('app', callback);

and in your callback you can instantiate two ESCS components:

window.Loader.load("ESCSButton", {
    visible: true
}, divEscsButton, () => {
    console.log("ESCSButton Loaded");
});

window.Loader.load("ESCSWebView", null, divEscsWebView, () => {
    console.log("ESCSWebView Loaded");
});

where firstContainer and secondContainer are your DOM elements, where Escs Button and Escs WebView will be rendered

Also, for your convenience, you can inject service in the global window scope, to be able to access it in all parts of your game:

window.escsService = service;

Integrating plugin into your game.

Initialization

To start using your plugin you need first initialize it:

service.invokeManaged({
    public_key: '3dd48bec-2e82-4826-8757-fc14d872882d',
    base_url: 'https://api.escs.io',
    player_base_url: 'https://player.escs.io',
    analyticsEnv: 'prod'
})

where:

  • public_key - a key that you've obtained in the step 1 of the integration guide

  • base_url - url for the core ESCS service. It is https://api.escs.io for production environment

  • player_base_url - url for the player's ESCS service. It is https://player.escs.io for production environment

  • analyticsEnv- environment to use for analytics reporting

Start/End Game

After that you are all set and ready to use ESCS functionality. To start a game's round, just call startGame() method:

service.startGame()

When the round of your game has ended, just call endGame(score) with score parameter:

service.endGame({ points: 150.0, points_extra: 2.0)})

Score is an object, fields names should be defined in game dashboard at client.escs.io, and the values should be of double type.

Probably you would like some additional layer of security sending game results to a server, so you can use encrypted transfer (using symmetric cryptographic key):

service.endGameEncrypted(key, score);

where key - is a function, that returns a string key when called. This key you should obtain in your client dashboard described in Anti-Cheat services - look up the "front secret key".

We recommend to obfuscate your key and not store it as a value - that is why endGameEncrypted is expecting a function, not a value. For example, you can obfuscate string values here: https://anseki.github.io/gnirts

Optional steps

Hiding ESCS button

Most of the time you will not want to show the ESCS button during the actual game, to not mess with the gameplay, for example user can accidentally touch it and almost full-screen webview will show up. To hide the button you can use its visible property. For React.js this would be:

<ESCSButton visible={false}></ESCSButton>

And for vanilla js a bit more verbose:

        window.Loader.load(
            "ESCSButton",
            { visible: false },
            divEscsButton,
            () => console.log("[ESCSButton Disabled]")
        )

Notifications/Announcements

There are situations, when ESCS needs to show announcements or notifications - for example to promote your game's upcoming championship, or ask user to add credit card, because his/her trial is about to expire. ESCS will open its full WebView automatically to show notification's content, if it's needed. To be able to show these, not interrupting your gameplay and at the times that are not interruptive for user, please call these methods:

   service.maybeShowAnnouncements()
   service.maybeShowNotifications()

There's internal logic in the plugin to decide whether it needs to show actual notification and announcement, but you should place these calls whenever you feel that interruption with ESCS WebView window is okay for user experience.

Please note that it does not mean that user will see notification or announcement every time you call these methods. We are trying for those to be as subtle and fluent as possible for end user. Their names imply that notification/announcement just maybe will be shown.

Additional Considerations

You might want to use some custom tracking within ESCS plugin, to bind you user to ESCS's user sessions and see how your championship is going. To use it set your custom tracking params like this:

escsService.setTrackingParams({param1: "value1", param2: "value2"})

Then these parameters will travel through ESCS analytics with the user session.

There are often situation when you want to respond somehow to the ESCS service state. You can use getStatus() method:

service.getStatus()

which will return object like this:

{
    loggedIn, // true / false
    initialized, // true / false
    subscription, //active subscription object
    gameId, //game id sting
    userSessionId, //internal ESCS session string
    gameName, //your game name in ESCS 
    trackingParams //tracking params that you set using setTrackingParams
}

Getting in-game rewards

To receive the list of in-game rewards that particular player has (you can set those rewards as string fields in your game dashboard - for winning matches and so on) you can use the following method:

const rewards = await service.getIngameRewards()
console.log("rewards", rewards)

which will return object like this:

{
    count, // number of rewards, integer
    data: [ //array of reward objects
        {
            _id, // id of the reward, string
            rewardData, // string representation of reward (you set it in dashboard)
            tournamentId //tournament id where it was received by player
        //...
    ]
}

Multiplayer

Overview

We support multiplayer games with different types of matches, matchmaking and so on. To be able to use this feature, you need to follow these steps:

  • Create multiplayer tournament in the game dashboard

  • Implement several callbacks in you game, which will be called in response to player's engagement with multiplayer tournament

Currently we provide 4 such callbacks:

  • OnGameSetStart callback - is called when a game set is started by escs backend. This is moment when you should start your game or create lobby and await for players to join it. What is a "set"? It's just one multiplayer game that several players are playing simultaneously. It can be real multiplayer (e.g. they, for example, race each other on track in a racing game or are participating in a deathmatch 1vs1 or 2vs2 and so on), or even "singleplayer", meaning that they all play their own singleplayer game (like solving puzzles and the one who solves it faster is the winner). In this callback you will receive information about players that are playing this set, teams that players are in (i.e. 2vs2 game), metadata that is supplied with the player (supplied by registerInGamePlayerId) and global metadata that is set in the game dashboard

  • OnGameSetEnd callback - is called when each player in the set has finished their game. this might be not necessary the same moment you end your multiplayer game - it is called when the escs backend processed all game end events from each participating player and saved their corresponding scores. You will receive matchId and setId as parameters

  • OnMatchStart callback - is called when multiplayer match has started. Usually you will get this event right before getting OnGameSetStart. Each match consists of several game sets. You will receive matchId as parameter of this callback.

  • OnMatchEnd callback - is called when multiplayer match has ended. That is when all the sets in the match has been played or timeout occurred. You will receive matchId as parameter of this callback

The following diagram may be helpful for understanding about aforementioned events:

To utilize these events you should call following methods after initializing escs service:

Registering in-game player id and metadata:

service.registerInGamePlayerId("playerId", "ingameMetadata")

where:

  • playerId - your ingame player id (string). It will be passed along with OnGameSetStart callback when the game set will start

  • ingameMetadata - your ingame metadata for this player (string)

Register OnGameSetStart event callback

service.registerGameSetStartCallback( payload => {
    console.log("setStartCallback", payload) 
})

where payload contains fields:

{
    setId, //setId of started set (string) 
    tournamentId, //tournamentId of the set (string) 
    matchId, //matchId of the set (string) 
    roundId, //roundId of the set (this is in fact id of the set "results") (string) 
    globalMetadata, //metadata string that can be set in the game dashboard (string) 
    setEndTimeUnix, //game set latest end time in unix time
    participants: 
    [    //array of "team" arrays (so it's array of arrays)
        [        //Each team has array of participants, which in turn contains:
            {
                playerId, //escs player id (string) 
                ingamePlayerId, //registered in-game player id via registerInGamePlayerId (string) 
                username, //user's escs username (string) 
                firstName, //user's escs first name (string) 
                lastName, // user's escs last name (string) 
                avatar, // user's escs avatar image url (string) 
                ingameMetadata // in-game metadata that was registered via RegisterInGamePlayerId (string)
            },
        //... more participants, if any
        ],
    //... more teams, if any
    ]
}

More explanation on participants array of arrays: Each sub-array is considered a "team". So if the game is 2vs2, then you will get array of 2 arrays, each having 2 objects inside. Those 2 arrays are 2 teams with 2 players each. In case of 1vs1 game, you will receive an array of 2 arrays, each having 1 object inside - thus each team contains only one player.

Register OnGameSetEnd event callback

service.registerGameSetEndCallback( async payload => {
    console.log("setEndCallback", payload) 
})

where payload object contains fields:

{
    setId,     // setId of finished set (string) 
    matchId     // matchId of the set (string)
}

Register OnMatchStart event callback

service.registerMatchStartCallback( payload => {
    console.log("matchStartCallback", payload) 
})

where payload object contains fields:

{
    matchId // matchId of the match that started (string)
}

Register OnMatchEnd event callback

service.registerMatchEndCallback( payload => {
    console.log("matchEndCallback", payload) 
})

where payload object contains fields:

{
    matchId // matchId of the match that has ended (string)
}

OAuth integration

  1. Create the OAuth app as described here: Using escs OAuth for sign in

  2. Implement the callback to send the access token to escs as described below.

Supporting user login using the game account (OAuth-like)

You can use our option for user game profile integration and allow your users to log in to our system without requiring them to manually create an escs account. Then the user will see an additional button "log in using %game_name% account" on the main escs screen. In order to support this, first, you need to follow the required steps in the client dashboard and set up the necessary fields as described in the corresponding docs section: Using escs OAuth for sign in. Note that you will also need to create an additional endpoint in your game's backend for the account system for verifying tokens. After this you will only need to implement one callback in your game:

service.setOnRequestGameUserProfilePermissions((options, respond) => {
    console.log("[GAME LOG] onRequestGameUserProfilePermissions", options)
    respond( 
        'yourAccessToken',
        ['profile', 'email'] //or any of the requested options
    )
})

where

  • options- list of requested profile permissions (string), for example ["email", "id"]

  • respond- a function that is used to respond to this profile permissions request; you may want to ask the user to accept the requested permissions list in a dialog, or allow them to select only some of them; such dialog, if any, you should be created and presented to the user by yourself; when the user responds to it, you can use respond function to send user's choices to escs:

    • yourAccessToken - user access token, which will be used by escs backend to obtain profile information from your game's backend (string)

    • ['profile', 'email'] - here you supply permissions that the user accepted, if any (array of strings). The permission strings should correspond to those that you have received in the options list

Deeplink integration allows you to process ESCS-related deeplinks in your app. We provide wagers integration, and for them to work this step is required.

In case of web application, the "deeplink" becomes just normal (i.e. http) link to your game, but with additional parameter, i.e.: https://yourgame.com/some/path/?escsplayer=%escs-specific-urlencoded-part%. So when creating a link for tournaments/wagers inside your game, ESCS will just append the "?escsplayer=" parameter to the url you have entered in escs dev console in your app settings.

In the field you should enter something like https://yourgame.com/some/path - where the path is any path for your web application. After this setup, you can use

escsService.followDeeplink( string ) 

method to pass the value of url parameter called "escsplayer" (%escs-specific-urlencoded-part% in the example above). How you extract the parameter value from the url is left to your game's implementation detail, but that should be fairly easy. You can provide it in urlencoded format, i.e. raw string that is passed in escsplayer param, escs will decode it correctly. This will trigger escs service to process that deeplink and automatically show relevant info in our overlay. If the user decides to take action with shown info, your game will receive the data about the match it needs to create using our standard APIs described in previous sections (i.e. OnGameSetStart and other relevant callbacks) and no additional implementation is required

Last updated