Open kellyelton opened 8 years ago
Seems reasonable to me. Only issue i perceive is when someone has a very high latency think of in the thousands that could basically slow down the responsiveness down to a major crawl.
so bill send a state change at 00:00 tim sends one at 00:01 bill has a latency of 0:05 tim has a latency of 0:02 tims message arives at 0:02 bills message arrives at 00:05
so if we didn't do the offset, tims state change would run before bills, even though bill sent his first, we just received them out of order
We add artificial lag to the server so we can account for the slowest connection, and make sure that even if you have a slow connection, your state change should still happen in the right order.
so tldr state changes on the client side get sent to the server. and the server processes them with the tickcount set as the lowest latency and when a tickcount gets hit then sends out a diff to all connected clients. That diff should have compounded the changes making sure the clients recieve the most up to date diff based on queue progress and tickcount.
Purpose of this task
To lay out the logic behind the state machine reconciliation and discuss it as necessary before it's implemented
Current
Server pings client so that it can see the clients latency
All messages come in and get two date fields, Received and Sent. Received is when we got the message, Sent is when we think it was sent (Received - Average client latency).
Messages are then put into a queue sorted by Sent date
tickCount == max(clientsAverageLatencies) / 2
The server ticks every
tickCount
and pops items off the queue. It only grabs items that have a Sent date that's <=DateTime.Now - tickCount
. So the server will always be processing the past.After the server processes all of the items it popped off the queue, it'll construct an object to send back that contains the newest state diff, as well as all of the
ID
's ofStateChangeReq
's the server processed at that point(theStateChangeReq
are what are sent by the client, requesting a specific state change. They include id's that the client generates so the client can know which changes it made were applied to the state it receives back)The client then gets the bundle and takes it and applys it to it's cached state object in the clients backend(the client has a state object that sits in memory that's immutable from the client side. It's basically a cached version of what's on the server).
After that is applied, it will apply the diff to the browsers state object. If there's a conflict between data: say the server says that the variable
A
changed to15
and on the client side, the variableA
was changed to1
since the last dump it got(basically if we change the state but haven't got it reconciled with the server yet) it will keep the change made by the client, otherwise we'll end up with visual jitter. This is only going to happen though if we've made a change locally since the last state diff from the server.State dumps into the browser should not trigger any new state updates, but can move items around visually. Basically no game logic should happen as a result of receiving the diff from the server, only visual updates to account for changed state.
Now every time the client changes the browser state, it'll send a message to its backend saying "Hey I updated the state"(this WON'T be triggered by server state dumps). The backend then sends the changes off as they happen to the server as quickly as possible.