After some years of game programmer, I suddenly found myself implementing a specific static functions and data structs basically every time I start a new project: a sort of a general purpose library I update and increment at every project and that I take with me to the next one, to avoid reimplementing the same stuff over and over again. Counter-based bools are an example of such implementations. This post might seem like an over-conceptualization of a very common programming technique, but I believe that sometimes it’s useful to stop one minute and think about the utility of the tools we end up implementing, in terms of optimal use cases and performances.

The problem

Let’s say that you implemented a locomotion system for your player character, and you have a bool property “Block Walking Off Ledges” that you set to true whenever you want to prevent that character from walking off ledges. Now, you implement a melee attack system with some root motion on your attack animations, and you want to keep the character on the ground while performing an attack: no problem, you set the bool value to true once the melee attack begins and you set it back to false once the attack ends.

Some weeks of development later, you now have elevators, and you don’t want your character to fall down while using them. You need the elevator system to be aware of the possibility of your character doing a melee attack, and you need the melee attack system to be aware of elevators, so that each one avoids setting the property back to false in case the other system is still active: you just introduced a dependency.

Moreover, fast forward to some months later, you now also have a little dialogue playing while on top of the elevator, and the dialogue system is supposed to allow the character to move during the conversation while preventing them from walking off ledges. You now need to introduce a new dependency, and the code already became tragically spaghettified. You need another approach: you need to convert your bool into a counter.

Counter-based bools

The concept behind this is quite straight-forward: instead of implementing your flag as a plane bool, you use an integer counter. Whenever you want that property to be true, you increment the counter by one, and you decrement it once the system doesn’t need it anymore. The system that is reading that value (in our example, the locomotion system) will read a true value whever the counter is greater than zero: this ensures that each piece of code that needs that property to be enabled will not break another system with the same need once it resets it back (decrementing the counter). For the sake of clarity, the example below is summarized in this sequence diagram:

This technique comes with some constraints:

  • Each system that increments the counter is also responsible of decrementing it. Not doing it would result in the property being true undefinitely just because of an elevator not being properly deactivated three hours before.
  • Each system that writes on the counter is responsible of doing exactly one decrement for each single increment. In other words, no things like “I will set the value to true at each frame as long as the elevator is active, just to be sure”. You need to be aware of exactly when you need that property to be true and when you don’t need it anymore.

An implementation in Unreal Engine

Instead of reimplementing the same counter over and over again, let’s try to encapsulate the logic into a struct and let’s try to make it also accessible from blueprints. The implementation is quite straight-forward:

USTRUCT(BlueprintType)
struct YOURPROJECT_API FCounterBasedBool
{
private:
  uint8 Counter = 0; // it's unlikely that we will need a bigger integer

public:
  FORCEINLINE void Set(bool bValue)  
  {
    Counter += (bValue? 1 : -1);
  }

  FORCEINLINE bool Get() const { return Counter > 0; }
};

We don’t need to make the counter accessible from blueprints. We want to keep it safe and protected from improper uses, so we are going to wrap the two functionalities we need (the setter and the getter) into a pair of static UFunctions.

UCLASS(DisplayName = "Counter-Based Bool Library")
class YOURPROJECT_API UCounterBasedBoolLibrary : public UBlueprintFunctionLibrary
{
public:
  UFUNCTION(BlueprintCallable)
  static void SetCounterBasedBoolValue(UPARAM(ref) FCounterBasedBool& BoolProperty, bool bValue)
  {
    BoolProperty.Set(bValue);
  }

  UFUNCTION(BlueprintPure)
  static bool GetCounterBasedBoolValue(const FCounterBasedBool& BoolProperty) 
  {
    return BoolProperty.Get();
  }
};

This is what we obtain in Unreal blueprints. Note that the UPARAM(ref) macro is crucial to able to use a reference to a struct as input pin instead of as output.