Skip to main content

Asynchronous game

What does it mean?

Asynchronous games are meant to be playable solo, where players compete for the highest score in the leaderboards. Although such games are basically single-player in their nature, client-server architecture we require is mandatory, as the server fills the role of an anti-cheat mechanism needed for secure and reliable match results gathering. With such confidence in our data, real competitiveness with the money on stake can be provided.

note

At the moment Web3 integration for such games is supported only for WebGL but works both on mobile and desktop browsers as well as on Telegram.

Meta-requirements of Elympics SDK integration

  1. In case you are not experienced with Elympics SDK, learn how to use it by checking:
warning

In many places we mention usage of the developer “Panel” which has been recently remade as the Developer Console. You could also use CLI instead.

  1. If you are integrating Elympics SDK to an already finished game, please note that some major gameplay design changes may be required in order for the game to fit our match-based, competitive and replayable experience needs. Most commonly it means random generation of content (obstacles / puzzles / etc.) using some starting seed, scoring based on player’s performance (which must be optimised around lowest probability of two players getting the same result and thus drawing) and limited time.

  2. It is best to work with a version control system from the beginning for easier code development and smoother support if needed. We recommend using git with Github or Gitlab. Do not forget to include proper .gitignore file.

Technical setup and requirements checklist

  1. Unity Editor version must be 2021.3.5f.1 or higher (but we do not necessarily recommend using versions 2023+ with our SDK)

  2. Remember that your game must work properly in WebGL. Take note about its limitations and be careful not to use WebGL incompatible code or assets (for example some shaders won’t work).

  3. Be sure to check “Use HTTPS/WebRTC” in your game’s ElympicsConfig in order to make Elympics SDK work with WebGL.
    WebRTC setting

warning

There is a bug, that when building to WebGL this checkbox is set automatically, but it doesn’t really work. In such case you have to check it when using another build target, be sure to save, upload new server build and only then you can proceed with building on WebGL. You will see in a version control tool if the change occured properly.

  1. Although your game is targeted on WebGL, knowing that the game can run in a mobile browser, you should make it with mobile-first in mind:

    • the game orientation should be vertical (recommended 9:16)
    • UI should be displayed properly regardless of used device
    • proper mobile input must be provided
    • any interactive UI elements such as buttons have to be of appropriate size for comfortable use on small screens
    • UI should be guiding and intuitive
  2. Regardless, Desktop browsers (besides Firefox) should still be supported.

  3. In summary, the target platforms are moblile / Desktop browsers AND Telegram. To make integration with Web3 and Telegram possible, we provide the PlayPad which takes care of external communication. It itself must still communicate with the game, but makes it a lot easier and more reliable than raw "game to Web3" communication.

  4. Integration with the PlayPad is implemented in the lobby add-on package to the ElympicsSDK which you can add to your project by using Package Manager and Add package from git URL option.

warning

The package is inseparably tied to the PlayPad. Please note that because of that you won't be able to test the game using classic localhost (it results in an error). We provide another solution instead, available below.

  1. To host and test your WebGL build on our testing site containing the PlayPad, please follow instructions in the related article. Note that this site is meant only for development and internal testing and not for publication.

  2. To learn how to test using a Web3 Wallet refer to the corresponding article.

  3. The game integrating Elympics SDK can be divided into two major parts - lobby and gameplay.

    • At first, focus on integrating the gameplay part. Use HalfRemote mode for development and testing, as it works mostly like our target distribution which is local client and online server, with the client starting on a menu scene. In HalfRemote though, your main Unity instance is a server, and a Clone is the client (player). During any match you shouldn't interact with the server instance (unless you do that for debug purpose and you know what you are doing).
    • Lobby scene should use the forementioned add-on to Elympics SDK to ensure proper Web3 integration and authentication. Navigate below for more details. (Do not implement Web3 features by yourself or use External Game Backend like we did in our endless runner sample - use the package instead)
tip

Visit general development tips article if you want more insight into the topic of integrating gameplay with Elympics SDK.

  1. A match has to be ended using Elympics.EndGame(resultsData), where resultsData represents score gained by the player. Such score must be server authoritative.

  2. Gained respect for the match should be fetched and displayed after the game ends. Guests shouldn't display respect but "Connect wallet to earn respect" instead.

