game design – engineering – narrative

Intro

Part of my work on the Conversational Card Game project includes systemizing the game in technical and gameplay aspects. The following is a breakdown of those efforts, including how I approached implementation using Unreal Engine’s Gameplay Ability System and ensured that designers could keep iterating with as few obstacles as possible.

Premise

The game’s tagline is “conversational blackjack.” In it, the player and their counterpart are usually players of equivalent power. They both have card decks they can play, they follow the same rules, etc.

Part of the game is that its conversations occur between the player and imaginary creatures, living concepts, eldritch gods, etc. This means that magical elements are at play, with custom cards, suits, and relationships between them.

Blackjack

To set some table stakes, this is the game structure of blackjack:

  • The game uses standard playing cards (52 cards, 4 suits, 4 special cards —  Ace, Jack, Queen, King)
  • One or more players play against a dealer
  • The players and the dealer share the two cards the dealer draws at the start of a round
  • Players bet on the outcome of each round
  • Players can:
    • Take turns
    • Choosing to hit (draw a card)
    • Choosing to stay (end their turn)
  • Dealers:
    • Deals cards
    • Chooses to hit (automatically)
  • The players and dealer share a boot (a deck)
  • Losing a hand means losing the current wager
  • Players don’t lose the game until they run out of money

Given these parameters, we get the following:

  • 2 entity types
  • 3 Object types
    • Card – Has a specific value 
    • Deck – Has a set collection of cards
    • Board – Receives cards as they’re played
  • We-go-you-go turn-based game mode
    • The dealer deals cards to players from the deck
    • The dealer deals cards to the board
    • Players hit/stay
      • The dealer deals cards on every hit 1 player at a time, left to right
    • The dealer always goes after players, dealing cards to themselves until beating the player’s hands or “breaking”
  • The players and the dealer are trying to reach a target number without exceeding that number
    • The number is not achievable with only one card
    • The number is odd
  • Players don’t interact directly. 2 possible decision points; bet, and hit/stay

The Twist

The magical element would apply on top of the standard blackjack rules, which means that the mapping I did had to account for more possible effects and relationships than what would occur in the standard game. This magic system will be developed alongside the card gameplay, so addressing specific implementations isn’t practical. Additionally, I had to account for the possibility that elements outside the card game could also come into play and that designers may try to incorporate mechanics closer to Magic The Gathering than blackjack. This emphasized the need for flexibility in the system as a whole.

Gameplay Ability System

The Gameplay Ability System provides scaffolding for gameplay interactions. However, it still needs to be structured around the intended game mechanics of a given project. The overall architecture is well-documented already, I won’t go into much detail here.

The GAS framework’s basic components are the following:

  • Entities have
  • Abilities have
    • Target Data
    • Logic
    • Gameplay Effect references
    • Tags
  • Gameplay Effects have
    • Effect calculation
    • Logic (lightweight)
    • Tags
  • Gameplay Cues have

Entities, along with attributes and tags, have abilities that they can trigger actively or passively. Those abilities have gameplay effects that they attempt to apply to targets. Those gameplay effects modify a target entity (or a group) by changing their attributes or tags. Gameplay effects can also grant new abilities to their targets, which can be used to depict a variety of complex game mechanics. These attributes, abilities, and effects are tied to the Ability System Component (ASC), which provides an Actor-based context to the other aspects I’ve listed here. Specifically, attributes are stored by the ASC, abilities are triggered and targeted in the context of an ASC, and gameplay effects apply their payloads to an ASC. Gameplay cues also refer directly to the ASC that is applying it to another ASC, or the ASC it’s being applied to, but I’m not going to delve into them here.

Something that the Gameplay Ability System doesn’t do out of the box is take into account anything that isn’t stored in an actor’s ASC. However, we can access an actor through its ASC, thereby accessing actor-based functionality.

For more information about GAS, refer to https://github.com/tranek/GASDocumentation

The Game

Cards

Cards have a type and a value. This value can be numeric, but it can also represent a glyph, in the sense that it can have other meanings — it can be part of an ordinal hierarchy, denote a calculation, etc. As such, we can consider each card to be an entity. They have attributes (their value) and tags (their type). They could then be subject to certain gameplay effects. They can also be in 4 distinct states:

  1. In a deck
  2. In a player’s hand
  3. In play on the board
  4. Discarded/In the graveyard

