I’m working on migration to Iris and found a peculiar problem. We have Widgets in the AHUD
which initialize a cached HUD variable from APlayerController
on NativeConstruct
. With traditional replication it works fine, the order is as follows:
APlayerController::ClientSetHUD
RPC comes in,APlayerController
creates HUD, but doesn’t initialize widgets, since theOnRep_ReplicatedHasBegunPlay
hasn’t come yet so noBeginPlay
s.OnRep_ReplicatedHasBegunPlay
comes in,BeginPlay
s are dispatched- In
BeginPlay
ofAHUD
widgets initialize and can retrieve the pointer to HUD fromAPlayerController
But with Iris I have non-100% repro where sometimes these come in a different order like this:
OnRep_ReplicatedHasBegunPlay
comes in firstAPlayerController::ClientSetHUD
RPC comes second and while creating HUD it also runsBeginPlay
and initializes widgets, which try to retrieve HUD fromPlayerController
, but can’t - we’re in the middle ofAHUD
creation!- Widgets end up without HUD and misbehave until we refresh the UI manually.
Creation of HUD happens in APlayerController::ClientSetHUD_Implementation
:
MyHUD = GetWorld()->SpawnActor<AHUD>(NewHUDClass, SpawnInfo );
This happens during SeamlessTravel
to the server I see the following snippet of code in FSeamlessTravelHandler::Tick
at the very end:
AGameModeBase* const GameMode = LoadedWorld->GetAuthGameMode();
if (GameMode)
{
// inform the new GameMode so it can handle players that persisted
GameMode->PostSeamlessTravel();
}
// Called after post seamless travel to make sure players are setup correctly first
LoadedWorld->BeginPlay();
PostSeamlessTravel
is the one that sends APlayerController::ClientSetHUD
RPC and BeginPlay
is the one that sets the replicated begin play which has OnRep_ReplicatedHasBegunPlay
RepNotify
. So it seems like it is meant to first all the player/HUD setup and only then perform BeginPlay
s.
In the docs (Replicated Object Execution Order in Unreal Engine | Unreal Engine 5.6 Documentation | Epic Developer Community) it says that replicated properties indeed come after RPCs, but it is not clear if this only holds true for a single actor or between actors also. In this case we have an RPC for APlayerController
and property for AGameModeBase
, which are different actors.
If replication order should be guaranteed here, then Iris seems to break this guarantee. If not - then I suppose our widgets should not try to get HUD during construction, since it can happen during HUDs own construction. Also the seamless travel comment then must be misleading, since players would not necessarily have the time to be setup first. Could someone clarify?
EDIT: Actually on the second thought I’m not sure how not to use HUD here since we need data it has during initial widget setup.