Skip to content

Releases: skillz/skillz-example-sync-server

Skillz Example Sync Server

24 Jun 21:21
100dcc8
Compare
Choose a tag to compare

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

06 Apr 19:34
ccbb6f3
Compare
Choose a tag to compare

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

17 Feb 18:49
b83443a
Compare
Choose a tag to compare

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

14 Dec 20:58
924c328
Compare
Choose a tag to compare

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

  1. 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'
}
  1. Replace your top-level build.gradle (<project_root>/build.gradle) with the file in this release.
  2. Copy the healthcheck.sh file from this release to your project root (<project_root>/healthcheck.sh).
  3. Copy the Dockerfile file from this release to your project root (<project_root>/Dockerfile).
  4. Delete any Sync Server SDK jarfiles located in <project_root>/<server_name>/libs/.
  5. 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:
Screen Shot 2021-12-13 at 12 57 20 PM

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

31 Aug 00:09
d1de073
Compare
Choose a tag to compare

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:

  1. 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...

  2. Delete the server_sdk.jar file in the example_sync_server/libs/ folder
    (the top-level folder example_sync_server may be named differently in your project)

How to Implement Server Report Score:

  • In your custom Game class, in the overridden broadcast() or process() function, call the newly available reportScores() function when the game is over.
  • This functionality relies on the following internal fields:
    • Client.score must be set accordingly
    • Game.isAborted() and Game.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();
        }
    }