Respect technical aspects and requirements
  • There is no need or a way of displaying total respect - Player's Cockpit is meant for this.

  • Note that it won’t work in “HalfRemote” - use full flow starting from the lobby instead.

  • The match has to be ended using Elympics.EndGame(resultsData) on the server before fetching respect.

  • You have to provide some waiting indication, as fetching respect may take a few moments.

  • Here is a sample implementation of respect fetching (you can get the config by calling ElympicsConfig.Load()):

    private async void GetRespect(Guid matchId)
    {
    var respectService = new RespectService(ElympicsLobbyClient.Instance, config);
    var respectValue = await respectService.GetRespectForMatch(matchId);
    SetRespectUi(respectValue.Respect);
    }

You can access matchId by subscribing to ElympicsLobbyClient.Instance.RoomsManager.MatchDataReceived in the lobby scene and caching received parameter.

  1. The game shall have proper error handling implemented, not allowing the player to become lost without some important feedback that something went wrong, especially after losing connection to the Internet (Websocket disconnection).

  2. PlayPad provides an external loading screen for the time before the game fully loads and sends ApplicationInitialized message.

    In order to make it consistent with your game style, we will need some informations from your side, which you can provide by the Google Form distrubuted by our support team after notifying us that the game is finished:

    • game title sprite (same as the in-game one, "powered by Elympics" not mandatory)
    • background gradient hex colors (2)
    • target aspect ratio of your game
    • loading bar colors (2: foreground and background) (hex)
    • optionally additional image to put below the loading bar

    Loading screen layout

Lobby scene requirements and implementation guideline

UI requirements

When designing UI refer to the prototype. You can also use our Cut the Zero game as a loose reference. Note that your design doesn't need to match the prototype exactly. Some adjustments are acceptable.

note

Please note that the “Loading Screen” is not a part of the lobby scene. It is created and displayed outside of the game by the PlayPad before loading your game.

