From Idea to Reality: Creating a Card Game in Just 2 Days

Saakshi Baheti
3 min read

Can we build a fully-fledged card game in just two days?

That was the challenge taken on by the Bhoos development team during an intense GameJam Hackathon on July 1st and July 2nd. What transpired during those two days was nothing short of extraordinary. Six developers were not only able to create working prototypes of card games, but another six made significant progress on their respective projects.

The hackathon was not something that came overnight; instead, the logic used in the hackathon resulted from extensive brainstorming and thorough experimentation.


Here’s how the concept came in:

A Paradigm Shift in Game Development

At the heart of Bhoos' game development is our proprietary Game Engine, an internal library that serves as the backbone for creating turn-based games like Callbreak and Ludo. In a recent overhaul of this engine, a groundbreaking shift in how APIs, events, and actions are managed was introduced. The transition moved away from the complexity of an event-driven model to a more intuitive and streamlined linear approach.

Pain Points with the Event-driven model:

In the multiplayer and friends network gameplay, the complexity of maintaining the integrity of game states and dealing with real-time synchronization was relatively high. Moreover, the game’s flow, logic and API calls were arduous to understand through the codebase.  

It was vital to design systems that can handle transitions between states seamlessly, regardless of whether they are interrupted by timeouts, reconnections, or abrupt departures.

The New Game Logic

Ranjan Shrestha and Bibek Panthi are the masterminds behind creating the paradigm of the new engine, which allows the core game logic to be elegantly expressed in a single function, which they named the "Game Loop." This game loop encapsulates the flow of each API, event, and action, represented using familiar control flow statements such as "if," "await," and "loop." This shift not only simplifies game development but also enhances the efficiency and maintainability of the codebase.

while(!isGameFinished(state)) {
  // Wait for a Play API from the server
  await server.wait(
    (expect, onTimeout) => {
      expect(PlayApi, (api) => {
        dispatch(new PlayAction(api.move)));
      },
      onTimeout() {
        // If there's a timeout, ask the bot for a move and then dispatch
        dispatch(new PlayAction(askBotForMove()));
      });
    }
  );

  // After receiving a Play API, we can proceed with other actions

  // Wait for a Pick API from the server
  await server.wait(
    (expect, onTimeout) => {
      expect(PickApi, (api) => {
        // Handle the Pick API here
      },
      onTimeout() {
        // Handle the timeout for Pick API
      });
    }
  );

  // After receiving a Pick API, we loop back to Play Api until Game is finished
}

This logic made a lot of processes simpler:

Synchronization

  • A key problem arises when a player returns to the game and attempts to make a move before the AI bot can decide its move. The bot typically takes about 10 milliseconds to make a decision, but a player can return and make a move much faster.
  • When this occurs, both the returning player and the bot end up playing a card simultaneously. This results in two cards being played at once, disrupting the flow of the game.
  • With the enhanced logic, no two cards can be played simultaneously, as after the timeout, the server doesn’t accept API from player

// “dispatch” condition is only active for the bot; hence, the player is in the game but will only play the next turn.

State Inconsistency

  • The card thrown by the bot can land in a different game state compared to when the player initially left or timed out. In the time between the player's absence and return, other players might have made moves, picked cards, or performed various actions.
  • The newly formed game logic is designed so that pickCard and playCard cannot happen simultaneously. By this, the system seamlessly handles the situation when a player leaves the game or experiences a timeout.

Continuity

  • Another pain point arises when players save and exit the game, expecting to resume from the exact point where they left off when they return.
  • This involves accurately maintaining the game state, player progress, and all relevant data. Although not shown in above snippet, this part of the process is also handled elegantly.

Validation

  • Validation code is reduced because unexpected Apis are directly discarded.

Coming back to GameJam Hackathon:

Games that we made
A happy image after the completion of the Hackathon

The games were evaluated based on various criteria, including game completeness, aesthetics, smooth animations, adherence to time limits, and API validation. The results were impressive, with Anmol Paudel, Bibek Panthi, and Sammelan Yogi securing top positions in the competition.
The Hackathon was about testing the new logic, breaking away from the daily scheduled work and tackling something more challenging.

This logic gave way to more ideas and more games. To put it in a sentence: something SUPER is coming.