Bolt Storm

Contributions: Loot System, Save System, Ludumdare Gamejam Game

Role: Gameplay Programming

Engine: Unreal Engine 4

Languages: C++, UE4 Blueprints

Project Accomplishments: Steam Greenlight, Dutch Game Award(2017)

About

Bolt Storm is an action-oriented dungeon crawler with a twist to the genre - the player is able to command an army of units to assist him in advancing through the dungeon. The project started off as a Ludumdare Gamejam Game and was picked up by Kuality Games as an external university project. Later on, it was accepted on Steam Greenlight. We later won an award for “Best Student Technical Achivement” at the Dutch Game Awards.

Contributions

Loot System

The loot system in our game is made to function on a room to room basis. Every room would distribute rewards within a fixed quality range, which would keep the player satisfied with the gameplay, while still retaining control in the designers’ hands when it comes to balancing the game.

Implementation

The loot system was a combination of a C++ and a Blueprint implementation. The majority of the architecture was done in C++, while Blueprints was used for implementation purposes. It makes use of UE4’s Data Assets for both the items and the loot tables.

Executioner Boss Loot Table

The following code demonstrates how rolling for an item works:

TSubclassOf<ABsLootable> UBsLootDistributor::GetDroppedLootable(UBsLootTable* aLootTable)
{
  if (BS_INVALID(aLootTable))
  {
    printError("UBsLootDistributor::GetDroppedLootable - Owner has no valid UBsLootTable.");
    return nullptr;
  }

  float chanceRange = 0.f;
  TArray<FBsLootProperties> nonGuaranteedLoot;
  
  // filter out guaranteed loot
  // and sum all the item drop weights 
  for (FBsLootProperties loot : aLootTable->mLootDrops)
  {
  // -1 weight = convention for guaranteed loot 
    float weight = loot.mDropWeight;
    if (weight < 0)
    {
      continue;
    }

    chanceRange += weight;
    nonGuaranteedLoot.Add(loot);
  }

  // roll the dice
  float lootRoll = FMath::FRandRange(0.f, chanceRange);
  float current = 0.f;

  // Keep adding loot.mDropWeight to current, until it's >= lootRoll
  //  Example:
  //  Item 1: 0 - 10 
  //  Item 2: 11 - 50
  //  Item 3: 50 - 100
  for (FBsLootProperties loot : nonGuaranteedLoot)
  {
    current += loot.mDropWeight;
    if (current >= lootRoll)
    {
      return loot.mLootItem;
    }
  }

  return nullptr;
}

Save System

Implementation

The save system is a wrapper around the UE4 API. It is split into 2 parts - Gameplay Data, which is relevant for the ongoing playthrough, and Persistent Data, which is related to various unlockables in the game.

Checkpoints

In different scenarios, the player’s data is handled differently (e.g. when the player dies, his gold is kept, but his companions and weapons are lost). Thus, checkpoints are made in a way where you can specify what data gets loaded.

User Interface

Below you can see various UI elements, which I’ve implemented in our game. The design itself was done by the UI artist.

Player HUD

Player HUD

Interaction Windows

Enter Dungeon Interaction Window

Replay Tutorial Interaction Window

Awards

Our game won a Dutch Game Award for “Best Student Technical Achievement”.

Best Technical Achievement Award