GAS + Seamless Travel: Best way to preserve ASC state across levels?

Hi,

I’m currently working on level transitions using seamless travel, and I’ve run into some issues with GAS.
The ASC (Ability System Component) for my players is on the PlayerState, and I’m having trouble keeping the GAS state across levels.

Right now, my workaround is:

  1. When seamless travel is triggered, I notify the PlayerState.

  2. The PlayerState takes a snapshot of the GAS (all GEs, attributes, and GAs).

  3. During CopyProperties, I pass this snapshot over.

  4. Once the PlayerState has a valid pawn, I restore/dump the snapshot into the new ASC.

This feels like a lot of manual work just to preserve the ASC state between levels.
Is there a cleaner or more “official” way to handle this with GAS and seamless travel? It really feels like I’m working around the system instead of using the intended flow.

Thanks!

i would have thought the PlayerState persisted by default but if not try adding it By default, these actors will persist automatically:

  • The GameMode actor (server only)

    • Any actors further added via AGameModeBase::GetSeamlessTravelActorList
  • All Controllers that have a valid PlayerState (server only)

  • All PlayerControllers (server only)

  • All local PlayerControllers (server and client)

    • Any actors further added via APlayerController::GetSeamlessTravelActorList called on local PlayerControllers

From what I’ve learned, it’s not recommended to add the PlayerState manually to AGameModeBase::GetSeamlessTravelActorList. Unreal already handles PlayerState during seamless travel, but not by keeping the same instance, instead it creates a new one and calls CopyProperties to migrate data.

That’s also where things get messy with GAS: when CopyProperties is triggered, the Pawn tied to the ASC has already been destroyed. This uninitializes the ASC, so by the time the copy happens, some abilities are already gone.

That’s why in my current setup I don’t try to snapshot inside CopyProperties. Instead, I take the snapshot of the ASC (attributes, GEs, GAs) as soon as seamless travel is triggered, before the Pawn gets removed, and then restore it once the new Pawn is valid.

you could move the ASC to an actor and add the actor to the GetSeamlessTravelActorList?

but honestly i think your method is fine, likely you’ll eventually need a save/load system anyway so may as well reuse it on travel