while constructing my EntitySystem I reread the valve article about lag compensating for building everything in a way that lag compensation can easily be implemented later on.
That created a question:
How can I find out how long a message needed from the client to the server? Saving the client time into the message does of course not work as one of server or client could have an incorrect running clock. If I measure clientside how long a message and the answermessage need, I have a value that could change immediately the next frame.
Is there a solution that I’m missing? What would be the common way to achieve this?
Edit: maybe one can send the client time to the server, wait for an answer of the server and then send how long the message needed to arrive at the server by dividing the total time needed by 2… Than the server would know the client’s time… Complicated^^
It requires a round trip to calculate latency.
Usually you try to keep some common time, like the server will send its time in messages and the client tries to adjust it’s view of time to be the same. There will be a difference that is equal to latency. If you also include the client’s time in some message back to the server then the server can calculate what the latency is… it will be timeDiff / 2.
To me, it’s more important for the server to know the latency of each client than it is for the clients to know. But the server could always send that average info to the client periodically.
Many applications will warn you and I’ve seen game servers refusing connection if your computer time’s off by too much as this can be used to cheat.
Geo-location based on an IP can be done to fetch the anticipated time on a connected computer. From this you can use a bias from which the client can variate, i.e. ~5 mins as all computers are not synchronized to the second.
Thanks for your answer.
So I will do one round message from the client and one from the server. Then adjust client time and calculate the client’s latency on the server side. Seems not to be too much effort.
Edit: @madjack Could you explain how it can be used to cheat?
Thanks for your answer.
So I will do one round message from the client and one from the server. Then adjust client time and calculate the client's latency on the server side. Seems not to be too much effort.
Edit: @madjack Could you explain how it can be used to cheat?
The client does not really need to know latency. The server is sending server time with every status update. This is the official "game time". The client adjusts its own time to that. It doesn't matter what system time is because the client is not using that for anything.
The client sends its current "game time" with its player control updates. It has to because it's important for the server to know when the state changed. The server can use this to calculate latency.
The client does not need to know latency unless you plan to provide that as information for some reason. Then you can just ask the server for it (since the server will be tracking it).
You cannot accurately predict time between machines even on the same network and there will always be some latency. The geo-based lookup thing is not really useful. We're talking about millisecond timing, not ~5 minute timing.
Edit: I originally read your post as "it's too much effort"... but the info is still good so I left it. :)
The above was from some years ago so I don’t have a readily available link, but I do know that Punk Buster enforces correct time locally.
The client sends its current “game time” with its player control updates. It has to because it’s important for the server to know when the state changed. The server can use this to calculate latency.
I know the second sentence. This sentence is important and the reason why I asked to somehow sync server and client. The "game time" is what is unclear to me. What is the game time in this case? Is this a time the server increments all the time and that is sent to the client upon login or where does it come from?
Every status update that the server sends to the client (20 times a second or whatever) includes the game time.
The client uses this to adjust its local time counter so that it has “game time” as close as it can. (It will be real “game time” - latency but that’s close enough.)
“Game time” is time as far as the client is concerned. Any time-based events are done with that time. So when it sends an event like “forward activated” then it also sends the time that forward was activated… in what the client sees as “game time”. (In reality, I’d do this slightly different but the game time would still be included in the message.)
Presuming that both clocks are moving forward at the same rate (a safe but not entirely accurate assumption) then the “game time” that the server sees from a client should be “local game time” + 2 * client latency. Even if one of the clocks is drifting it is still safe for the server to view that as latency. (And if the latency is off by some margin then you can presume that the client is having issues or depending on how off, that it is cheating.)
Thank you, I do now know how to implement this.
Now I want to ask another question that I’m thinking about since yesterday evening:
I have my entity system that executes one loop each server cycle (let’s assume 20 times per second) and that updates the entity’s components only at the end of the loop. (Because every subsystem should have the same view from start to end of the tick). Now the clients’ inputs come in. In average 3 per tick. They are stored until the next server tick. This is the point I can’t figure out the best way… The InputHandling system should now move the players but that’s complicated. The easier problem first: The Physics System handles collision (e.g. with the terrain). So should I move the player one input forward, call collision detection and then apply the next input? That seems not very entity system like…
More mind blowing: The inputs are from different times due to different latencies. Some just include walking, but one that had a great latency causes a collision with another player whose movement would be blocked from that point of collision on. That needs to be recalculated (maybe?). And all this with an entity system.
That really causes me headache
It’s so complicated in my mind right now that I feel that I can’t even explain it well. Maybe I think to complicated about it?
It’s tough to answer that but I will give some hints that occurred to me while reading it:
-the physics system is moving the objects based on velocity and acceleration. The user input should really only be affecting acceleration.
-marrying up the different latencies on the server across all of the clients is always going to be tricky.
-and actually, that’s all I got… everything else immediately dives off into the deep end of the pool. In my case, I have a carefully designed thread-safe data structure that I use for an object’s position buffer that automatically interpolates position based on game time. I store one of these as a component with every mobile entity but it’s not like a regular component because all of my other components are immutable and are swapped out for changes. This one interacts with its systems in a way that it is always expected to be there and they know they can ask for a position + orientation at a specific time and get a nice interpolated value without worrying about threading, etc… The simulation then only needs to keep track of frame time.
It’s a very complicated thing to get right but in many ways makes everything else simpler.
Yeah, I read about this buffer component again today in the thread “understanding of entites”. Maybe it will help to build my thoughts around this one. So creating a fitting system around this and not the other way round…
Yeah, I read about this buffer component again today in the thread "understanding of entites". Maybe it will help to build my thoughts around this one. So creating a fitting system around this and not the other way round...
The hard part is making it thread safe without slowing it down. I had to use every Java threading trick I know. It would probably perform ok with a more straight-forward, slightly slower, approach, though.
Edit: for example, if you don't know the implications of "volatile piggybacking" and how to adequately test such a fragile construct then it's probably best to go the safer/slower route. :)
Well my server runs with a fixed tick (50ms) ans sends updates at that times, including position,rotation,velocity,angvelocity , the client then has a interpolator object that is responsible for moving the entities as wanted. For manys stuff i use (spaceshgips, vehicles) a simple linear interpolation is fine enough. → you see the object 50 ms delayed, it is interpolated linearly to the last recievied position. (For spaceships noone expects them to react instantly so a 50-100ms delay before any reaction is quite fine (as they only start to slowly gain speed ect anyway, phyiscs limited thrust ect.) The player is way more tricky. camera sterring is completly clientisde, position is currently interpolated percentbased. (each frame 50% to target location, so the changes in direction are smoother as they can appear far more often. Next step is to add a prediciton based on the client (move position if client assumes a free space instantly, and only correct if server position drift off to far.
I'm definitely not a master in concurrency and I had to look the term up. But I was happy when I saw that I know this :) (In fact I read the first ~ 100 pages of "Java - Concurrency in Practice" by Brian Goetz. Maybe I should invest time in reading through it completely^^)
I did think about the lag compensation drawpacks and advantages till 2 am in the night yesterday (at least 3 hours from my last posting) and drew a lot of timelines.
Finally it now occurs to me that making an RPG instead a FPS with no instant hit weapons could lessen the drawbacks of lag compensation naturally. Combined with what you pspeed said in another thread that every action has even on the local machine a delay of 150 ms this makes lag compensation look less unnatural.
As an example one can say that shooting a weapon and waiting 150 ms for a bullet to come out looks less unnatural than waiting this small time slice for a heavy sword to be swung.
Now it's the question how to "merry" the inputs on the server but I will program a first simple solution and later create a more advanced one when I have done some other work.