Attach the Gameplay Abilities handler
- Open the Save Rule that matches the actors whose Ability System Components save, or the actor’s Rolly Save component (see Choose what saves).
- Under Handlers, add an entry, click its class button and pick Gameplay Abilities under Engine State (see Attach engine state handlers).
- Expand the entry to set what it saves; every setting has a default that works without a change.
| It saves | Per Ability System Component |
|---|---|
| Attributes | Each attribute’s base value. Current values follow from the base values and the restored effects |
| Abilities | The abilities given to the component, with their level, input ID, source object and the variables of their instance that have SaveGame ticked |
| Effects | Active effects with a duration or infinite: level, stacks, the time they had left, Set By Caller values, dynamic tags, who applied them and from what |
| Loose tags | The tags your game added to the component itself, with their counts |
- The handler saves the components its actor owns. It does not follow the Ability System Interface, so a component saves once, under the actor that holds it.
- Apply Timing is After Begin Play by default: the values are set on a tick after the actor’s Begin Play, never inside the load’s own calls or an ability’s. When Asked waits for Apply Saved Values. Before Begin Play is not offered: the entry shows it disabled, and Data Validation warns (TimingNotOffered) where it is set anyway.
- Only the server or a standalone game sets ability system state, since every call that restores it needs authority.
- Components narrows the components it takes by name, class or component tag.
Save a player’s ability system
Many games keep the player’s Ability System Component on the Player State. Attach the handler in a rule that matches your Player State class; the Player State saves with the local player, beside its pawn and controller (see Save the player). A rule that matches only your character class finds nothing when the character’s Ability System Interface returns the Player State’s component, and its Data Validation warns (NoTargets) with that fix.
A component on the player’s pawn saves with the pawn: attach the handler in a rule that matches the pawn’s class.
Save AI bots
With Include AI Controller (on), a pawn an AI controls also saves the Ability System Components of its AI controller and of that controller’s Player State, as bots set up with a Player State have them. Controllers and their Player States never save themselves, so attach the handler to the pawn.
- The values on a controller wait until the pawn has its AI controller, with its Player State; Rolly Save checks at the apply and again when the pawn gets a controller. A pawn still without one keeps its values waiting, and the Message Log says why (AINotReady); Apply Saved Values for the pawn sets them later.
- Spawn Missing Controller (on) gives a pawn that a load spawned again its AI Controller Class. Off, its values wait until your game possesses it and calls Apply Saved Values.
- A pawn a player controls takes none of them: the player’s Player State saves through a rule of its own.
- Before play the editor cannot see the Player State an AI controller makes, since the game mode picks its class: for a pawn whose AI Controller Class has Wants Player State ticked, Effective Settings shows “the Player State of” that controller, and Data Validation does not warn.
Choose which attributes save
- Save Attributes (on) saves every attribute of every attribute set the component has, but the component’s own duration attributes.
- Attributes saves only the attributes it lists; Not Saved Attributes leaves some out, such as a Damage meta attribute.
- Base values are set before the effects apply, so effects that read attributes as they apply see them, and again after, so a clamp against an attribute the effects change, such as Health against a buffed MaxHealth, keeps the saved value. Attribute change events can fire twice for one attribute during a load.
- Add Missing Attribute Sets (off) adds a set the save holds values for when the component lacks it, such as one your game adds when an item is equipped. Off, those values are left out, with HandlerTargetMissing in the log.
Choose which abilities save
- Save Abilities (on) saves the abilities given to the component and gives them again after a load.
- Abilities an effect gives come back with that effect, and abilities removed once they end are never saved.
- An ability your game gives again before the handler applies, such as in Begin Play, is matched to the saved one, by class and source, and takes its saved level and input ID: it is not given twice.
- Save Ability Variables (on) saves the variables with SaveGame ticked on an Instanced Per Actor ability’s instance, such as a combo counter, and sets them again by name and type. An Instanced Per Execution ability has no instance to save.
- A variable of a struct whose code writes its own bytes, or of a type a save cannot hold (a weak, lazy or interface reference, a delegate or an optional, also in an array, set or map, or a C++ fixed-size array), is not saved: the save leaves it out and succeeds, the Message Log says so once per session (VariableLeftOut) and each save’s Issues list it. Use a struct of plain variables, an object or class reference, or a TArray.
- Abilities active at the save are given again, not active. An ability your game activates when it is given or when its avatar is set starts again.
Choose which effects save
- Save Effects (on) saves the active effects that have a duration or are infinite, and applies them again with the time they had left. Instant effects are never active, so nothing of them saves.
- An effect your game applies again before the handler applies is matched to the saved one, by class and instigator, and updated in place: level, stacks, Set By Caller values by tag and the time left.
- The effect keeps its saved duration, also one from attributes or Set By Caller values, and Set By Caller values come back exactly. Magnitudes the effect captures from attributes are captured again from the attributes at the load.
- A periodic effect with Execute Periodic Effect on Application executes once more on the tick after the load, and its period starts again then.
- Application requirements, immunity and a chance to apply below 100 % run again: an effect the engine refuses is left out, with EffectNotApplied in the log.
- The instigator and effect causer save when they are saved actors; the component’s own actor and avatar come back as the restored effect’s context takes them. An instigator that does not save, such as an unsaved trap, saves as empty, with an UntrackedObject line in the save’s Issues, and the restored effect takes the component’s own actor.
Choose which loose tags save
- Save Loose Tags (on) saves the tags your game added with Add Loose Gameplay Tag, with their counts. Tags that effects grant and that active abilities own come back with them, and GameplayCue tags never save.
- Loose Tags saves only these tags and their children; Not Saved Loose Tags leaves tags out, with their children.
- Loose Tag Replication sets how restored tags replicate: None, as Add Loose Gameplay Tag does by default, or Count to Owner, as Add Loose Gameplay Tag with Should Replicate.
- Loose tags are set first in the apply, since effects’ application requirements and abilities’ activation read them.
Keep what your game gives itself out of saves
Effects and abilities your game applies after every load, such as spawn protection or an ability your equipment system grants again, must not save, or they double:
- Add the tag Rolly.Save.NotSaved to the effect’s or ability’s Asset Tags: every rule leaves it to your game. It is in Not Saved Effect Tags and Not Saved Ability Tags by default.
- Or list the classes in Not Saved Effects and Not Saved Abilities, or other tags in the two tag lists.
An effect or ability left out this way is never saved, matched or removed. What your game gives again before the handler applies, such as in Begin Play, is matched instead of doubled; what it gives again after, such as in its own On Rolly Save Loaded, doubles unless it is left out this way.
Decide what happens to what the save lacks
Not in the Save decides about abilities, effects and loose tags the component has and the save does not hold:
- Remove in Place (default): removed when the load keeps the current map or loads a part, since the actor was there before the load; kept on actors the load made fresh, at a map’s load, a remembered level, a level that streams in or a respawn, so an ability an update gives at start stays.
- Remove: always removed.
- Keep: never removed.
Effects and abilities left to your game are never removed, and abilities an effect gives go only with their effect.
Play with several players
The handler restores on the server; clients see what the engine replicates:
- Active effects replicate with the component’s replication mode, Full by default; with Minimal only their tags and cues.
- Attribute values replicate when your attribute set replicates them.
- Granted abilities replicate to the owning player.
- Tags of effects and active abilities replicate; restored loose tags replicate with Loose Tag Replication Count to Owner.
- Remote players’ Player States do not save in this version (see Save the player).
See what the handler takes and sets
- Effective Settings of a Rolly Save component shows the handler’s line with what it takes on that actor, counted as saves count it: “Gameplay Abilities · 1 ability system”, adding “and 1 on BP_BotController” for components of an AI pawn’s controller and that controller’s Player State, or “the Player State of BP_BotController” before play. A line that reads “finds nothing” gives the reason and the fix in its tooltip, as NoTargets does in Data Validation (see Check your save setup).
- Data Validation of a Save Rule or Rolly Save component reports an entry of the handler’s lists that is ignored (BadEntry): an empty entry, a class that cannot be loaded or is of another kind, such as an effect in Not Saved Abilities, an entry listed twice, an attribute its set no longer has, an attribute both Attributes and Not Saved Attributes list, and a tag your project no longer has.
- The Gameplay Debugger’s Rolly Save category shows, under the handler’s line, one line per component: what the last load set, such as “3 attributes, 2 abilities, 1 effect, 1 loose tag set on AbilitySystem”, or before a load what a save would take, without “set” (see See what an actor saves while you play).
Change abilities and effects after release
The handler sets its values a tick after the load reported, so the lines below go to the log as warnings, not into the load’s Issues.
- Renamed classes and attributes follow your Core Redirects.
- A class, attribute set or attribute that is gone keeps its design, with HandlerTargetMissing; the next save drops it.
- An effect that became Instant is not applied, since it would execute (HandlerValueSkipped); an effect whose duration policy changed applies as it is now.
- An ability or attribute set class that became abstract is not given or added, since the engine makes no object of it (HandlerValueSkipped).
- A class variable of an ability takes a saved class only when it is the variable’s class or a child of it: one you narrowed keeps its value when the save holds a class of another kind (HandlerValueSkipped).
- A value an edited or damaged save holds that no effect can take, such as a time below zero or an unknown tag, is skipped with HandlerValueSkipped; a record with more entries than a save holds sets the first ones, with HandlerEntriesDropped.
Save values of your own effect context
A C++ subclass of the handler (URollySaveGASHandler) saves members of your game’s effect context type: override CaptureContextValues to write them into a property bag and ApplyContextValues to set them on the restored effect’s context. The actors list and the hit result of a context are not saved.
#include "RollySaveGASHandler.h"
void UMyGASHandler::CaptureContextValues(const FGameplayEffectContext& Context, FInstancedPropertyBag& OutValues) const
{
if (Context.GetScriptStruct() == FMyEffectContext::StaticStruct())
{
OutValues.AddProperty(TEXT("HitZone"), EPropertyBagPropertyType::Name);
OutValues.SetValueName(TEXT("HitZone"), static_cast<const FMyEffectContext&>(Context).HitZone);
}
}What is not saved
- Where an active ability was: abilities are given again, not active.
- The time to a periodic effect’s next execution.
- Magnitudes captured from attributes when the effect was first applied.
- Members of your effect context type, unless a C++ subclass saves them.
- Effects your game makes at run time from no class.
- Remote players’ ability systems.