See: UAbilitySystemGlobals::HandlePreLoadMap

GAS features static variables that are modified by both server and client, thus result in issues in single process PIE where they access the same memory. Specifically, GlobalActiveGameplayEffectHandles in ActiveGameplayEffectHandles.cpp is cleared by the client on map switch via the callstack below, and it affects server execution.

This issue impacts GAS behavior when testing in single process PIE with late-joining clients. A user reported on UDN that when a PIE client joins the server (late), that client's PreLoadMap callback to reset GlobalActiveGameplayEffectHandles would clear the active handles for the server, who may be hosting a gameplay session that is long in progress.

UAbilitySystemGlobals is also the same object for server and client in single process PIE. While investigating this, please also do a pass to see whether there are variables in UAbilitySystemGlobals that are written to and investigate whether this can cause issues in PIE.

Steps to Reproduce
  • Have a project with GameplayAbilities plugin enabled
  • Make sure UAbilitySystemGlobals::InitGlobalData() is called
  • Start single process PIE with server and client
  • Put a breakpoint in UAbilitySystemGlobals::HandlePreLoadMap()
  • Do a map switch with the client like console command: open AnyOtherMap
  • It triggers UAbilitySystemGlobals::HandlePreLoadMap(), which clears the static variable for the server as well.

UAbilitySystemGlobals::HandlePreLoadMap(const FString &) AbilitySystemGlobals.cpp:613
[Inlined] Invoke(void (UAbilitySystemGlobals::*)(const FString &),UAbilitySystemGlobals *&,const FString &) Invoke.h:66
[Inlined] UE::Core::Private::Tuple::TTupleBase<TIntegerSequence<unsigned int> >::ApplyAfter(void (UAbilitySystemGlobals::*&)(const FString &),UAbilitySystemGlobals *&,const FString &) Tuple.h:327
TBaseUObjectMethodDelegateInstance<0,UAbilitySystemGlobals,void __cdecl(FString const &),FDefaultDelegateUserPolicy>::ExecuteIfSafe(const FString &) DelegateInstancesImpl.h:551
[Inlined] TMulticastDelegateBase<FDefaultDelegateUserPolicy>::Broadcast(const FString &) MulticastDelegateBase.h:190
[Inlined] TMulticastDelegate<void __cdecl(FString const &),FDefaultDelegateUserPolicy>::Broadcast(const FString &) DelegateSignatureImpl.inl:983
UEngine::LoadMap(FWorldContext &,FURL,UPendingNetGame *,FString &) UnrealEngine.cpp:14413
UEngine::TickWorldTravel(FWorldContext &,float) UnrealEngine.cpp:14341
UEditorEngine::Tick(float,bool) EditorEngine.cpp:1869
UUnrealEdEngine::Tick(float,bool) UnrealEdEngine.cpp:515
FEngineLoop::Tick() LaunchEngineLoop.cpp:5473
[Inlined] EngineTick() Launch.cpp:61
GuardedMain(const wchar_t *) Launch.cpp:190
LaunchWindowsStartup(HINSTANCE__ *,HINSTANCE__ *,char *,int,const wchar_t *) LaunchWindows.cpp:233
WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) LaunchWindows.cpp:282
[Inlined] invoke_main() 0x00007ff76613b1e6
__scrt_common_main_seh() 0x00007ff76613b1c5
<unknown> 0x00007ff843c07034
<unknown> 0x00007ff8443a26a1

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-170257 in the post.

Login to Vote

ComponentUE - Gameplay - Gameplay Ability System
Affects Versions5.05.15.2
Target Fix5.5
CreatedNov 16, 2022
UpdatedJan 29, 2024