Skip to main content

PlayPad compatible lobby integration guide

For asynchronous games with tournaments

Lobby scene UI contents

PlayPad lobby scene mockup
Mockup of a lobby scene containing all the required elements

Important

It is important to preserve the UX suggested in the mockup, but remember that the UI and its arrangement can be way more flexible. You should provide your own UI design befitting your game style and needs. Be creative! You don't want your game menu to look like a copy-paste of many other titles, don't you?

  1. Free space at the top of the canvas - for PlayPad provided player info panel
    • about 7~8% of canvas vertical space (140 units with 1920 units high canvas)
  2. Game logo
  3. Tournament title - from the TournamentInfo
  4. Switch Tournament clickable UI element
    • on click, sends message to the PlayPad to show the selection view of accessible tournaments for the user in an over-game UI
    • should be near the tournament title
    • should be represented by a custom icon (without text)
    • as a clickable element it should encourage user's activity
  5. Time left to close the tournament (custom icon is recommended)
  6. Number of participants in the tournament (custom icon is recommended)
  7. Prize Pool subsection
    • should contain a clickable element represented by a custom "info" icon:
      • on click, sends message to the PlayPad to display detailed rewards info for the current tournament in an over-game UI
      • as a clickable element it should encourage user's activity
    • should display TournamentInfo.PrizePool:
      • its format is icon then text value
      • if null - display no icon and "Fame & Glory" text
      • received Image can be null - in such a case no icon should be displayed
      • if Amount is 0, set text value as DisplayName, else as Amount - this is in case the prize is of an uncountable type, such as "Undisclosed" or "Fame & Glory"
  8. Leaderboard
    • should be able to display from 0 to 6 entries (you should always have 6 slots ready to display, but depending on the received data, not all of them may be shown)
    • should display all the received entries (you won't receive more than 6)
    • entries are in ascending position order but may not be consecutive (e.g. 1, 2, 3, 25, 26, 27) - received entries are determined by PlayPad
    • if adjacent entries are not consecutive, a visual separator should be displayed between them (e.g. ". . .")
  9. All time high score of the player
  10. Play button - adjusted visually to tournament play availability, with displayed proper info label
    • with 3 possible, distinguishable states to inform the user of playing possibility:
      • Play (i.e. green) – gameplay is possible, pressing play will proceed directly, or almost directly to the gameplay
      • UserActionRequired (i.e. blue) – gameplay is possible but requires some long-lasting action that can be handled by the PlayPad (like signing in via wallet, confirming a transaction, buying entries, etc.)
      • Blocked (non-interactable button) (i.e. grey) – gameplay is not possible, and it is not fixable (the tournament is already finished, or it requires some NFT that the user does not have and cannot buy directly, etc.) with exception of the case when the tournament has not yet started
    • remember that you only should have one Play button and its state should only be determined by the most recent PlayStatusInfo you received. PlayPad SDK and PlayPad are fully responsible for handling the logic of what's behind this button, so you don't have to implement any blockchain or tournament-specific logic.
  11. Authentication in progress waiting panel
  12. Match loading waiting panel
  13. Error displaying panel - for handling unsuccessful user action resolving (i.e. canceling wallet sign) and edge cases (i.e. tournament ended when a player was resolving needed external actions)

UI examples

PlayPad lobby scene example
Example from the AsyncGameSample

Gameplay scene adjustments

  1. If you use randomization, you should make it deterministic for a tournament to ensure fairness and keeping the challenge uniform between all the contestants. For that use IServerHandlerGuid to receive InitialMatchPlayerDatasGuid, then derive the seed from initialMatchPlayerDatas.CustomMatchmakingData.TryGetValue(TournamentConst.TournamentIdKey, out var tournamentId) and tournamentId.GetHashCode().
    If it is not available (like in the Editor), randomize the seed the same way as previously.
    Please note that providing unexistent tournament id for the match will prevent it from starting.

  2. Find RttReporter prefab and put it in your scene to ensure connection quality tracking.

Migration from 0.4.5 to 1.1.1

Using AsyncGameSample

As the scope of migration may be quite broad, it is recommended to use the sample in place of your old, manual lobby integration. With that, you can just focus on implementing your graphics according to your design without needing to worry about technical details.

Custom migration

  1. Update Elympics SDK to at least 0.14.2

  2. Update PlayPad SDK (formerly known as Elympics Lobby Package or Elympics External Communicator) to at least 1.1.1

  3. Rename all occurrences of ElympicsExternalCommunicator to PlayPadCommunicator

  4. Delete SessionManager.TryReAuthenticateIfWalletChanged or SessionManager.TryReAuthenticateIfAuthDataChanged usages

  5. Delete GameFinished usage when finishing the Gameplay

  6. Delete OnWalletConnectedChanged usages

  7. Go through all the compile errors and using IDE try auto-resolving missing using directives (and delete non-existent ones)

  8. Remove the Player Info Bar from the menu scene entirely (both UI and code)

  9. Remove the Connect Wallet button from the menu (both UI and code)

  10. Remove all the code responsible for fetching and updating the Leaderboard (UI should not be removed)

  11. Remove all the logic that adjusts the "Play button" state based on the context (like setting it to "Train" when the user is not logged in)

  12. Remove all the logic that selects the matchmaking queue based on the context (only one solo queue is needed now)

  13. If any compile error remains, it is recommended to delete the line causing it and message us about the occurrence on our developers' Discord

  14. Ensure you have the PlayPadCommunicator prefab on your lobby scene and provide references to standalone configs for its PlayPadCommunicator script. To create them go to the Project context menu, then Create->Configs->Standalone. You can also delete the old StandaloneBrowserJsConfig ScriptableObject, which is no longer used

  15. Ensure that ElympicsLobbyClient's AuthenticateOnAwakeWith is set to None

  16. On Start, find the SessionManager game object and call a method connecting to the PlayPad (but only once per game application launch) and adjusting lobby UI with provided data

    private void Start()
    {
    var sessionManager = FindObjectOfType<SessionManager>();
    OnLobbySceneLoaded(sessionManager).Forget();
    }

    private async UniTask OnLobbySceneLoaded(SessionManager sessionManager)
    {
    bool shouldHideSplashScreen = false;

    if (!sessionManager.ConnectedWithPlayPad)
    {
    await sessionManager.AuthenticateFromExternalAndConnect();
    shouldHideSplashScreen = true;
    }

    // Put here any further lobby scene configuration and UI adjustments
    . . .

    if (shouldHideSplashScreen)
    PlayPadCommunicator.Instance.GameStatusCommunicator?.HideSplashScreen();
    }

After these changes and uploading the server build you should be able to play the game now without errors. If that's not the case, please contact us on our developers' Discord.

Implementing lobby scene features
  1. To show "Authentication waiting panel" correctly, before ConnectedWithPlayPad if statement, subscribe to the events below. Remember to unsubscribe if destroying the subscribing object

    sessionManager.StartSessionInfoUpdate += ShowAuthenticationWaitingPanel;
    sessionManager.FinishSessionInfoUpdate += HideAuthenticationWaitingPanel;
  2. Use PlayPadCommunicator.Instance.LeaderboardCommunicator to set up the leaderboard UI

    • use .Leaderboard to access the leaderboard's entries, player's entry, and number of participants to display (available after AuthenticateFromExternalAndConnect)
    • use .LeaderboardUpdated event to get notified when PlayPad's leaderboard data gets updated (after leaving the gameplay scene) then adjust to it
    • [optional] use .FetchLeaderboard() to manually fetch the most recent leaderboard results from the PlayPad (meant for custom usage)
  3. Use PlayPadCommunicator.Instance.TournamentCommunicator to set up tournament UI

    • use .CurrentTournament to access the tournament's data like its name, time scope, PrizePool, and more (available after AuthenticateFromExternalAndConnect)
    • use .TournamentUpdated event to get notified when PlayPad's tournament data gets changed then adjust to it
    • [optional] use .GetTournament() to manually fetch current tournament data from the PlayPad (meant for custom usage)
  4. Use PlayPadCommunicator.Instance.GameStatusCommunicator to set up play button visuals, availability, and functionality

    • use .CurrentPlayStatus to access the tournament's play availability status and short text to put on the button label (available after AuthenticateFromExternalAndConnect)
    • use .PlayStatusUpdated event to get notified when tournament play availability changes then adjust to it
    • use .PlayGame(...) to load a match and run the gameplay
    • [optional] use .CanPlayGame(false) to manually fetch current play availability data from the PlayPad (meant for custom usage)
  5. PlayButton should:

    • call PlayPadCommunicator.Instance.GameStatusCommunicator.PlayGame() upon click (note that PlayGameConfig's QueueName parameter is the only mandatory one)
    • try..catch around the call to handle and display potential issues
    • display match loading screen upon click (and hide it on an error)
    • change visually according to the PlayStatus
    • be non-interactable when in a Blocked state
    • use LabelInfo as displayed text
    info

    PlayPad SDK & PlayPad will take care of all the context-dependent requirements that the player has to meet to proceed with the gameplay. Corresponding UI will be displayed over your game (similar to how In-App Purchase UI could be displayed over your game in an iOS environment). So you don't have to care about what the user is doing with our (PlayPad) UI, but instead, you will be delivered a final result (which is proceeding to the game or failing with an error code)

  6. Tournament Rewards button should call PlayPadCommunicator.Instance.ExternalUiCommunicator.Display("tournament/rewards"). It is async and becomes complete after closing the corresponding over-game UI

  7. Switch Tournament button should call PlayPadCommunicator.Instance.ExternalUiCommunicator.Display("tournaments/listing") It is async and becomes complete after closing the corresponding over-game UI

  8. Use PlayPadCommunicator.Instance.LeaderboardCommunicator to set up the player's all-time high score

    • use .UserHighScore to access the player's all-time best score (available after AuthenticateFromExternalAndConnect)
    • use .UserHighScoreUpdated event to get notified when PlayPad's best score data gets updated (after leaving the gameplay scene) then adjust to it
    • [optional] use .FetchUserHighScore() to force fetch the most recent all-time best score (meant for custom usage)