Host migration in C++
Drive or extend host migration from C++ with the subsystem, the state component and the snapshot utilities
Host migration in C++
Everything the nodes do lives on UUCIKHostMigrationSubsystem (HostMigration/UCIKHostMigrationSubsystem.h), a game-instance subsystem that survives the world the host took down.
UUCIKHostMigrationSubsystem* Migration = GetGameInstance()->GetSubsystem<UUCIKHostMigrationSubsystem>();
Migration->OnHostElectedNative.AddUObject(this, &UMyGameInstance::HandleHostElected);
void UMyGameInstance::HandleHostElected(const FUCIK_MigrationContext& Context)
{
if (Context.bLocalIsElected)
{
Migration->BecomeHost(FString(), FUCIKCallback<FUCIK_ConnectInfo>::CreateWeakLambda(this, [](const TUCIKResult<FUCIK_ConnectInfo>& Result) { /* hosting */ }));
return;
}
Migration->WaitForHost(0.0f, FUCIKCallback<FString>::CreateWeakLambda(this, [this](const TUCIKResult<FString>& Result)
{
if (Result.bOk)
{
Migration->ReconnectToHost(FUCIKCallback<bool>());
}
}));
}RunMigration() does exactly that sequence, and Seamless mode calls it for you. HandOverHost(Preferred, Callback) promotes another member before the current host leaves. AbortMigration(Error) stops everything. GetPhase(), GetContext(), GetCandidates(), GetPeers() and GetLastSeenEpoch() expose the state; every dynamic event has a ...Native twin.
Events and providers
The lobby and session provider contracts carry what migration needs:
FUCIKLobbyProviderEvents::OnMemberLeftdeliversFUCIK_MemberLeftEventwithReason(EUCIK_LeaveReason) andbWasOwner;OnOwnerChangeddeliversFUCIK_OwnerChangedEventwithPreviousOwnerandbLocalIsNewOwner.UUCIK_LobbyEventsSubsystemfills the previous owner and owner flag from the owner it recorded, so providers only report what they know.EUCIK_LobbyCapability::NativeHostElection(EOS, Steam) tells the subsystem to wait for the service's owner change; otherwise it ranks members (UCIKHostMigrationUtilities::RankCandidates/ElectHost).IUCIKSessionProvidergainedRegisterEvents,PromoteMember,SetSessionAttributes,GetSessionAttributesandQueryMembersbehind theEvents,PromoteandAttributescapabilities;UUCIK_SessionEventsSubsystemfans them out.IUCIKLobbyProvider::ClearHostAddressremoves any explicit host address the old owner published (Steam'sGameServer*keys) so the connect string resolves to the current owner again.
Announcements are plain attributes: UCIKHostMigrationUtilities::MakeClaim, MakeReady and ParseAnnouncement read and write UCIK_MigrationEpoch, UCIK_MigrationState, UCIK_MigrationHost, UCIK_HostHandle and UCIK_ConnectString.
Peers
On a listen server UCIK adds UUCIKPeerListComponent to the game state and UUCIKPlayerLinkComponent to every player controller. The link reports the client's UCIK handles to the host; the peer list replicates handle, ping, join order, player id and (Direct IP) address to everyone. RegisterPeer(Handle, Address) sets the address the game knows; the host publishes per-member UCIK_Ping_<handle> and UCIK_JoinOrder_<handle> lobby attributes so members can rank each other later.
Seamless state
UUCIKMigrationStateComponent marks an actor for capture. UCIKWorldSnapshotUtilities::Capture walks tagged actors and player states into an FUCIK_WorldSnapshot; Restore matches placed actors by id, spawns missing ones deferred, applies transform, velocity and SaveGame properties, then re-links references. References to tagged actors are written as ucik-mig:<guid>[/<component>] by FUCIKMigrationWriter and resolved by FUCIKMigrationReader; other object references are written as paths, so assets and CDOs round-trip and untagged runtime actors become null.
The subsystem captures on a timer on clients (SnapshotIntervalSeconds) and inside GEngine->OnNetworkFailure() before the engine tears the world down, restores on the new host at FWorldDelegates::OnWorldInitializedActors, and finishes each returning player when its link reports (OnPlayerRestored). Override OnBeforeCapture / OnAfterRestore on the component to hook the game's own bookkeeping.
Test seams: SetTravelDriver(TSharedPtr<IUCIKTravelDriver>) replaces listen-server hosting and travel; IngestHostLost, IngestOwnerElected, IngestAnnouncement and IngestPeers feed events without a service. See Source/UCIKCore/Private/Tests/UCIKHostMigrationTests.cpp and UCIKSnapshotTests.cpp.