I’m trying to set up replication, but I’m not having any luck.
My setup: Play In Editor using 2 players, using a listen server. The relevant actors are a subclass of APlayer, and two subclasses of my Inventory class: a weapon and its ammo. Inventory has bReplicates = true;
in the constructor.
The client window walks over the weapon pickup. In standalone play, the overlap event would call AddToInventory on the Player. For my attempt at handling replication, I restricted the overlap to serverside only, and at the end, added:
if (GetWorld()->GetNetMode() < ENetMode::NM_Client && GetWorld()->GetNetMode() != ENetMode::NM_Standalone)
Client_AddToInventory(n);
And then Client_AddToInventory should notify the client that they picked up the item, adding it to the local copy of the inventory chain. However, the parameter to Client_AddToInventory is NULL. I’ve tried decorating the function with both Client and NetMulticast, and they both result in it being NULL. This would mean that the item hasn’t been replicated to the client, but it should be set to be replicated. Is it an issue if I try to use a pointer to an object in the same tick that it is created?
Full prototype and declaration of the replicated function. Replace ‘NetMulticast’ with ‘Client’ for my other test, but the result is essentially the same.
UFUNCTION(NetMulticast, Reliable)
void Client_AddToInventory(AInventory *n);
A few things, yes you will get into trouble if you are doing something on the server that will be replicated but in the same tick (or even a few ticks later) try to have the client behave assuming the replication already took place.
When you say “in the same tick that it is created” are you referring to the object or pointer? If object then yes that is your issue.
I was commenting on another question almost identical to this one: Weird replication behaviour - Programming & Scripting - Epic Developer Community Forums
Basically, the easiest, most reliable, and safe thing to do is to have the server drive the logic and rely on replication (update your inventory on the server and mark that variable for replication). You can also have the client do things (play the equip animation and whatnot) while the server catches up but the more you do that the more careful you have to be. For example if you have the client switch weapons before the server does what happens when you try to fire? If you keep moving control, such as firing, the client then acts as the authority and all sorts of abuse and problems can occur.
I am referring to the object itself, yes. As in, AmmoObj = SpawnActor(AmmoClass); Character->AddToInventory(AmmoObj);
. So, creating the object and immediately trying to propagate it to the client. I assumed that the engine would be able to create the object on the client and obtain a pointer to it in the same network call. So is that not the case?
And if so, what’s the proper way to handle a situation like this? I can’t exactly have the client sit and wait for a second to guarantee that the object is created before using it.
I was trying to avoid using property replication for this specifically if possible. Most of my knowledge of replication comes from years back when I modded the original unreal, and I found the cause of a crash. In short, if an inventory item was quickly removed and re-added, the replication could update the linked list out of order and generate an infinite loop, leading to a crash. I disallow the exact situation that led to this in unreal, and the replication engine is probably more intelligent now, but I’m still naturally wary about replicating a linked list.
I can certainly try it, though. But what do I do about any other logic I was doing in AddToInventory, or related functions? For example, to play the bringup animation on a weapon, do I simply make an OnRep function for Weapon and locally play the animation whenever the Weapon variable changes?
There’s always a ton of different ways to do any desired action, and for your case using Rep Notify is one way.
If you wanted to remove some of the delay between having the server update your client you could have the client begin playing the weapon switch animation on button press. Granted if the server ever rejects the switch weapon because it is aware of something the client isn’t you’d have to back out of that animation / state on the client.
Well, making the invchain replicated fixed it. The actor is being spawned on the client, so I don’t have any other issues with that. I guess I’ll just have to add some extra protection to the linked list to be absolutely certain no linked lists get created. Better safe than sorry, after all. Thanks.