Crash when getting a game instance subsystem.

Hi! I’m trying to make the game instance call a callback when the level is done loading its actors:

void UPKGameInstance::Init()
{
	Super::Init();

		FWorldDelegates::OnWorldInitializedActors.AddLambda([this](const UWorld::FActorsInitializedParams& Params)
			{
				if (Params.World)
				{
					Params.World->OnWorldBeginPlay.AddUObject(this, &UPKGameInstance::OnLevelDoneLoading);
				}
			});
}

In this UPKGameInstance::OnLevelDoneLoading callback, I’m calling auto SaveGameSubsystem = GetSubsystem<UPKSaveGameSubsystem>();, UPKSaveGameSubsystem being a UGameInstanceSubsystem. The issue is that, 1/3 times, GetSubsystem will crash because the subsystem map is invalid. Here is the callstack:

	[Inline Frame] UnrealEditor-Engine.dll!TSet<TTuple<UClass *,USubsystem *>,TDefaultMapHashableKeyFuncs<UClass *,USubsystem *,0>,FDefaultSetAllocator>::FindId(const UClass *) Line 872	C++
 	[Inline Frame] UnrealEditor-Engine.dll!TSet<TTuple<UClass *,USubsystem *>,TDefaultMapHashableKeyFuncs<UClass *,USubsystem *,0>,FDefaultSetAllocator>::Find(const UClass *) Line 919	C++
 	[Inline Frame] UnrealEditor-Engine.dll!TSet<TTuple<UClass *,USubsystem *>,TDefaultMapHashableKeyFuncs<UClass *,USubsystem *,0>,FDefaultSetAllocator>::Find(const UClass *) Line 937	C++
 	[Inline Frame] UnrealEditor-Engine.dll!TMapBase<UClass *,USubsystem *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass *,USubsystem *,0>>::FindRef(const UClass *) Line 668	C++
 	UnrealEditor-Engine.dll!FSubsystemCollectionBase::GetSubsystemInternal(UClass * SubsystemClass) Line 51	C++
 	[Inline Frame] UnrealEditor-SandboxUE5.dll!FObjectSubsystemCollection<UGameInstanceSubsystem>::GetSubsystem(const TSubclassOf<UPKSaveGameSubsystem> &) Line 158	C++
 	[Inline Frame] UnrealEditor-SandboxUE5.dll!UGameInstance::GetSubsystem() Line 464	C++
 	UnrealEditor-SandboxUE5.dll!UPKGameInstance::OnLevelDoneLoading() Line 93	C++
 	[Inline Frame] UnrealEditor-SandboxUE5.dll!Invoke(void(UPKGameInstance::*)()) Line 66	C++
 	[Inline Frame] UnrealEditor-SandboxUE5.dll!UE::Core::Private::Tuple::TTupleBase<TIntegerSequence<unsigned int>>::ApplyAfter(void(UPKGameInstance::*)() &) Line 327	C++
 	UnrealEditor-SandboxUE5.dll!TBaseUObjectMethodDelegateInstance<0,UPKGameInstance,void __cdecl(void),FDefaultDelegateUserPolicy>::ExecuteIfSafe() Line 618	C++
 	[Inline Frame] UnrealEditor-Engine.dll!TMulticastDelegateBase<FDefaultDelegateUserPolicy>::Broadcast() Line 178	C++
 	UnrealEditor-Engine.dll!TMulticastDelegate<void __cdecl(void),FDefaultDelegateUserPolicy>::Broadcast() Line 975	C++
 	UnrealEditor-Engine.dll!UWorld::BeginPlay() Line 4890	C++
 	UnrealEditor-Engine.dll!UGameInstance::StartPlayInEditorGameInstance(ULocalPlayer * LocalPlayer, const FGameInstancePIEParameters & Params) Line 547	C++
 	UnrealEditor-UnrealEd.dll!UEditorEngine::CreateInnerProcessPIEGameInstance(FRequestPlaySessionParams & InParams, const FGameInstancePIEParameters & InPIEParameters, int InPIEInstanceIndex) Line 3163	C++
 	UnrealEditor-UnrealEd.dll!UEditorEngine::OnLoginPIEComplete_Deferred(int LocalUserNum, bool bWasSuccessful, FString ErrorString, FPieLoginStruct DataStruct) Line 1626	C++
 	UnrealEditor-UnrealEd.dll!UEditorEngine::CreateNewPlayInEditorInstance(FRequestPlaySessionParams & InRequestParams, const bool bInDedicatedInstance, const EPlayNetMode InNetMode) Line 1889	C++
 	UnrealEditor-UnrealEd.dll!UEditorEngine::StartPlayInEditorSession(FRequestPlaySessionParams & InRequestParams) Line 2894	C++
 	UnrealEditor-UnrealEd.dll!UEditorEngine::StartQueuedPlaySessionRequestImpl() Line 1203	C++
 	UnrealEditor-UnrealEd.dll!UEditorEngine::StartQueuedPlaySessionRequest() Line 1106	C++
 	UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1777	C++
 	UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 517	C++
 	UnrealEditor.exe!FEngineLoop::Tick() Line 5367	C++
 	[Inline Frame] UnrealEditor.exe!EngineTick() Line 66	C++
 	UnrealEditor.exe!GuardedMain(const wchar_t * CmdLine) Line 202	C++
 	UnrealEditor.exe!LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 233	C++
 	UnrealEditor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 282	C++

As far as I can tell, all game instance subsystems should be valid and part of a valid subsystem map in the game instance by the time my callback is called. Any idea as to why it’s crashing sometimes?

1 Like