Skip to main content

PlayPad SDK integration guide

For asynchronous games with tournaments

To see lobby & PlayPad SDK integration requirements see the corresponding article.

Using AsyncGameSample

The main route for integrating PlayPad SDK with your Elympics game is to use AsyncGameSample. It comes with already functional lobby scene and prefabs for streamlined gameplay integration.

Initial setup

Running the sample in the Editor for the first time (already done steps can be skipped):

  1. Update Elympics SDK to the newest version.
  2. Install PlayPad SDK or update it to the newest version.
  3. Import the sample.
  4. Import TextMeshPro essentials (Window > TextMeshPro > Import TMP Essential Resources).
  5. Add new scenes to the build settings.
  6. Add the attached ElympicsGameConfig asset to the list in the "Manage games in Elympics" window (Tools > Elympics > Manage games in Elympics) and choose it as the active game.
    Known bug

    There is a bug that won't allow developer to add an ElympicsGameConfig to the list manually. To do so, please delete ElympicsConfig and recreate it using Manage games in Elympics view like when starting your project.

  7. Starting from the lobby scene, test if the setup works correctly.

Connecting your own gameplay to the sample lobby

  1. In the console, create a queue named solo (of Solo type). Alternatively, change the value of the playQueue field in the TournamentPlayButton component to your pre-existing Solo-type queue name.

  2. Select your own game as the active one in Manage games in Elympics view. Also remember that your gameplay scene has to be added in the build settings.

  3. For gameplay scene integration, use the GameplayNetworkManager prefab:

    • GenericServerHandler component is responsible for determining the initial randomization seed, starting the game, and handling client disconnections on the server side
      • [mandatory action]: remove conflicting DefaultServerHandler script from Elympics GameObject (or if you have your own one, merge the functionality so only one remains)
      • [optional]: use GameJustStarted event to start the gameplay logic at the server and client at the same time, while being sure that randomization seed is already synchronized
      • [optional]: provide and reference your own implementation of randomization system deriving from SynchronizedRandomizerBase (you can remove ExampleSynchronizedRandomizer component afterwards)
      • [optional]: if your game is developed in a way allowing for rejoining a match after leaving and you want to enable such feature, change AutoTerminationOnLeft to None and utilize PlayerRejoined_ClientCallIncluded and PlayerDisconnected_ServerOnly events to handle game's behaviour
    • MatchEnder component is used for proper results uploading, including mid-game disconnection handling
      • [mandatory action]: make your score system derive from ScoreProviderBase and reference it
      • [mandatory action]: use to end the game according to your game's rules
      • [optional]: adjust the configuration for 0 score matches to be treated as not played ones (returning the social tournament tickets)
    • MatchConnectionHandler component is responsible for client-side errors and temporary disconnections handling; it also hides persistent MatchConnectingMask on OnConnected event (if it exists)
      • [mandatory action]: add and reference a UI object with the MatchDisconnectionMask component attached to display the errors (you can use the DisconnectionMask prefab for that)

It should be working properly now, but you still should ensure smooth updating experience and customize the lobby design.

Ensuring smooth updates

Copy the lobby scene from the sample (remember to add it to the build settings!) and do not use the imported one. Any other files you are willing to modify should also be copied with the exception of prefabs, which should be made into variants.

warning

Although using these directly from Samples directory may be possible, it is not recommended as updating the package (and reimporting the sample) would erase your changes.

Customizing the lobby scene

Your lobby is now ready to embrace your creativity regarding the design and functionality! 🎨

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?

Manual integration

warning

This approach is not recommended as it is error-prone and requires high workload. In most cases, you should use the AsyncGameSample instead.

  1. Add the PlayPadCommunicator prefab to your lobby scene and provide references to standalone configs inside its PlayPadCommunicator component. To create the configs, go to the Project context menu, then Create > Configs > Standalone.

  2. Ensure that ElympicsLobbyClient.AuthenticateOnAwakeWith is set to None.

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

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

    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();
    }
  4. Ensure that all the requirements are fulfilled. Use PlayPadCommunicator and SessionManager to implement the following logic:

    • The Tournament Rewards button should call the PlayPadCommunicator.Instance.ExternalUiCommunicator.DisplayTournamentRewards method. It is asynchronous and becomes complete after closing the corresponding over-game UI.

    • The Switch Tournament button should call the PlayPadCommunicator.Instance.ExternalUiCommunicator.DisplayTournamentsListing method. It is asynchronous and becomes complete after closing the corresponding over-game UI.

    • Use the PlayPadCommunicator.Instance.LeaderboardCommunicator field to set up the leaderboard UI:

      • read the Leaderboard property to get all the leaderboard entries, the local player's entry, and the number of participants to display (available after the AuthenticateFromExternalAndConnect method finishes)
      • subscribe to the LeaderboardUpdated event to get notified when the PlayPad leaderboard data gets updated and refresh the UI accordingly (raised after leaving the gameplay scene)
      • [optional] call the FetchLeaderboard method to manually fetch the most recent leaderboard results from PlayPad
    • Use the PlayPadCommunicator.Instance.TournamentCommunicator field to set up social tournament UI:

      • read the CurrentTournament property to get the tournament's data like its name, time scope, PrizePool, and more (available after the AuthenticateFromExternalAndConnect method finishes)
      • subscribe to the TournamentUpdated event to get notified when the PlayPad social tournament data gets changed and update the UI accordingly
      • [optional] call the GetTournament method to manually fetch current social tournament data from PlayPad
    • Use the PlayPadCommunicator.Instance.GameStatusCommunicator field to set up play button visuals, availability, and functionality:

      • read the CurrentPlayStatus property to get the tournament's play availability status and short text to put on the button label (available after the AuthenticateFromExternalAndConnect method is finished)
      • subscribe to the PlayStatusUpdated event to get notified when the tournament's play availability changes and update the UI accordingly
      • call the PlayGame method to load a match and run the gameplay
      • [optional] call CanPlayGame(false) to manually fetch current play availability data from PlayPad
    • PlayButton should:

      • call the PlayPadCommunicator.Instance.GameStatusCommunicator.PlayGame method upon click (note that the PlayGameConfig.QueueName field is the only mandatory one)
      • catch and handle any exceptions thrown by the PlayGame method, displaying errors in UI when necessary
      • display a loading screen upon click (and hide it in case of an exception)
      • change visuals according to PlayStatus
      • remain non-interactable in the Blocked state
      • use LabelInfo as displayed text
      info

      PlayPad SDK and 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 is displayed over your game in the iOS environment), so you don't have to worry about what the user is doing with our (PlayPad's) UI, but instead you will be delivered a final result (that is loading the game scene or failing with an error code).

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

      • read the UserHighScore property to get the player's all-time best score (available after the AuthenticateFromExternalAndConnect method finishes)
      • subscribe to the UserHighScoreUpdated event to get notified when the best score data retrieved from PlayPad changes and update the UI accordingly (raised after leaving the gameplay scene)
      • [optional] call the FetchUserHighScore method to force fetching the most recent all-time best score

Playing outside the Editor

To learn how to run your build online, see the corresponding article.