PlayPad compatible lobby integration guide
For asynchronous games with tournaments
Lobby scene UI contents
Example arrangement of lobby scene required contents
- 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)
- Game logo
- Tournament title - from the
TournamentInfo
Switch Tournament
button- (logic handled by PlayPad) shows the selection process of tournaments that the user can enter in an over-game UI
- should be near the tournament title
- should be represented by a custom icon (without text)
- as a clickable button it should be green to encourage user activity
- Time left to close the tournament (custom icon is recommended)
- Number of participants in the tournament (custom icon is recommended)
Tournament Rewards
button- (logic handled by PlayPad) displays the current Tournament Rewards in an over-game UI
- should display short prize pool summary message
- should be represented by a custom icon
- as a clickable button it should be green to encourage user activity
- 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. ". . .")
- All time high score of the player
- 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 gameplayUserActionRequired
(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
andPlayPad
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.
- with 3 possible, distinguishable states to inform the user of playing possibility:
- Authentication in progress waiting panel
- Match loading waiting panel
- 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)
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.
For randomization, when the tournament is not default (TournamentInfo.OwnerId
is not null), you should derive the seed from TournamentInfo.Id.GetHashCode()
to keep the tournament challenge uniform between all the contestants.
For default, daily ones it is best to use full randomization to make the game more surprising, fun and engaging.
Custom migration
-
Update
Elympics SDK
to at least0.14.2
-
Update
PlayPad SDK
(formerly known asElympics Lobby Package
orElympics External Communicator
) to at least1.1.1
-
Rename all occurrences of
ElympicsExternalCommunicator
toPlayPadCommunicator
-
Delete
SessionManager.TryReAuthenticateIfWalletChanged
orSessionManager.TryReAuthenticateIfAuthDataChanged
usages -
Delete
GameFinished
usage when finishing the Gameplay -
Delete
OnWalletConnectedChanged
usages -
Go through all the compile errors and using IDE try auto-resolving missing
using
directives (and delete non-existent ones) -
Remove the Player Info Bar from the menu scene entirely (both UI and code)
-
Remove the Connect Wallet button from the menu (both UI and code)
-
Remove all the code responsible for fetching and updating the Leaderboard (UI should not be removed)
-
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)
-
Remove all the logic that selects the matchmaking queue based on the context (only one solo queue is needed now)
-
If any compile error remains, it is recommended to delete the line causing it and message us about the occurrence on our developers' Discord
-
Ensure you have the
PlayPadCommunicator
prefab on your lobby scene and provide references to standalone configs for itsPlayPadCommunicator
script. To create them go to the Project context menu, then Create->Configs->Standalone. You can also delete the oldStandaloneBrowserJsConfig
ScriptableObject, which is no longer used -
Ensure that
ElympicsLobbyClient
'sAuthenticateOnAwakeWith
is set toNone
-
On
Start
, find theSessionManager
game object and call a method connecting to the PlayPad (but only once per game application launch) and adjusting lobby UI with provided dataprivate 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
-
To show "Authentication waiting panel" correctly, before
ConnectedWithPlayPad
if statement, subscribe to the events below. Remember to unsubscribe if destroying the subscribing objectsessionManager.StartSessionInfoUpdate += ShowAuthenticationWaitingPanel;
sessionManager.FinishSessionInfoUpdate += HideAuthenticationWaitingPanel; -
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 afterAuthenticateFromExternalAndConnect
) - 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)
- use
-
Use
PlayPadCommunicator.Instance.TournamentCommunicator
to set up tournament UI- use
.CurrentTournament
to access the tournament's data like its name, start, and end dates, and more (available afterAuthenticateFromExternalAndConnect
) - 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)
- use
-
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 afterAuthenticateFromExternalAndConnect
) - 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)
- use
-
PlayButton should:
- call
PlayPadCommunicator.Instance.GameStatusCommunicator.PlayGame()
upon click (note thatPlayGameConfig
'sQueueName
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
infoPlayPad 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) - call
-
Tournament Rewards button should call
PlayPadCommunicator.Instance.ExternalUiCommunicator.Display("tournament/rewards")
. It is async and becomes complete after closing the corresponding over-game UI -
Switch Tournament button should call
PlayPadCommunicator.Instance.ExternalUiCommunicator.Display("tournament/change-view")
It is async and becomes complete after closing the corresponding over-game UI -
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 afterAuthenticateFromExternalAndConnect
) - 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)
- use
-
If you use randomization and the tournament is not default (
TournamentInfo.OwnerId
is not null), you should derive the seed fromTournamentInfo.Id.GetHashCode()
to keep the tournament challenge uniform between all the contestants.