Tuesday, December 29, 2015

architecture - How often to update a Game Client about the World?



Using socket.io, I have a communication similar to that of other MMORPGs, a steady connection with messages.


In my design so far, the client sends the player's position and animation frame with every update frame. When the server gets that message, it broadcasts it to all the clients, which will then move the graphic accordingly.


Would it be a better idea to 'collect' these and broadcast them, say, once in 1/10 of a second?


Also, should the client send many different messages (exp gained, clicked on item) as soon as they occur or rather just one collected? The first would be implemented easier.



Answer



I am going to approach this from a high-level discussion and then work towards your questions. For the sake of disclosure, I have no personal experiencing using socket.io but a lot of exposure to the problem space with regards to MMORPGs.


The design of an MMORPGs engine's network architecture and/or the selection of a middle-ware or open source project to provide the functionality is one of the more challenging decisions influenced by the game design, budget and technical expertise of the team. The ultimate choice will influence other architectural decisions (and sometimes design decisions as well).


As developers of MMORPGs, we plan for great success (often also known as catastrophic success) where large numbers trigger warning lights and sirens. One of the scary large numbers that crops up is in algorithms that are N-squared (N^2 hereafter), in your question the first thing that jumped out to me is that it sounded like the design called for an entity to broadcast information to all other connected entities. This is the classic example of an N^2 problem.


MMOs generally approach addressing N^2 issues by attacking the problem in several different ways; awareness systems (situational, spatial, etc) where an entity is aware of some subset of all of the other entities, partitioning players into different "shards", partitioning players in "zones" and/or instancing, implementing game mechanics that discourage too many players from congregating together (Asheron Call's teleport storms), etc.


Most MMORPGs and many FPS engines have fairly sophisticated networking architectures that support a variety of features including:




  • reliable and unreliable communication pathways (TCP, custom implementations of reliable UDP and UDP packets)

  • bandwidth shaping (prioritization, lifetimes, etc)

  • automatic replication of field/viarable data and function calls

  • atomic sets of data (i.e. data that is communicated together)

  • discrete updates (i.e. where every transition is important)

  • latency correction

  • a variety of tricks to make the client feel responsive


I find that the Unreal Networking Documentation and Valve Networking Documentation provide a good primer on a variety of the issues.



So, now lets approach the questions.



Would it be a better idea to 'collect' these and broadcast them, say, once in 1/10 of a second?



It's hard to provide a simple yes or no answer here...because it depends on the scale (number of observing entities), frequency of updates and size of updates. For example, collecting them all might be horridly wrong if the size of the updates could blow a buffer somewhere.


The client for MMORPGs and FPS games are generally designed such that they will visualize something that "looks" right even if they do not receive an update for many more update frames than is "normal". When using unreliable communication (UDP) you can just expect to lose some number of updates into the void, clients can make up for this by sending more frequent updates than might be used with a reliable transport.


From a cursory review of the socket.io documentation, it looks like it supports both reliable and unreliable (volatile in its terminology) communication pathways.


I'd approach this first by tackling, at what frequency are updates needed...


If a player is moving in a straight-line at a constant rate, a lower update frequency is fine because the observing clients can predict with high accuracy where the player will be at any point in time. When a player is turning in a tight circle or making rapid direction changes, then much more frequent updates are required. Conversely, when a player is not moving at all there is no reason to send out movement updates at all.


No matter what, is probably not (generally) necessary to send updates every frame from the client to the server. The server itself may choose to send messages each frame where it has them, or delay them (see bandwidth shaping, prioritization and update lifetime).



Other types of updates have different characteristics...for example consider a "health" field that is modified when a player or creature is damaged. One way to implement this is broadcast each change immediately when it happens, but this leads to wasting processing and bandwidth if the value is changed multiple times in a frame or consecutive frames (networking architectures that implement bandwidth shaping solve this issue by coalesing the updates to only the most recent is sent to an observing client when they have available bandwidth).



should the client send many different messages (exp gained, clicked on item) as soon as they occur or rather just one collected?



Again, no simple yes or no answer is going to work here. Depending on what precisely you mean by collected...both may be right under different circumstances and also depend on implementation of the networking layer.


Collecting messages for a specific entity to be sent as one message can (depending on implementation) reduce the bandwidth overhead for sending a message (reducing your costs) conversely (depending on implementation, such as field/value mappings communicated by strings) can increase bandwidth requirements compared to a simpler specific message type.


Reviewing the socket.io documentation, it would appear to me that message overhead is on the higher end of the spectrum which would favor collecting updates to send as an aggregate message as opposed to lots of single updates.


I'd recommend reviewing all of the updates you contemplate replicating, for example most MMORPGs and FPSs do not bother to send player clicked on X events to observing clients unless that would result in a state change for an object of which they were aware as well.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...