Releases: skillz/skillz-example-sync-server
Skillz Example Sync Server
About Gradle & Updating the Sync Server SDK in Your Project
This example project uses Gradle to pull the Sync Server SDK Library Jar File from GitHub packages. When building with Gradle, the Sync Server SDK will be pulled and updated as defined here: https://github.com/skillz/skillz-example-sync-server/blob/master/build.gradle#L41
To change the Sync Server SDK's library version in your project, modify the version: 1.4.+
string in the aforementioned build.gradle
file accordingly. Note that a version of 1.4.+
will take the most recent patch version of 1.4.x
(at the time of writing, this is 1.4.4
).
Ephemeral Deployments
Setting IS_EPHEMERAL
to true
(the default) will configure the sync server to shut down after a single match has been played to completion. This enables deploying on the Skillz platform in "ephemeral" deployments.
@Slf4j
@CompileStatic
class ExampleSkillzGame extends Game<Player> {
...
public static final boolean IS_EPHEMERAL = true
...
Skillz Example Sync Server v1.4.0
What's Changed
- [PS-59099] Allow configuring forfeit integer score value, allow configuring aborts on disconnect/timeout/paused-too-long, bump version to
1.4.0
by @jgoldin-skillz in #5
Full Changelog: v1.3.4...v1.4.0
New Configuration Variables
The following variables are now available for configuration in your custom Game
class, see below for an example.
Setting ABORT_ON_DISCONNECT
to true
will configure the sync server to report an Abort when a player pauses for too long or disconnects during gameplay. If this variable is set to false
, the player will be forfeited instead (their score will be submitted using the default FORFEIT_SCORE_VALUE
value configured, see below).
FORFEIT_SCORE_VALUE
is the default score submitted for a given player when they forfeit.
@Slf4j
@CompileStatic
class ExampleSkillzGame extends Game<Player> {
...
public static final boolean ABORT_ON_DISCONNECT = true
public static final int FORFEIT_SCORE_VALUE = 0
...
Skillz Example Sync Server v1.3.4
What's Changed
- [PS-56329] Send down forfeiting/aborting player on MatchOver by @jgoldin-skillz in #4
Full Changelog: v1.3.1...v1.3.4
Skillz Example Sync Server v1.3.1
Changelog
- Added Dockerfile
- Added Gradle task which exports a Docker Image Archive to
./build/docker
- Added
healthcheck.sh
script to improve server health monitoring on the Skillz platform - Allow configuration of disconnect/reconnect/pause/resume limits and thresholds via reflection (values of -1 will disable the MAX_ thresholds), defaults shown here:
public static int WARNING_SECONDS = 4 public static int DISCONNECT_SECONDS = 31 public static int MAX_RECONNECTS = 7 public static int MAX_ALLOWED_APP_PAUSES = 4 public static int MAX_ALLOWED_APP_CONNECTION_WARNINGS = 7 public static int MIN_TIME_IN_SECONDS_FOR_NEW_PAUSE = 1 public static boolean USE_CUMULATIVE_PAUSE_DISCONNECT_TIMER = true
- Allow use of cumulative pause/disconnect timer
- Rename SERVER_ variables to remove redundant prefix
- Added ability to load Matchmaker keys from ENV variables
- Update Sync Server SDK to
v1.3.1
- Miscellaneous bug fixes
Upgrading Existing Projects
- Ensure your server-module level
build.gradle
(<project_root>/<server_name>/build.gradle
) takes the following change:
task exportDockerImageArchive(type: Exec) {
dependsOn('jar')
commandLine 'sh', '-c', 'rm -rf build/docker && mkdir -p build/docker/source && cp build/libs/' + project.name + '.jar build/docker/source/server.jar && cp ../Dockerfile build/docker/source/. && cp ../healthcheck.sh build/docker/source/. && cd build/docker/source && /usr/local/bin/docker build -t ' + project.name + ' . && /usr/local/bin/docker save -o ../' + project.name + '_`date +%m.%d.%Y`.tar ' + project.name + ' && cd .. && rm -rf source'
}
- Replace your top-level
build.gradle
(<project_root>/build.gradle
) with the file in this release. - Copy the
healthcheck.sh
file from this release to your project root (<project_root>/healthcheck.sh
). - Copy the
Dockerfile
file from this release to your project root (<project_root>/Dockerfile
). - Delete any Sync Server SDK jarfiles located in
<project_root>/<server_name>/libs/
. - Follow implementation details below.
Usage
Installing Docker
https://docs.docker.com/desktop/mac/install/
Exporting Docker Image Archive
In order to tighten the sandbox development iteration loop, Skillz requests that third-party developers hand-off their Sync Server deliverable as a Docker Image Archive (.tar
or .tar.gz
archive file).
In order to simplify this process, we've implemented a Gradle task, exportDockerImageArchive
, which will use the provided Dockerfile to build and export a Docker Image Archive tarball to the <project_root>/<server_name>/docker/
folder, like so:
New Configuration Variables
The following variables are now available for configuration in your custom Game
class, see below for an example.
Setting any of the MAX_
variables to a value of -1
will disable that limit (e.g., allowing for unlimited pause/resumes, or unlimited disconnect/reconnects).
Setting USE_CUMULATIVE_PAUSE_DISCONNECT_TIMER
to true
will enable the use of a single, cumulative timer for pause/resume and disconenct/reconnect. This timer will count down from the value of DISCONNECT_SECONDS
, maintaining its value across pause/disconnect events.
@Slf4j
@CompileStatic
class ExampleSkillzGame extends Game<Player> {
// Required Configuration Vars
public static final int TICK_RATE = 100
public static final String VERSION = "1.0"
public static final int VERSION_NUMBER = 1
// Optional Configuration Vars
public static final int WARNING_SECONDS = 4
public static final int DISCONNECT_SECONDS = 30
public static final int MAX_RECONNECTS = -1
public static final int MAX_ALLOWED_APP_PAUSES = -1
public static final int MAX_ALLOWED_APP_CONNECTION_WARNINGS = -1
public static final int MIN_TIME_IN_SECONDS_FOR_NEW_PAUSE = 1
public static final boolean USE_CUMULATIVE_PAUSE_DISCONNECT_TIMER = true
Skillz Example Sync Server v1.2.1
This release uses the most recent Sync Server SDK jar, pulled from the Github Packages repository for this repo.
To download this example project, please use the Source Code links below.
Changelog:
- Server report score feature added
- Exposed server metrics via OpenMetrics Prometheus endpoint (port
10142
) - Removed
FairRandom
class - Minor bug fixes and performance improvements
- Skillz Sync Server SDK
.jar
library file is available via Github Packages repo
Upgrade Steps:
-
Make the following changes to the your top-level
build.gradle
file:
https://github.com/skillz/skillz-example-sync-server/pull/1/files#diff-49a96...- If you've made no changes to this build.gradle file, you can simply replace it with the file located here:
https://github.com/skillz/skillz-example-sync-server/blob/v1.2.1/build.gradle
- If you've made no changes to this build.gradle file, you can simply replace it with the file located here:
-
Delete the
server_sdk.jar
file in theexample_sync_server/libs/
folder
(the top-level folderexample_sync_server
may be named differently in your project)
How to Implement Server Report Score:
- In your custom
Game
class, in the overriddenbroadcast()
orprocess()
function, call the newly availablereportScores()
function when the game is over. - This functionality relies on the following internal fields:
Client.score
must be set accordinglyGame.isAborted()
andGame.isForfeited()
are used to determine the end game state, ensure the following functions are used when tracking/setting game state:Game.forfeitGame(Client forfeitingClient)
Game.abortGame(Client abortingClient)
See below for an example:
@Override
def broadcast() {
for (Player player in players as List<Player>) {
if (isGamePaused() || isResuming()) {
player.getMessageSender().sendOpponentConnection()
}
player.getMessageSender().sendGameStateUpdate();
}
if (completed || aborted) {
log.info("Game over for matchId: " + matchId + ", completed: " + completed + ", aborted: " + aborted);
// The game has ended and we want to report the scores to the Skillz platform now
reportScores()
for (Player player in players as List<Player>) {
log.debug("Sending GameOver to player: " + player.getUserId());
player.getMessageSender().sendGameOver()
}
reset();
}
}