I am making a game with C#/Unity, and have devised a Client-Server system to update the positions and directions of all units in play ten times a second. My biggest concern is that the more units running about, the more likely it is that a correction event will come too late.

The simplest way of handling that is pausing the client to apply changes and catch up, but this cannot be used to excuse suboptimal code.

Previously this was happening a lot, and after using Stopwatch I realised the issue was BinaryFormatter being slow (often clocking 7-9ms to Serialize for 80ish units in motion). So I changed BinaryFormatter to BinaryWriter/Reader and things are much smoother now.

However I suspect more issues. Please comment if I need to provide more information or code. Long explanations welcome.

1 Answer
1

Implementation

A unit's position can never be set to 0 on any of the cardinal axes: The client will just discard the change! I don't think this is intended. Maybe switch over ucf.type instead of comparing new values to 0 in UnitCorrections?

A unit's position will be updated wrongly if it moves on either the x-axis or the z-axis: The updates are only sent if both x- and z-coordinates have changed!

UnitCorrectionFloat.type should probably be an enum (possibly with [Flags] attribute to allow movements of any type).

Design / Scalability

PrepareUnitCorrections has to iterate over all the units. Since there probably already is a method to update the units anyways, why not add the units whose position changed into a HastSet<Unit> there and only iterate over that set of changed units in PrepareUnitCorrections? (Clear it afterwards to only record new changes!)

Every change in a unit's position is sent to every player - regardless whether they actually need that information. If the player can't see the unit (e.g. it's in the fog of war / outside of vision radius), the changes of those units don't need to be sent to that specific player.

Also, only changes in position are sent. It might be more efficient to only send changes in the velocity / movement target (i.e. the clients can move the units on their own and corrections only need to be sent in case the velocity / movement is changed instead of the position). After all, if the movement is constant, it's easy to calculate where a unit will be.

\$\begingroup\$Thank you, I have implemented i1, i2, and i3. I didn't even notice i2 was an issue! As for d1, that is somewhere deeper in Unity and I don't have a general update function yet. d2, I haven't implemented fog yet, but it's definitely to consider. d3 is interesting, though I fear it may lead to desyncs since movement speed is based in floats, the guts of which are pretty deep in Unity. I can't guarantee determinism with velocity, but good idea if I could!\$\endgroup\$
– inappropriateCodeOct 29 '17 at 12:38