Is LobbyBeaconState replicated

Hello !

I’m trying to use the Lobby system recently added in the version and I’m asking a question : Is LobbyBeaconState and LobbyBeaconPlayerState replicated when on a client when connected to a lobby ?

I succeeded to connect to a lobby created in another instance of my game (on the same computer). But it seems that i don’t have any LobbyBeaconState neither LobbyBeaconPlayerState in my actor list in the world of my client. And the references to PlayerState and LobbyState are null in my LobbyBeaconClient client side.

I thought they must be replicated because they have the Replicated property.

The LobbyBeaconClient seems to work through replication so maybe the system is intended to only go through this actor ?

Thanks for any clarification and nice work for this system !

I just noticed this question, I’m sorry it wasn’t brought to my attention sooner. The short answer is yes the lobby should replicate that data when you connect using this feature.

ALobbyBeaconHost is setup on the server, it is registered with the AOnlineBeaconHost class that is the main network listener for all beacons

ALobbyBeaconHost (similar to AGameMode as an analogy but not really same in function) will have a ALobbyBeaconState (similar to AGameState)

The client creates a ALobbyBeaconClient instance and connects to the server. The server will establish the connection and notify the user that they are connected.

The client will then call LoginLocalPlayers(), which should establish the necessary user id handshaking to properly create an entry on the server for the client players. At this point the server should make an ALobbyBeaconPlayerState for the client passing it and the ALobbyBeaconState to the client via replication.

Maybe the login step was missed? Maybe there was some error (possibly mine) that is preventing this from happening.

Can you put some breakpoints in your server and client code and see how far this handshaking is getting?

Additionally, these two more obscure functions may have a reason why they aren’t replicating the data (assuming login was called). These are used on the server to determine whether or not the server should replicate data to the client.

bool AOnlineBeacon::IsRelevancyOwnerFor(const AActor* ReplicatedActor, const AActor* ActorOwner, const AActor* ConnectionActor) const;
    
bool AOnlineBeacon::IsNetRelevantFor(const AActor* RealViewer, const AActor* ViewTarget, const FVector& SrcLocation) const;

I wrote this up a little while ago hoping to help people out about beacons, which might be informative as well.

I am having the same issue in my project.

IsRelevancyOwnerFor and IsNetRelevantFor are both returning true.

It looks to me like perhaps the host is creating another client locally, leaving the real client with a “dead” lobby client, while the fresh one lives on in the server. At least that’s what it looks like when I try using some custom replicated values that are set on the client prior to connection (client has all values pertaining to pre-connected state, while server has a fresh set of default values).

Specifically, AOnlineBeaconHost::NotifyControlMessage creates a new client when it receives NMT_BeaconJoin.

Hopefully this points someone in the direction of where GwiGwi and I are going wrong!

Edit: Just ran a sanity check - it does not appear that the client is left with a dead client. When I run a client RPC, the server object has the LobbyState and PlayerState, but when the RPC reaches the client, the LobbyState and PlayerState are null. So it’s not a different object being created causing the issue.

Edit2: It appears that both the client and the server think they are the authority over the beacon client.

Edit3: How would playerstate and lobbystate be replicated, if objects are replicated through the use of a GUID and the client has no knowledge of said objects? I tried manually sending these objects using an RPC - they are non-null on server, but null on client.

The GUID question should be answered by the flow comment/diagram at the bottom of DataChannel.h. There is a handshaking that occurs that tells the server to make its own actor to duplicate the one the client has and to create a GUID that it shares with the client to connect the two actors to each other. The fact that you call RPCs and the client responds on the same pointer should prove that is working properly. There should be no dead actors as you describe.

I had a longer explanation for the following, but I lost it in this silly webform, hopefully this succint answer is just as clear.

Make sure that these variables are set on the beacon state actors, they should be in the base class, but just in case.

bReplicates = true;
bAlwaysRelevant = true;
NetDriverName = NAME_BeaconNetDriver;

The server will call the following, you should only need one client connected during this (use -notimeouts so you can debug it easier)

ServerReplicateActors

  • main function that is going to call all the functions below
  • there will be two calls per frame to this (one for game net driver, one for beacon net driver)

ServerReplicateActors_PrepConnections

  • make sure Connection->ViewTarget is set to the beacon actor owner (should be the ALobbyBeaconClient)

ServerReplicateActors_BuildConsiderList

  • you can put an Actor->GetName().Contains(“Beacon”) check inside the main for loop to narrow down the beacon actors in question (lobbystate/playerstate)
  • make sure it gets added to the list OutConsiderList.Add( ActorInfo );

For each client connection (stick with just one for now)

ServerReplicateActors_PrioritizeActors

  • actors come in as part of ConsiderList variable and are added to OutPriorityList if they are making the next cut
  • again check the actor is in the ConsiderList variable (AActor Actor = ActorInfo->Actor* at top of main loop)
  • these state actors shouldn’t be only relevant to owner (every connection needs a copy)
  • check IsActorRelevantToConnection and it should be true

ServerReplicateActors_ProcessPrioritizedActors

  • again check the actor is in the FinalList (AActor Actor = PriorityActors[j]->ActorInfo->Actor* mid loop)
  • trying to get to Channel->ReplicateActor()
  • shouldn’t have saturated network (Channel->IsNetReady)

I’m ready to help further, but you’ll have to debug this some for me so I can see what is going wrong. This code is well exercised in Fortnite.

I was able to fix the replication of player and lobby state in my project by reordering some of the setup functions on the host.

Make sure you are calling them in the following order:

AOnlineBeaconHost::InitHost()
ALobbyBeaconHost::Init(SessionName)
AOnlineBeaconHost::RegisterHost(LobbyBeaconHost)
ALobbyBeaconHost::SetupLobbyState(MaxPlayers)

If you are calling SetupLobbyState prior to RegisterHost, the lobby state will be unable to set up replication because it can’t find the net driver name. This then chains every time a playerstate is created, grabbing the same empty net driver name.

I investigated this claim and I believe that all that matters here is that RegisterHost must be called before SetupLobbyState because the former sets the owner of the host object which is used in SetupLobbyState to set the beacon name properly. InitHost has to come first, but the Init call is pretty sparse and could arguably occur after RegisterHost.

Thanks for the effort here to help figure this out.

InitHost must be called prior because that’s where the name of the beacon type is set, which is used in setting up callbacks in RegisterHost.

Hey! Not sure, if you’re still active but could you share your lobby creation code with me. I’m struggling setting this up correctly.

PlanixArtz, if your still struggling with implementing beacons, I have released a new plugin for UE4.27, 5.0, 5.1 where I have fully implemented lobby beacons with a bunch of advanced features for party management. Check it out here: Advanced Lobby System in Code Plugins - UE Marketplace