1 of 18

The Gameplay Abilities Module

Michael Chapman

(@woppin on Discord)

2 of 18

Gameplay Abilities

  • A Common Plugin shared by Paragon and Fortnite
  • Handle gameplay mechanics + their replication and prediction

Why?

  • Allow engineers to handle the network prediction and replication in C++
  • Allow designers to work in blueprint to tweak mechanics easily
  • Generic enough to support anything the design team comes up with
  • Optimised to reduce network load

3 of 18

Gameplay Abilities

Resources available:

4 of 18

Concepts

AbilitySystemComponent

AttributeSets

GameplayTags

GameplayEffects

GameplayCues

GameplayAbilities

GameplayTasks

GameplayEvents

5 of 18

Gameplay Abilities : AbilitySystemComponent

Central point for coordinating everything

Attach to any actor implementing IAbilitySystemInterface

AbilitySystem = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystem"));

On pawns after possession: AbilitySystem->InitAbilityActorInfo(this, this);

Relatively lightweight, attach to anything that should receive effects or activate abilities

6 of 18

Gameplay Abilities : AttributeSets

Store replicated floats wrapped in a struct

UPROPERTY(Category = "Attribute", EditAnywhere, ReplicatedUsing = OnRep_Health, BlueprintReadWrite) FGameplayAttributeData Health;

UFUNCTION() void OnRep_Health() { GAMEPLAYATTRIBUTE_REPNOTIFY(UBaseAttributeSet, Health); } static FGameplayAttribute AttributeHealth();

Account for temporary changes without losing base

AbilitySystem->GetNumericAttribute(UBaseAttributeSet::AttributeHealth());

AbilitySystem->GetNumericAttributeBase(UBaseAttributeSet::AttributeHealth());

7 of 18

Gameplay Abilities : AttributeSets

Attribute Change Events

void PreAttributeBaseChange(const FGameplayAttribute& Attribute, float& NewValue) const;

void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue);

Used to clamp values Eg. health <= max_health

void PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData &Data);

Used to trigger actions as a result of attribute changes, eg health < 0 -> do_ragdoll

bool PreGameplayEffectExecute(struct FGameplayEffectModCallbackData &Data);

Used to modify or discard the values passed into an effect execution.

8 of 18

Gameplay Abilities : GameplayTags

If attributes are the ‘float’ part of describing the game state, tags are the ‘bool’ part. Can be applied locally and have state managed manually:

AbilitySystem->AddMinimalReplicationGameplayTags(InitialTags);

More commonly applied via effects and replicated. Can be applied multiple times and stack.

Triggers events on both client and server

FOnGameplayEffectTagCountChanged& LitheCallback = AbilitySystem->RegisterGameplayTagEvent(FGameplayTag::RequestGameplayTag(UGlobalData::LitheTag), EGameplayTagEventType::AnyCountChange);

LitheCallback.AddUObject(this, &ABaseCharacter::SetLithe);

9 of 18

Gameplay Abilities : GameplayEffects

Predictively applied when done via an ability

  • Can modify attributes
  • Can add/remove tags
  • Can be instant, have set duration, or be infinite
  • Can trigger a Cue
  • Can have tags itself
  • Can be blocked by tags on the source or target
  • Can stack, and overflow the stack
  • Can trigger other effects
  • Can remove other effects
  • Can trigger events
  • Can have a context attached to it, including a FHitResult.

10 of 18

Gameplay Abilities : GameplayEffects

Can be applied via an ability, or using the ASC of the target. The latter won’t be predicted

  • Create GameplayEffectSpec from class
  • Add or Remove tags
  • SetByCallerMagnitude
  • Add Effect Context
  • Apply Effect Spec to Self/Target

The blueprint nodes for use within abilities omit the middle 3 steps.

11 of 18

Gameplay Abilities : GameplayCues

Cues encapsulate cosmetic effects

  • Driven by a tag namespace ‘GameplayCue’
  • Can be triggered by GameplayEffects
  • Can be executed by a predicting client in ability and replicated out
  • Can be executed locally and not replicated

Cues hook into several events from the cue manager

  • OnActive
    • Called when GameplayCue is activated.
  • WhileActive
    • Called when GameplayCue is active, even if it wasn't actually just applied (Join in progress, etc)
  • Executed
    • Called when a GameplayCue is executed: instant effects or periodic tick
  • Removed
    • Called when GameplayCue is removed

12 of 18

Gameplay Abilities : GameplayAbilities

  • Provide a (optionally) network-predicted way of interacting with all of these elements
  • Lots of tag options:
    • Cancel other abilities
    • Block other abilities from activating
    • Require tags to activate
    • Block from activating
    • Apply to owner when activated
  • Instancing:
    • Per Actor
    • Per Execution
    • Non Instanced

  • Net Execution Policy
    • Local predicted
    • Local
    • Server Initiated
    • Server Only
  • Cooldown effect class
  • Cost Effect class

13 of 18

Gameplay Abilities : GameplayAbilities

  • Most player abilities will be local predicted. This will have the ability graph run on both the client and the server.
  • Often there will be a WaitTargetData node at the beginning. This allows the player to visualise aiming.
  • The cooldown and cost will be applied when ‘CommitAbility’ is used.
  • All paths must lead to EndAbility, or the UGameplayAbility instance will not be cleaned up.

14 of 18

Gameplay Abilities : GameplayAbilities

Simple ability that applies an effect to the caster

15 of 18

Gameplay Abilities : GameplayAbilities

Simple ability that spawns a projectile.

16 of 18

Gameplay Abilities : GameplayTasks

  • Flexible task running framework, can be used separately from GameplayAbilities
  • The GAS component inherits from the task management component
  • bSimulatedTask
  • bTickingTask
  • AbilityTask adds some convenience pieces on top of GameplayTask
  • Designer focused

17 of 18

Gameplay Abilities : GameplayEvents

  • Trigger things from other things.
  • Associated with a tag and a UObject payload
  • Trigger Abilities
  • Wait for Event

18 of 18

Acknowledgements

  • Thanks to the many friendly folks on the discord channel:
    • @Kaz for taking the time to write everything up initially
    • @jackblue for helping me through the early stages
    • @Roy Awesome, @Dartnalla, @Boolean Fiasco and everyone else who has helped to build up the collective knowledge around this plugin.
    • Finally, best of luck to @Acren and his colleagues, who are working on Hyper-Jam down in Melbourne, which is built on the GAS.