Home Portfolio Dead Cells Updates Version 2.8 - Break the Bank
Post
Cancel

Version 2.8 - Break the Bank

Introduction

Update 2.8, officially named Break the Bank, was focused on adding new mechanics and features around gold (the game’s in-run currency), with a new free biome, as well as a bunch of enemies and weapons.

Notable additions and changes

A full list of changes can be found on the Dead Cells Wiki.

What I worked on

The weapons

The three weapons added in the update all have mechanics centered around gold:

  • Gold Digger
    • A melee weapon resembling a pickaxe. Enemies hit with the weapon drop gold, and having enough gold makes it deal critical hits.
  • Dagger of Profit
    • A dagger that deals critical hits for a few seconds after the player picks up any kind of gold.
  • Money Shooter
    • A ranged weapon, firing projectiles in the form of nuggets, removing some gold from the player’s inventory each time.

Gif of a player using the Money Shooter, then the Gold Digger.

In Dead Cells, the player can carry two weapons and three mutations at a time. The goal was for those to synergize not only with each other, but also with the mutations. Having some mechanics that give, take away or react to gold lets the player combine them and play around with them.

I was tasked with implementing all three of the weapons above. Their overall mechanics were already designed, but I had creative liberty for their implementation and for some specific values (such as the amount of gold used by the Money shooter, or the duration of the Dagger of Profit buff.)

The Bank spawning mechanic

The Bank is a special level, in the sense that it can be found randomly at any point throughout the run. In Dead Cells, each biome has multiple exit doors leading to a transition to another biome. The Bank entrance takes the form of a chest that can randomly appear in any transition, as an optional alternate path.

The chance of the Bank entrance appearing increases with each level visited, making it less and less rare as the player progresses through the run.

If the player interacts with the chest, it will open and they will jump in it, leading them to the Bank.

Gif of a player jumping in the Bank entrance chest.

The Bank level structure

While I didn’t end up making the level design of the rooms for the Bank, I did implement the overall structure of it.

The biome is centered on an elevator, leading to four different floors:

  • Three main floors, locked behind colored key doors (red, blue and green), that have to be explored one after the other.
  • One secondary floor, locked behind a gold door (a locked door that can be opened by paying some gold), that can be accessed at any point.

In the beginning of the level, the player can find a Red Pass, granting access to the red floor. The red floor then contains the Blue Pass, and the blue floor contains the Green Pass.

The red and blue floors are both mandatory to complete, as the exit can be found somewhere in the blue floor, while the green one is completely optional and hosts a special platforming challenge, granting good rewards if completed.

Sketch of the Bank’s overall structure.

The Mimic

The Mimic is a special mini-boss that can appear in the Bank. When the player enters the level, one of the shops gets chosen randomly and is replaced with a Mimic.

A replaced shop looks completely normal, and is impossible to spot. If the player tries buying anything from the shop, the Mimic will spawn, eat the item that the player tried to buy, and start attacking them.

The Mimic.

The Mimic is the enemy with the most complex moveset in the game (besides bosses), and uses a more complex system than usual.

Enemies have a list of attacks, each with a cooldown value and detection area. They then iterate over that list of moves and execute them as follow:

  graph LR

    start(("Every frame"))

    checkMove["Check attack"]

    nextMove["Go to next attack"]

    checkCooldown{"Is attack
    on cooldown?"}

    checkArea{"Is player touching
    detection area?"}

    attacksExpired{"All attacks
    checked?"}

    executeMove(("Trigger the attack
    and put it on cooldown"))

    doNothing(("Do nothing"))

    

    start-->checkMove

    checkMove-->checkCooldown

    nextMove-->checkMove

    checkCooldown-- Yes --> attacksExpired

    checkCooldown-- No --> checkArea

    checkArea-- Yes --> executeMove

    checkArea-- No --> attacksExpired

    attacksExpired-- Yes --> doNothing

    attacksExpired-- No --> nextMove



    linkStyle 3,5,7 stroke:palegreen;
    linkStyle 4,6,8 stroke:salmon;

The Mimic doesn’t use this system. Instead, it has three different pools of attacks depending on its position in relation with the player: CloseRange, MidRange and LongRange. Those pools are then filled with its 4 basic attacks:

Bite

A fast bite with short range.

Tongue Lash

A medium range tongue lash, stunning the player for a short time if it hits.

Chain Whip

A long range whip attack using chains.

Hook Throw

Charges a hook and throws it at the player. If it hits, they get grabbed and pulled toward the Mimic.


Additionally, the Mimic gains one more move, depending on the kind of item it ate upon spawning. This move is added to the corresponding pool.

If it ate a melee weapon: Sword Slash

A slow but big melee attack.

If it ate a ranged weapon: Spit

Spits out 2 bursts of 5 projectiles in a fan.

If it ate a shield: Parry

Turns into a shield. If the player hits it in this state, they get stunned, and the Mimic will counter-attack.

If it ate a skill: Spikes

Charge a huge area-of-effect attack, hitting all around it.

If it ate a healing item: Feeding

Stops and starts eating a body part for health. The player can interrupt it with an attack.


Moves added to a pool are also given a weight that defines how likely each of them is to be triggered.

For example, while both Bite and Tongue Lash are added to the CloseRange pool, Bite get assigned a bigger weight, as its speed and range make it more pertinent to use at close range.


With all the pools filled, this is how the Mimic executes its moves:

  graph LR

    start(("Every frame"))

    checkDistance{"Check distance
    with player"}

    closeRange["Use CloseRange pool"]
    midRange["Use MidRange pool"]
    longRange["Use LongRange pool"]

    getMove["Get a weighted random
    attack out of the pool"]

    executeMove(("Trigger the attack"))

    start-->checkDistance

    checkDistance-- Close --> closeRange
    checkDistance-- Medium --> midRange
    checkDistance-- Far --> longRange

    closeRange-->getMove
    midRange-->getMove
    longRange-->getMove

    getMove-->executeMove

Contents