Skip to main content

Scope and requirements of PlayPad SDK integration

For asynchronous games with tournaments

tip

All the following functionality can be easily achieved by importing the AsyncGameSample and using it as a base for PlayPad SDK integration.

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, do you?

Required elements:

  1. Free space at the top of the canvas - for PlayPad Island, which contains player info and takes about 7~8% of canvas vertical space (140 units with 1920 units high canvas)
  2. Game logo
  3. Tournament name synchronized with the TournamentInfo.Name field
  4. "Switch Tournament" clickable UI element:
    • on click, sends a message to PlayPad to show the selection view of tournaments accessible to the user in an over-game UI by calling the PlayPadCommunicator.Instance.ExternalUiCommunicator.DisplayTournamentsListing method
    • should be near the tournament title
    • should be represented by a custom icon (without text)
    • as a clickable element, it should encourage the user to click it
  5. Time left to close the tournament (note that the tournament can not only be ongoing, but also finished or not started yet)
  6. Number of participants in the tournament
  7. Prize Pool subsection
    • should contain a clickable element represented by a custom "info" icon:
      • on click, sends a message to the PlayPad to display detailed rewards info for the current tournament in an over-game UI by calling the PlayPadCommunicator.Instance.ExternalUiCommunicator.DisplayTournamentRewards method
      • as a clickable element, it should encourage the user to click it
    • should display the data from 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
      • set the text value to DisplayName if Amount is 0 and to Amount otherwise - 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 not all of them may be shown depending on the received data)
    • should display all the received entries (you won't receive more than 6)
    • entries are sorted by position in the ascending 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 a proper info label:
    • in 3 distinguishable variants to inform the user of playing possibility:
      • Play (i.e. green) – gameplay is possible, pressing play will proceed to the gameplay scene (almost) directly
      • UserActionRequired (i.e. blue) – gameplay is possible, but entering it 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 nothing can be done about it (the tournament has not started yet or is already finished, or it requires some NFT that the user does not have and cannot buy directly, etc.)
    • if the current tournament is competitive (with real money at stake), additionaly a "Train" button should be displayed, allowing the player to learn how to play the game, without having to use a ticket for entry
    • note that there is only 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 what happens after clicking 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 (i.e. canceling wallet sign, matchmaking errors, websockets disconnection) and edge cases (i.e. tournament ended while the player was resolving required external actions)

UI examples

PlayPad lobby scene example
Example from the AsyncGameSample

PlayPad lobby scene example
Example from Cut the Zero

Example from Sweet Rush showcasing different tournament types and play states (Note: "The debug console is not present in production")

Gameplay scene adjustments

tip

The simplest and the most errorproof way of implementing the following features is using GameplayNetworkManager prefab from the sample and setting it up accordingly.

  1. If you use randomization, you should make it deterministic for a tournament to ensure fairness and uniformness of the challenge between all the contestants. For that purpose, you can implement IServerHandlerGuid.OnServerInit to receive InitialMatchPlayerDatasGuid, then derive the seed from InitialMatchPlayerDatasGuid.CustomMatchmakingData.TryGetValue(TournamentConst.TournamentIdKey, out var tournamentId) and tournamentId.GetHashCode().
    If it is not available (like in the Editor), randomize the seed in the usual manner.
    Please note that providing a nonexistent tournament ID for a match will prevent it from starting.
  2. Provide error handling for the gameplay connection in case of any issues (e.g. player temporarily losing connection to the server). For reference, check MatchConnectionHandler from AsyncGameSample.
  3. Make the Match loading waiting panel persist after entering the gameplay scene and hide it after receiving the IClientHandlerGuid.OnConnected callback.
  4. If the player leaves (or loses connection entirely) before the match is concluded, the server should either call EndGame with current score of the player or wait for the player to rejoin (with some timeout).
  5. If game's design interprets 0 score as not participating in the match, null result can be send instead to return the tournament ticket. It is a good way to compensate for potential Internet connection issues.
caution

You should never use Elympics.Disconnect() as it disrupts player's experience. The server disconnects the client on its own after the match is completed, so just leave handling it to Elympics systems.