Refactoring Interconnected Actor Components

Purpose

The purpose of this devlog is to describe the architecture used to manage character state parameters for the Powderkeg Pals Character Blueprint. The character has several state parameters that are dependent on several actor components responsible for functionality (ragdoll, enter/exit tutorial zones). I recently refactored the character blueprint and found that the architecture described below really helped me debug issues I and wanted to share the results!

Background

Powderkeg Pals is a physics based puzzle/action game. You control a character that can drop bombs that apply radial force to nearby objects. When characters get hit by an explosion they enter ragdoll and are propelled around the map.

To describe the character blueprint refactor I'll focus on a single state parameter, the character's Bomb Drop Enable. If this is TRUE the character can drop explosive kegs. If it is FALSE then they cannot drop kegs. There are a couple game play mechanics that impact whether or not the character can drop bombs. We don't want the character to be able to drop kegs when the character is in ragdoll or when they are inside a tutorial zone.

We don't want players to accidentally drop a keg when the tutorial is active

Old Architecture

Prior to the refactor, the Bomb Drop Enable was directly set whenever ragdoll was activated, or when they entered/exited a tutorial zone. Whenever we enter/exit a tutorial zone we update our Bomb Drop Enable and whenever we enter/exit ragdoll we also update our Bomb Drop Enable.







There are several bugs with this implementation that are not immediately obvious and require confounding factors to reproduce. For example the following sequence produces a bug:

enter tutorial zone (Bomb Drop Enable = FALSE ) enter ragdoll (Bomb Drop Enable = FALSE ) exit ragdoll while still in the tutorial zone (bomb drop enable = TRUE)

In this example the character has bomb drop enabled while they are inside a tutorial zone! This issue didn't appear obvious to me during play testing because it requires multiple factors to confound before the bug occurs. This issue worsens as we extend functionality and add actor modules that may influence the character's Bomb Drop Enable. This bug motivated the refactor.

New Architecture

After refactoring, Bomb Drop Enable is now updated based on the current state of all dependent factors ( ragdoll active, tutorial zone) and its updated whenever one of its dependent factors changes based on a couple event binds.





This makes the logic very obvious for the Bomb Drop Enable because its all in one place and easy to debug. When an issue is observed with Bomb Drop Enable there is only one place to look for issues! It also offers consistent functionality based on state and functionality is not based on the order in which events occur, so there are far fewer possibilities and corner cases.



As I continued to refactor the Character this method produced much cleaner communication between actor modules. In Powderkeg Pals I am now using the architecture to manage updates for most character state parameters including character collision and visibility and I'm quite happy with the results.