Each card should have an active ability a player can trigger while holding the card. They could also have other passive abilities, or be granted such abilities during play. In those cases, transitioning between those states could be used as a triggering event for those passive abilities. 

Separate from the game state the cards can exist in, they also can exist as one of two data-states:

  1. As a template. The card as it exists in a deck outside the context of being in a player’s hand.
  2. As an instance of itself. The card in the context of the game’s state and the player’s hand, with its values and effects modified by it. 

In this way, it mirrors GAS’ structure for abilities and gameplay effects. Note that this doesn’t make assumptions about anything other than cards that cards can exist in different states and contexts.

Decks

In the current conception of the game, there is only a single deck, as is the case in Blackjack. All the players, including the dealer, draw from it and discarded cards are not returned. As such, they are an ordered collection, though they are shuffled, and likely composed from cards that players and the dealer contribute. As a result, they are a part of the game’s overall state.

Players

Players have attributes, take turns, and take actions in those turns. The player’s attributes are taken as part of the effect calculations in cards that are instantiated in their context. Players also have card collections — cards they have gathered throughout the game. How those collections are leveraged through gameplay is still being developed. However, with a blackjack base, the players may choose cards to add to the shared deck, opening up different strategies where they, the dealer, or their opponent draws them. This approach allows us to theme a non-human-controlled player in ways that match their personality and furthers the ludonarrative aspect of the game, with each player using cards that match their demeanor and so on.

The Dealer

The dealer has some of the player’s capabilities. However, their behavior is dictated by the state of the game. The dealer doesn’t have their own attributes or special cards, instead act as the board’s agent. Their actions are dictated by the game’s rules instead of any strategy.

The Board

The board reflects the state of the game. While players have attributes and conditions that change how their cards behave, the board has the overall game’s state and is the context used when an effect is targeted at a player. Players, therefore, do not affect one another directly.  They have to manipulate the state of the board, taking into account the dealer, to interact with each other. 

Rounds

Rounds have distinct phases:

  1. Each player has a turn
    1. After all the players take their turns
    2. The “pending cards” are played with their effects triggering
    3. The board’s state is updated
  2. The dealer plays according to the rules, further modifying the board’s state
  3. The board’s “result” pays out, modifying the player’s attributes accordingly
  4. All the cards played during that round are moved to the “graveyard” deck

Since the dealer is just another player playing automatically, we can infer it’s drawing and staying according to the game’s rules. Its hit/stay logic is the only thing that differs from a normal player’s turn.

Win/Lose Conditions

The conditions that dictate whether a game ends, and its outcome, are the board’s and players’ attributes. The thresholds involved could vary from each game, but the overall mechanics remain the same.

Development Philosophy

Given the above gameplay scheme, and that flexibility was one of the core values that my GAS implementation needed to follow, I approached the problem with the following guidelines:

Don’t create a finished product

Rather than take blackjack and try to create a 1:1 model of it in GAS, I took each aspect of the game and broke it down further, aiming to build building blocks rather than direct, rigid solutions. The point of this work isn’t to make the game from end to end. It’s to build the components our designers will use to make it, with whatever game mechanics they create.

Data goes one way

The structure shouldn’t rely on back-references to determine the context of its effects. I learned this from working on similar game mechanic pipelines in the past. It’s better to consider the context as a shifting window where only the immediately relevant information is accessible. This will make game mechanics reusable because they are independent of the context that triggers them, which is important to make them reusable and recontextualizable. An example of this reuse/recontextualization in practice would be taking a boss’ ability and granting it to the player. This becomes significantly harder when abilities rely on references to a specific entity, and it’s often how a complex ability is implemented.

Centralize control

Two aspects of the card game we’re building dictate the structure of our game systems:

  • It’s strictly turn-based
  • We need a predictable order of operations in each turn

Given these parameters, there has to be a single source of truth about the game’s state, such as whose turn it is, the order in which abilities and effects occur, etc. Implementing things this way does add an up-front cost. This investment pays off since it will limit possible issues due to race conditions and unexpected behaviors and simplify how things are implemented later in development.

Leave a comment