Our project has an array of structs used to track information about sections of the level, one struct per section. The array itself and the structs are not replicated. Each client sets this up when they load the level based on static level data. The server just uses RPC’s to tell each client when and how to modify a section’s struct. We then have a bunch of systems that can react to changes in these structs. I’ve used delegates to achieve this. Basically, each system calls AddDynamic on the delegate for each section. Then if that section changes at all, it calls the delegate, which notifies each system, who in turn can decide how (or if) they want to react to that change. Works amazingly well, until we try it in multiplayer!
For some reason, in a multiplayer game the various systems on the first connected client are not responding to changes in the section structs. Any additional connected clients after the first work fine. For example, in a listen server scenario with two players, then the player on the server doesn’t work, while the player on the client works fine. In a dedicated server scenario, the first client to connect doesn’t work, while the second client works fine.
After a lot of debugging, I eventually tracked the problem down to the systems not receiving the call to the delegate. AddDynamic works correctly and if I inspect the delegates registered array by stepping through the code it shows all the systems in there, so it makes no sense to me. When a section changes and it calls the delegate, the systems are never notified even though they’re registered with the delegate!?!?
The sections struct array is set up on the client side inside the game state (non-replicated array). Then AddDynamic is called by each system once they have been created by the player controller, again client side. I thought maybe it might be some sort of network latency issue since the game state itself is replicated. So I tried calling AddDynamic in the Tick function (after waiting 1 second) of each system instead of in BeginPlay… and it worked! So this is telling me that for some reason delegates are not being registered correctly due to some sort of pending network transfer. I tried waiting 0.5 seconds, but that failed. It only works if I wait 1 or more seconds before calling AddDynamic. I find this to be a very dodgy hack as obviously different network conditions would affect the required delay time, which is too unreliable.
Is there anyone that might have a better understanding of how and why this is happening? Ideally, I would like to work out precisely when it would be safe to call AddDynamic and know that it will work.