Respective UI elements are described below:

  1. button for starting the game, which changes in relation to the context like in the implementation guideline; please note that you have to configure proper (solo) queues in the Developer Console or CLI to be able to use them - named ”training”, “eth”, “telegram”
  2. match loading indication overlay active after clicking forementioned button, which blocks all actions in the lobby
  3. button "Connect wallet" - visible only in proper conditions explained in the implementation guideline
  4. "authentication in progress" indication which blocks all actions in the lobby, active when such action takes place (on game launch, after clicking “Connect wallet” button, on response to events)
  5. clickable player data view:
    • avatar placeholder
      avatar-placeholder.png
    • nickname text able to properly display longest name available for Elympics Cockpit - 15 "W" letters (player can set a nickname at Player's Cockpit)
    • simplified (shortened) wallet public key
  6. current leaderboard top x ranked people nicknames and scores:
    • if the player appears there, they should be highlighted
    • time scoped to starting at 01:00 UTC and ending at 23:59 UTC
    • in the time between leaderboards (00:00 - 00:59 UTC) previous one is shown, but note that no new records are added
    • queue scoped to: if Telegram is available in Capabilities then "telegram" and else "eth" - it means that on Telegram and in the browser leaderboards will differ and that is expected
  7. top score of the player scoped in the same way as the button for starting a match (note that guest has separate queue for playing and for displaying leaderboard - their results won't be shown in the leaderboard)
  8. remaining time to closing current leaderboard or time to the next leaderboard if showing previous one
  9. game logo (it is important for it to have the same size and be located in the same position as the logo used in the loading screen)
  10. error display for handling abnormal situations, especially losing connection (ElympicsLobbyClient.Instance.WebSocketSession.Disconnected event with Reason not equals ClientRequest or ApplicationShutdown)
  11. some instructions / controls / tutorial if needed
  12. optionally - number of people in the leaderboard
  13. any additional feature you find appealing

Implementation details

  1. Add Elympics Unity Lobby add-on to your project by using Package Manager and Add package from git URL.

  2. Put ExternalCommunicator prefab from the package on your first scene.

note

In runtime, this game object changes name to JsReceiver.

  1. Reference it as an ElympicsEthSigner for ElympicsLobbyClient game object.

  2. Provide Inspector references for ExternalCommunicator game object components, wheras SmartContractServiceConfig Scriptable Object should be copied from the package to your project locally to ensure proper version control tracking. Also provide ElympicsGameConfig reference for SmartContractServiceConfig (by default there is a missing reference).

  3. Set ElympicsLobbyClient.AuthenticateOnAwake in the inspector to None - you will connect to Elympics manually.

  4. After the game application launches, send message to the PlayPad to notify it that the game is ready and external loading screen can be turned off. Use this method only once per game application launch - it is up to the developer to restrict that. You can send the initial message by using ElympicsExternalCommunicator.Instance.GameStatusCommunicator.ApplicationInitialized().

  5. Anytime any authentication method is processed, input-blocking waiting indicator should be displayed to prevent a player from interfering with the process.

  6. Fetch the leaderboard and allow to play only when already authenticated and connected. If any authentication method is in progress, it should be awaited before such actions.

  7. On scene Start, if a player is not authenticated and connected already, access an object of SessionManager type and call and await its AuthenticateFromExternalAndConnect method. Do it inside of a method with UniTask return type and be sure to use Forget() on this call to be able to run such method correctly. It will take care of initial authentication process and provide some useful informations for further usage. Note that it is currently the only way to authenticate to Telegram.

    private void Start()
    {
    TryAuthenticateOnLobbySceneStartAndAdjustUi().Forget();
    }

    private async UniTask TryAuthenticateOnLobbySceneStartAndAdjustUi()
    {
    // Put described logic here
    }
tip

SessionManager gives you access, among others, to SessionInfo storing Capabilities, a Wallet address (SignWallet) and IsMobile info indicating accessed environment.

  1. A Guest (with a proper context you can see at point 12.) can connect Wallet using a button. For that, use and await SessionManager.ConnectToWallet method along with the input-blocking waiting indicator handling and further UI adjustments.

  2. The game should react and adjust lobby to any external actions available for the user in their Wallet. For that, such events are handled by the PlayPad and messaged to the game. The game receives them internally and provides Web3Wallet.WalletConnectionUpdated event for the developer to use. To reauthenticate on such event call SessionManager.TryReAuthenticateIfWalletChanged, but only when not during the gameplay or matchmaking (it is up to the developer to determine) - player cannot be changed when already in a match. Else - it should be skipped. To handle such cases later, Web3Wallet internally remembers last not yet executed event. The developer should call forementioned TryReAuthenticateIfWalletChanged every time after going back to the lobby scene to ensure execution of such cached event.

tip

To summarize authentication sources, in the context of UX there are three of them:

  1. At the launch of the game, after receiving initial message
  2. After receiving an event from the PlayPad
  3. After clicking “Connect Wallet” button by the user, potentially triggering forementioned events
  1. After any awaited authentication change, number of UI elements should be adjusted accordingly to the snippet below. Also leaderboards should be fetched anew, loading overlay hidden and play button unlocked. Please note that these variables still have to be applied to the corresponding UI elements.

    using Elympics;
    using Elympics.Models.Authentication;
    using ElympicsLobbyPackage.Session;
    using ElympicsLobbyPackage.Authorization;

    ...

    public void AdjustUiAfterAuthentication(SessionManager sessionManager)
    {
    // gathering info for further evaluation
    var capabilities = sessionManager.CurrentSession.Value.Capabilities;
    var currentAuthType = ElympicsLobbyClient.Instance.AuthData.AuthType;
    bool isGuest = currentAuthType is AuthType.ClientSecret or AuthType.None;

    // UI elements adjustments logic
    string playButtonText = isGuest ? "Train now" : "Play now";
    bool showPlayerDataView = !isGuest;
    bool showConnectToWalletButton = (capabilities.IsEth() || capabilities.IsTon()) && isGuest;

    // adjusting queues
    string leaderboardQueue = capabilities.IsTelegram() ? "telegram" : "eth";
    string playQueue = currentAuthType switch
    {
    AuthType.Telegram => "telegram",
    AuthType.EthAddress => "eth",
    _ => "training",
    };

    // applying data to UI
    ...
    }

    ...
  2. "Player data view" is clickable and such action should send ElympicsExternalCommunicator.Instance.WalletCommunicator.ExternalShowAccountInfo() message to the PlayPad.

  3. You can access nicknames in the leaderboard using LeaderboardEntry.Nickname (nicknames are settable in the cockpit.elympics.ai, there is no need to implement it yourself)

  4. For a logged player nickname use _sessionManager.CurrentSession.Value.AuthData.Nickname. Wallet address can be accessed by _sessionManager.CurrentSession.Value.AccountWallet property.

  5. For Editor testing purposes you can create some custom, mock implementations of interfaces to use with #if UNITY_EDITOR to manipulate the UI. To learn about testing using a Wallet refer to the corresponding article. Note that for more thorough testing uploading to PlayPad will be needed.

  6. Use ElympicsLobbyClient.Instance.RoomsManager.StartQuickMatch(playQueue) instead of PlayOnlineInRegion to start a match. While this method runs, display blocking loading indication. If an error occurs, display error screen and unlock inputs.

  7. When a match ends, client instance should call ElympicsExternalCommunicator.Instance.GameStatusCommunicator.GameFinished() with final score value as an argument. (It is important only for Telegram bot score display, it is only a visual and does not imply client authority.)