Set up Your Game for Play and Compare Gameplay
This article will walk you through setting up your game for Play and Compare gameplay on Skillz.
Implement Skillz Delegate
Control of your application is given to Skillz when you launch the Skillz UI. Because of this, the SDK provides a Skillz Delegate interface, which declares callbacks that will be invoked for key events. There are two callbacks that you must respond to: when a match begins, and when the Skillz UI is exiting (usually via the sidebar menu).
The examples below demonstrate how to respond to handle the start of a match, and when the Skillz UI is exiting. Check out the API Reference for information on optional callbacks.
In this example, the AppDelegate
class will implement SkillzDelegate
, which is declared in the Skillz/SKillz.h
header file.
#import <UIKit/UIKit.h>
#import <Skillz/Skillz.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, SkillzDelegate>
@end
Here, required SkillzDelegate
methods are implemented:
#import <Skillz/Skillz.h>
@implementation AppDelegate
- (void)tournamentWillBegin:(NSDictionary *)gameParameters
withMatchInfo:(SKZMatchInfo *)matchInfo
{
}
- (void)skillzWillExit
{
}
tournamentWillBegin:(NSDictionary *)gameParameters withMatchInfo:(SKZMatchInfo *)matchInfo
is called when a match is about to begin.
The first parameter, gameParameters
, is a dictionary that is passed in to this method by the Skillz framework, and contains parameters configured (from the Skillz Developer Console) for the specific match type that is starting. You can use these parameters to customize game behavior for specific tournaments.
matchInfo
, the second parameter, is a data structure that contains information about the current match and the player in it. The data contained within can be used to display information to players or to power external analytics.
skillzWillExit
is called when the Skillz UI is exiting. This usually happens when the player exits the UI from the sidebar menu.
In this example, the AppDelegate
class will implement SkillzDelegate
, which is imported from the Skillz
module.
import UIKit
import Skillz
class AppDelegate: UIResponder, UIApplicationDelegate, SkillzDelegate {
func tournamentWillBegin(_ gameParameters: [AnyHashable : Any]!, with matchInfo: SKZMatchInfo!) {
}
func skillzWillExit() {
}
}
tournamentWillBegin
is called when a match is about to begin.
The first parameter, gameParameters
, is a hash table that is passed in to this method by the Skillz framework, and contains parameters configured (from the Skillz Developer Console) for the specific match type that is starting. You can use these parameters to customize game behavior for specific tournaments.
matchInfo
, the second parameter, is a data structure that contains information about the current match and the player in it. The data contained within can be used to display information to players or to power external analytics.
skillzWillExit
is called when the Skillz UI is exiting. This usually happens when the player exits the UI from the sidebar menu.
The Skillz Delegate in the Android SDK is implemented by some meta-data tags that should have been added to your game's AndroidManifest.xml
file when the Skillz SDK was installed:
<application>
<meta-data android:name="skillz_game_activity" android:value="com.packagename.yourgameactivity" />
<meta-data android:name="skillz_allow_exit" android:value="true" />
<meta-data android:name="skillz_exit_activity" android:value="com.packagename.yourgameactivity" />
</application>
For skillz_game_activity
, set it's value to the fully qualified name of the Activity that represents your game's actual gameplay.
skillz_allow_exit
is a flag that allows you to enable/disable the player from exiting the Skillz UI from the sidebar menu. If set to true
, then you will need to provide a value for skillz_exit_activity
, which is the fully qualified name of an Activity to load when the Skillz UI exits. This usually would be an Activity that represents your game's start screen.
For Unity, you need to implement the SkillzMatchDelegate
interface as a regular C# class. This will be instantiated when launching Skillz later.
using SkillzSDK;
using UnityEngine;
using UnityEngine.SceneManagement;
public sealed class GameController : SkillzMatchDelegate
{
private const string GameSceneName = "Level1";
private const string StartMenuSceneName = "StartMenu";
public void OnMatchWillBegin(Match matchInfo)
{
// This method is called when a match is about to begin.
// Remember to load the scene that represents actual gameplay!
SceneManager.LoadScene(GameSceneName);
}
public void OnSkillzWillExit()
{
// This method is called when the Skillz UI is exiting.
// The user can exit it via the hamburger menu in the
// Skillz UI.
SceneManager.LoadScene(StartMenuSceneName);
}
}
The Skillz Delegate is located in the path relative to your Cordova game's location: plugins/skillz-crossplatform-cordova/www/SkillzDelegateCordova.js
. This assumes you have the Skillz Cordova SDK installed. The class looks like:
class SkillzDelegateCordova {
constructor() {
this.matchInfo = null;
}
// void
static OnMatchWillBegin(matchInfoString) {
// This block of code will be called when the user is about to begin a match.
// You can use this match object to instantiate variables in your game.
const matchInfoObject = JSON.parse(matchInfoString);
console.log(
'SkillzDelegateCordova: OnMatchWillBegin was called. Here is the match information: %s',
JSON.stringify(matchInfoObject)
);
this.matchInfo = matchInfoObject;
// Modify the DOM to display your game.
}
// void
static onSkillzWillExit() {
// This block of code will be called when the user exits out of the Skillz UI.
// Modify the DOM to display the desired 'screen' of your game. This will usually
// be the 'start' screen or something similar.
}
static getMatchInfo() {
return this.matchInfo;
}
}
new SkillzDelegateCordova();
Warning
Changes to this file can be lost easily by removing and re-adding the Skillz Cordova SDK. To mitigate this issue, it is recommended that you keep a copy of this file with your changes in a safe location in your project.
Handling Match Starts
When Skillz has launched, it will take control of your game by displaying its UI on top. Here, the user will eventually enter a match. When that happens, Skillz will notify the game. At this point, control will be given back to your game to launch the gameplay portion of its UI. The examples below illustrate how to do this.
#import "AppDelegate.h"
#import <Skillz/SkillzInstance.h>
@implementation AppDelegate
- (void)tournamentWillBegin:(NSDictionary *)gameParameters withMatchInfo:(SKZMatchInfo *)matchInfo
{
}
This example has an AppDelegate
class that has implemented the SkillzDelegate
protocol. The tournamentWillBegin:withMatchInfo:
method is called when the player's match is about to begin. Implement this method to navigate to the View/ViewController that represents the gameplay portion of your game.
Additionally, the gameParameters
parameter holds key value parameters of the specific type of tournament being played. These parameters are created by your in the Skillz Developer Console when defining the types of tournaments your game will support.
import UIKit
import Skillz
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, SkillzDelegate {
func tournamentWillBegin(_ gameParameters: [AnyHashable : Any]!, with matchInfo: SKZMatchInfo!) {
}
}
This example has an AppDelegate
class that has implemented the SkillzDelegate
protocol. The tournamentWillBegin
method is called when the player's match is about to begin. Implement this method to navigate to the View/ViewController that represents the gameplay portion of your game.
Additionally, the _ gameParameters
parameter holds key value parameters of the specific type of tournament being played. These parameters are created by your in the Skillz Developer Console when defining the types of tournaments your game will support.
As described in the example for launching Skillz, Skillz will launch the activity that you set for the skillz_game_activity
meta-data tag in your game's AndroidManifest.xml
file.
<meta-data android:name="skillz_game_activity" android:value="com.skillz.your.GameActivity" />
When your activity launches, we recommend that you call relevant methods of the Skillz
static class to retrieve tournament parameters, and match info. Refer to the API Reference for a list of the methods available.
In the example for launching Skillz, we implemented the SkillzMatchDelegate
interface. We'll now handle a match start. You will need to launch the scene representing your gameplay in the OnMatchWillBegin
method:
using UnityEngine;
public class GameController : SkillzMatchDelegate
{
public void OnMatchWillBegin(SkillzSDK.Match matchInfo)
{
// A match is about to being. Launch the appropriate scene for your game
SceneManager.LoadScene("GameplayScene");
}
}
For Cordova, the OnMatchWillBegin
method in plugins/skillz-crossplatform-cordova/www/SkillzDelegateCordova.js
needs to be implemented:
class SkillzDelegateCordova {
constructor() {
}
static OnMatchWillBegin(matchInfoString) {
const matchInfoObject = JSON.parse(matchInfoString);
const message = 'SkillzDelegateCordova: OnMatchWillBegin was called. Here is the match information: '.concat(
JSON.stringify(matchInfoObject)
);
this.matchInfo = matchInfoObject;
const gameRoot = document.getElementById('game-root');
gameRoot.style.visibility = 'visible';
}
}
new SkillzDelegateCordova();
In this example, the code has an element in the DOM whose id is game-root
. This element represents the gameplay portion of the Cordova game, so it is made visible.
Warning
Changes to this file can be lost easily by removing and re-adding the Skillz Cordova SDK. To mitigate this issue, it is recommended that you keep a copy of this file with your changes in a safe location in your project.
Report Final Score
Once a game is complete you should report the score and go back to the Skillz interface to see the match results.
[[Skillz skillzInstance] displayTournamentResultsWithScore: score withCompletion:^(void)
{
// Completion block
}];
Skillz.skillzInstance().displayTournamentResults(withScore: score) {
// Completion block
}
Skillz.reportScore(finishActivity(), score);
SkillzCrossPlatform.ReportFinalScore(score);
SkillzCordova.reportScore(score, gameId);
Aborting a Match
Aborting a match is an alternative to reporting the final score. When a player aborts a match, they have forfeited it to the opponent.
[[Skillz skillzInstance] notifyPlayerAbortWithCompletion:(^(void)
{
// Completion block
}];
Skillz.skillzInstance().notifyPlayerAbortWithCompletion() {
// Completion block
}
Skillz.abortMatch(abortActivity());
SkillzCrossPlatform.AbortMatch();
SkillzCordova.abortMatch(gameId);
Random Numbers and Fairness
NOTE
The Skillz random number generator ensures that each competitor receives the exact same number.
Random numbers can be essential to many different types of games. However, it also causes fairness concerns when playing in Skillz tournaments. In order to address the potential imbalance caused by random numbers, the Skillz API offers the SkillzRandom
class. SkillzRandom
has functions for integers including nextInt
, and nextInt(min, max)
. There are also SkillzRandom
methods for other data types, including nextBoolean
, nextDouble
, and nextBytes
, among others.
The function nextInt
returns a pseudo random number between 0 and RAND_MAX, while nextInt(min, max)
lets you specify your own range (min inclusive, max exclusive). The numbers returned by the SkillzRandom
methods are in the same sequence for each player in a match.
[Skillz getRandomNumber];
Skillz.getRandomNumber()
Skillz.getRandom().nextInt();
SkillzCrossPlatform.Random.Value();
SkillzCordova.getRandomNumber(function (randNumber) {
// Use randNumber inside the callback
});
Considerations
Please be aware that just because you use either of the Skillz random methods does not guarantee that all players will have an identical game experience. These methods can only ensure that players get the same sequence of random numbers. Over time the player’s decisions may diverge and the same random number will not be used in the same place.
There may be places where the random decision is trivial to the outcome of the game, or purely aesthetic; in that case we recommend you do not use the Skillz random methods to reduce the chances of making a different number of calls between players.
Ensure Players Cannot Obtain Advantages from Outside the Game
With the potential for real money to be awarded to one player or another, we’ll need to be certain that players won’t have any edge based on factors outside the tournament they are playing. Examples of this include items obtained from in-app purchases or bonuses gained from playing in single-player mode. This is highly specific to each individual game, but if there are any ways for players to obtain in-game bonuses these should be disabled when playing with Skillz.