Skip to content

redhat-gamedev/shipwars-game-server

This branch is 30 commits ahead of rhdemo/2021-frontend-wss:master.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

f06be92 ยท Jan 7, 2022
Jan 30, 2021
May 18, 2021
May 14, 2021
May 14, 2021
Jan 7, 2022
Apr 13, 2021
Feb 19, 2021
Jan 4, 2021
Feb 19, 2021
Feb 19, 2021
Feb 14, 2021
Jan 4, 2021
May 14, 2021
Jun 15, 2021
May 20, 2021
Jun 2, 2021
Jun 2, 2021
Jun 2, 2021
Feb 19, 2021

Repository files navigation

Shipwars Game Server

WebSocket server for the Shipwars game.

Requirements

  • Node.js v14.3
  • npm 6.14

Building

The deployment to OpenShift uses a pre-built image. The image can be built and pushed to an image registry using included scripts.

Requirements:

Optional environment variables are supported to modify image registry and tag.

# These are the defaults defined in both scripts, so change them if you'd
# like to push a different tag or to another image registry/repository
export IMAGE_TAG=latest
export IMAGE_REPOSITORY=quay.io/evanshortiss/shipwars-game-server

./scripts/build.sh

./scripts/push.sh

Deployment

Use the script documented here.

Local Development

Use the Docker Compose setup documented here.

About

A simplified version of the backend used for the live keynote demo at Red Hat Summit 2021.

The initial deployment was performed using a StatefulSet. Since the codebase in this repository is designed to run as a single Pod, certain oddities from the previous StatefulSet architecture might be hanging about.

Game flow is summarised in the following sequence(ish) diagram. This activity continues until a player has sunk all of the opposing player's ships.

Client-Server Sequence

Endpoints

Two WebSocket endpoints are exposed:

  • $HOST:$PORT/game - The Shipwars Client uses this to facilitate gameplay.
  • $HOST:$PORT/leaderboard - The Shipwars Dashboard uses this to render the leaderboard in real-time.

Cache/Storage

This iteration of the game uses a simple Node.js in-memory cache. Entries have a TTL of 1 hour before they are flushed.

Previous versions used an external Infinispan cache.

Models

The game stores state using the following models. All model instances have a unique UUID. Models are written to the cache for storage.

  • Game - Game is the top-level state that all matches inherit from. Previously could be updated using an external cache to pause, stop, reset the overall game and matches for each connected player.
  • Player - Represents a connected player.
  • Match - Represents a match that two players use to face-off.
  • MatchPlayer - Represents match data specific to a player, e.g score, shots, ship positions. Two of these are stored in a Match instance.

Kafka Integration

The following events are sent to Kafka, with the associated data to facilitate reconstructing the events of a match/game, and generate statistics.

  • Match Start (match-start) - One of these events is sent per match. Sent when both players lock their ship positions.
  • Attack (attack) - Multiple attacks are sent per player, per match.
  • Bonus (bonus) - Multiple bonuses are sent per player, per match. Unlucky players might not send many though!
  • Match End (match-start) - One of these events is sent per match. Sent when a winner is determined.

WebSocket Payloads

These are documented in the src/payloads folder, differentiated as incoming and outgoing.

Each client WebSocket has a mutex wrapper that locks while we process an incoming payload. This is to prevent a malicious client sending multiple attacks and other types of cheats.

Each incoming/outgoing message has the basic structure:

{
  type: String
  data: Object
}

For example, an incoming attack frame from a client targeting cell 0,2 (x, y) on the opponent grid:

{
  type: 'attack',
  data: {
    origin: [0, 2]
  }
}

And a sample response frame stating that the attack landed a hit, and sank the opponent's Destroyer. Some data is removed for brevity:

{
  type: 'attack-result',
  data: {
    result: {
      hit: true,
      origin: [
        0,
        2
      ],
      type: "Destroyer",
      destroyed: true
    }
    // More data about the overall game state is also included,
    // but is not shown here since it's too verbose for an example
  }
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 97.1%
  • JavaScript 2.5%
  • Other 0.4%