Data-Heavy Game and Replication (UObjects vs. Structs)

I’m trying to figure out the best way to organize/implement class structure for my game. It’s a sports simulation type game similar to Out Of The Park baseball, so it seems pretty heavy on the data side, with so many classes that a player needs to be aware of at once (I think) (players/coaches/conferences/teams and related statistics).

Initially I had all of these as uobjects as I know I did not want hundreds and hundreds of actors when uobjects would work fine enough. After having some trouble replicating them and discovering this discord and reading that for the most part I should be using structs instead of uobjects unless I need inheritance (which I don’t), I’m at a bit of a crossroads in terms of how to implement multiplayer functionality. Especially since I can’t just totally convert my uobjects to structs because then I can’t run UFunction RPCs on those structs. So here are the options I see:

  1. Don’t try to replicate everything or really very much at all. Use RPCs to retrieve the data when it is needed. (Server RPC GetTeamAStatistics() → calls Client RPC SendTeamStatistics(TeamAStatistics)). This feels clunky and seems like it would have a lot of near duplicative code, as I would need a different Server RPC and different ClientRPC for each context of requesting those statistics. (I could be wrong about this last sentence).

  2. Keep my Uobject functionality, but move stored data into a separate struct that can be replicated by an actor. This would mean calling server RPCs on the Uobject, which would then manipulate the properties on a struct that exists within its outer. This is what I implemented last night, and it seems to work, but feels clunky.

  3. Get rid of the uobjects altogether and replace them with structs, with all the data and functionality. Since I can’t have RPCs on the struct, move them to the structs owning actor. The RPC would be called on the actor, which would then call a (non-UFunction) function on the struct with all the actual functionality. Essentially the Actor owner would just be a conduit for all the actual functionality and properties living on the structs. I thought of this option as I was thinking this through, and seems like the best option, but I haven’t implemented it / tried it yet and I am not sure it would work.

Data Tables and Structs

Structure the Data Tables as you would a relational data base. Have a DT for each Team.

e.g. DT_NY_METS
Row Name (player), Position, GP, AB, R, H, RBI, BB, SO, HR, Avg, icon, etc, etc, etc


  • Pete Alonso, First baseman, 130, 487, 72, 132, 105, 51, 110, 31, .271…
  • Jeff McNeil, Second baseman, 117, 418, 55, 133, 49, 28, 55, 7, .318…

Clients can read them directly, so no need to replicate anything. Additionally DT’s can be loaded at runtime.