Replicating TMaps, what are my options?

There are a number of ways to compute the stats.
The simplest possible way to do this, would be to implement a GetStatValue() function.
This function would simply:

  • get base stat value from base class
  • iterate through all active modifiers, which are arrays of {stat, delta} pairs
  • for the modifiers that affect this stat, update the value
  • return the result

This might feel like it’s “a lot of work,” but, honestly, it will probably never show up in a profile of the game, unless you do something excessively expensive with stat values, or have hundreds of units all with modifiable stats.

If you absolutely have to improve it, then you can keep a map of state → calculated value on the client, and use RepNotify for each of the arrays. When you get the notify, set a “stats dirty” flag. In your GetStatValue() function, if the “stats dirty” flag is set, then re-compute all of the stats, and store them in a local (not-replicated) stat map, and clear the “stats dirty” flag. Then always return the value from the stat map.

You could even check this flag in your Tick() function and recompute there if you needed. Note that replication is never tick precise anyway, so any kind of delay is something you’ll have to live with in a networked game anyway.

Another benefit of a system like this is that save games or character checkpoints can be robust. You will never “drift” between what’s actually applied, and what the calculated value is. If you save a character while it has a temporary buff, that temporary buff affect will still be there when you load it back, and re-applied as appropriate. And when it expires, it will no longer be applied.

Btw, you can keep an array of {stat, delta, expiration time} tuples, if you have many temporary stat changes; that might be easier than keeping separate affects that have to remember to remove their temporary stat affects.
Tuples can be any replication-enabled UObject or Struct class.