DEV Community

Cover image for Game Night Just Got a Digital Upgrade: The Deck
Ilbets
Ilbets

Posted on

3 1

Game Night Just Got a Digital Upgrade: The Deck

The inspiration for “The Deck” came from a situation many of us have experienced. Imagine gathering with friends for a game night, only to realize that nobody has the necessary cards. Frustrating, right? This dilemma sparked the idea of leveraging technology to create a solution.

The primary goal of “The Deck” is to provide a user-friendly and cooperative digital game environment for playing classic games that were usually played with cards on paper. One of the standout features of “The Deck” is its unique ability to assign one device as the “table” (a.k.a. deck). By placing this device in the middle of the group, all players can witness the real-time state of the cards. This adds a new level of immersion making it a truly captivating experience.

Image description

Game Flow

First, let's look at the result 👨‍💻. I ideated on what might be the perfect UX for such a solution and settled on the next steps (here we are using Android TV as the table):

  1. Create the Room - use TV, mobile, table, or laprot to create a room.

Image description

  1. Join the room. A device that created the room can participate as well, or just be the deck.

Image description

  1. Start the game! As soon as you have enough players, the host can start the game.

Image description

In this case, TV is the host & deck. Players are using their phones to move and other people can observe game updates on the TV.

Implementation

Over a span of approximately four months, I dedicated my weekday evenings and weekends to developing three games: Tic Tac Toe, Connect Four, and Dixitt. Eventually, I released them to both iOS and Android stores. Here are some details on the implementation of the game.

Transport layer

Considering that I wanted to make sure that app can run in the local network and require bi-directional, low-latency communication between participants, the solution was quite obvious — sockets:

Image description

For MVP I decided to stick to go with socket.io. After a quick search, I found packages for Dart:

socket-client
socket-server

Game Room

The game room is the platform's base abstraction. Each game starts with a host creating a room and inviting participants and observers. As soon as the game constraints are fulfilled (e.g., the required minimum number of players), the host can start the game.

Creating architecture was one of the most challenging tasks. As I need to ensure that abstraction will scale well for various games

Image description

Components breakdown:

  • Game Details — it is a description of the Game and room IP. It is advertised in the QR code so clients can check if they support the game and can join;
  • Game Room — created based on Game Detail, it is the main orchestrator for the game, keeps track of participants, and controls game state
  • Game Participants — List of participants with some metadata
  • Participant profile — participant profile in The Deck, with user profile information
  • Game Board — base abstraction for any game
  • Game Move — board contains a list of all game moves that were applied;
  • Game Player — an entity that describes participants' role in the game, like “red” or “yellow” in Connect Four;
  • Game Field — representation of the game field, i.e. 7 by 8 matrix for Connect Four;

Room: create, join, start

Here is GameRoom lifetime:

Image description

The Deck / Table

The deck or table, as well as the client, subscribe to updates, the only difference is that the server cannot execute “move”.

You can play as well without a deck, in case you don’t have a spare device

Image description

Please note that Android TV devices serve exclusively as the “table” within the game.

Packages

From the beginning, I wanted to ensure that socket server code could be run separately and deployed in the cloud. Therefore, I split the app into 4 separate packages:

  • Common — shared DTO and utilities
  • Server — socket server logic, depends on Common
  • Client—socket client logic, depends on Common
  • UI — Flutter UI app package, depends on 3 other modules

Image description

Common, Client, and Server modules don’t have any Flutter dependencies and can be published as separate packages.

Using Alfred, I created a new app to run a standalone HTTP server that depends on the Socket Server package and allows you to create a game room, and connect to it via socket. This solution could be potentially deployed in the cloud to remove constrain on the local network.

Game State

One tricky part of any online game is to ensure consistency of the game state on all devices. To simplify the problem, I decided that only the server would be able to modify the game state. The client is only able to send a request to change state — move and listen for field updates.

Image description

The state is propagated via broadcast ( socket.io API) to all connected clients.

UI State with Redux

The client is merely a game field representation, it was quite an obvious decision to use Redux as an application architecture. Each game screen has two basic functions:

  1. Draw Game Field
  2. Send Game Move request

Image description

Sockets & Redux

The pieces come together to form the next flow:

Image description

  1. When the user selects the Game, the app creates a Socket Server & Game Room and stores them on the host device;
  2. At the same time Host device create a Socket Client and connects to the server running on the same device;
  3. Socket Server broadcast Game Board to 2 clients (himself and another player);
  4. Socket client receives a Game Board and propagates it to middleware;
  5. Middleware update Redux game-specific state;
  6. Game widget updates based on the new state;
  7. Now the player can send a move request to the server, which is propagated via middleware & socket client to the server and GameRoom middleware.

Socket API

To simplify communication via socket, I decided to build a REST-like abstraction. Each message extends from the back which contains the path. The path is usually a /roomId/* or/roomId/gameId/*. When a client connects to the room, they will subscribe to updates from the specific room for the specific game.

class AppSocketMessage extends JsonEncodeable {
  final String messageId;
  final String path;
  final DateTime createAt;

  final JsonEncodeable data;

  AppSocketMessage.send(this.data, this.path)
      : messageId = Ulid().toUuid(),
        createAt = DateTime.now();

  AppSocketMessage._receive(this.data, this.createAt, this.messageId, this.path);

  @override
  Map<String, dynamic> toMap() {...}

  factory AppSocketMessage.fromJson(Map<String, dynamic> json) {...}
}
Enter fullscreen mode Exit fullscreen mode

All data sent in AppSocketMessage comply with JsonEncodeable that ensures that it can be converted to JSON.

Cross-platform support

A significant benefit of using Flutter is that you can run it on multiple platforms, including Android and iOS. With M1/2 Apple chips supporting iOS apps, you can run The Deck even on your MacBook.

Image description

➡ Unfortunately, Tizen / Samsung doesn’t allow independent developers to release apps outside of the US. As for Apple TV- this is something I’m planning to look into later.

Design

I want to highlight that all assets in the game, including the app icon, achievement badges, player avatars, and Dixit game cards, everything were generated by Midjourney or DALL-E.

Image description

Hard to express how much time, effort, and money I saved leveraging generative AI 🧑‍🎨 Even tho, I spend a significant amount of time “fine-tuning” them in Figma.

What is next?

First of all, the power of “The Deck” is in the platform. ➡️ Moving forward, my vision is to abstract the game code and open-source it, encouraging enthusiasts to develop and onboard their own games. My goal is to ensure that adding a new game to the platform becomes an effortless process. If you are interested in joining early testing contact me at me@getthedeck.com 🤝

I want to explore new cross-platform connectivity protocols, to allow seamless connection with devices nearby. 🎮

Add AI agents to play with you when you are lacking a few players 🤖

Finally, I am intrigued by the prospect of Web3. Give players AI-generated unique NFT badges for achievements, open internal marker place, and incorporate bidding options for adult players with cryptocurrencies. Who knows what exciting developments lie ahead?🤓

Visit

Visit getthedeck.com

Image description

Download

Source Code

Contribution is very welcome! 🤝 ❤️

Tech Stack

List of tools used to deliver the project

Image description

Retry later

Top comments (0)

Retry later
Retry later