How-To: Wait for the Experience

Goal: run code once the experience has finished loading, without depending on BeginPlay ordering.

Prerequisites
How-To: Get the Building Blocks step 1.

Actors spawn before the experience finishes loading, so anything an experience's actions set up - a component, a widget, an ability grant - does not exist in BeginPlay. Every registration path here is call-or-register: if the experience already loaded, your callback fires immediately rather than never.

1. Register a callback

Event BeginPlay -> Wait For Experience Ready, then run your setup from the On Ready pin. The node takes a world context and nothing else.

Verify
Add the registration to an actor placed in the level and to one spawned late. Both fire - the late one immediately.

2. Choose a priority tier (C++ only)

Three tiers exist so ordering between systems is explicit rather than incidental. All three fire in the same frame, in order.

FunctionFiresUse for
CallOrRegister_OnExperienceLoaded_HighPriorityFirstWork other listeners depend on.
CallOrRegister_OnExperienceLoadedSecondThe default. Almost everything.
CallOrRegister_OnExperienceLoaded_LowPriorityLastWork that must see every other listener's results - spawning, for example.
Verify
Register a log line on each tier from the same actor; they appear in high, standard, low order.

3. Waiting without naming this plugin's types

Code that must not depend on this plugin (another plugin, a shared module) waits on a ModularGameplay feature state instead. After the low-priority tier, on the server and on every client, the manager calls ChangeFeatureInitState(GameState, "Crimson.Experience.Loaded", ManagerComponent, CrimsonGameplayTags::Experience_Loaded) (CrimsonExperience::ExperienceLoadedFeatureName in CrimsonExperienceTags.h). The same mechanism covers "one system is usable on one actor": plugins that other code waits on announce their own Crimson.SystemReady.<X> feature on the owning actor.

Use Wait For Experience Ready (above) - there is no Blueprint node for raw feature states. For a per-system wait, bind the owning plugin's own Blueprint event instead.

Do not re-register from inside your own retry
With bCallImmediately set, RegisterAndCallForActorInitState fires inline when the feature is already in that state. Calling it from a function that your callback also calls will recurse; unregister in your callback if you only need it once.
Verify
The callback fires once the experience is loaded (immediately if it already was), on the server and on each client, with the manager component as Implementer.

See also

  • API Reference
  • Concept: The Load Sequence
  • API Reference