Synchronized input-based networking- computational load?

Started by
17 comments, last by hplus0603 16 years, 3 months ago
Quote:I plan to average around 400 delta updates (give or take) for a 28K connection (aka 3584 bytes/s


What does 400 delta updates mean? The 28 byte UDP header overhead times 400 datagrams (say, 20 players 20 times a second) means a lot more bytes than that, so that's not what you mean.

The upstream bandwidth used can be estimated as:

  bandwidth = tickrate * (28 + deltasize * numplayers) * numplayers


tickrate is number of updates a second, and deltasize is the size of the update for a given player, in bytes. The bad part about that formula is the numplayers-squared factor.

Quote:I believe the Newton physics engine is deterministic, and it happens to be the easiest to implement on account of the engine I'm using (TrueVisison 3D 6.5)


Several hundred rigid entities will be challenging; if nothing else, then because you'll need to use base line re-sync for cases where the client can't possibly make the right guess. Unless you use a server-side round-trip for every player's interaction, including firing weapons (which usually is bad from a gameplay perspective). I don't know if Newton is multi-threaded, and I don't know how complex environments and bodies you are planning on using, though -- with the right trade-offs and optimizations, it might work.

I doubt that Newton combined with TrueVision will actually end up being as deterministic as you say they are, when you start deploying in the wild. There are lots of little details that will trip you up.
enum Bool { True, False, FileNotFound };
Advertisement
//Off Topic
Quote:Original post by hplus0603
Quote:I plan to average around 400 delta updates (give or take) for a 28K connection (aka 3584 bytes/s


What does 400 delta updates mean? The 28 byte UDP header overhead times 400 datagrams (say, 20 players 20 times a second) means a lot more bytes than that, so that's not what you mean.

The upstream bandwidth used can be estimated as:

  bandwidth = tickrate * (28 + deltasize * numplayers) * numplayers


tickrate is number of updates a second, and deltasize is the size of the update for a given player, in bytes. The bad part about that formula is the numplayers-squared factor.
Oh whoops I wrote that down too fast without thinking. 32 bytes for a TCP header lets say and 10 updates per second. And my automatic serialization is really odd, so I'm just gonna say roughly 20 bytes for an update and 10 bytes for random stuff maybe.
3500 = 10(32 + 10 + 20x);
//10 is for some random data
x = 15.4 updates per tick, so like 154 updates per second. Not too bad, but kind of unrealistic since some updates only take a fraction of a byte or like 23 bits and such, so the number is probably much higher, but worst case isn't too bad. I'll have to do tests later. I've switched around the system to an automatic serialization system I'm inventing. So much more to research.
Quote:Original post by hplus0603
Several hundred rigid entities will be challenging; if nothing else, then because you'll need to use base line re-sync for cases where the client can't possibly make the right guess.

I don't see how that situation would arise if the physics engine is deterministic. The client is making guesses but they only apply to that which is apparent to the player, not what the client knows about the actual gamestate.
Quote:Original post by hplus0603
I doubt that Newton combined with TrueVision will actually end up being as deterministic as you say they are, when you start deploying in the wild. There are lots of little details that will trip you up.

Hmm, guess you're right about Truevision insofar as its built-in Newton support is concerned- I can't know whether it has precision or other issues, and if it has them I can't fix them (it's closed-source). But if Newton itself isn't deterministic, then the blurb on their site is full of damn evil lies.

EDIT: Using estimates of 3000 updates/sec peak and 300 average (50 Hz simulation, max 800 ms old information) Newton clearly isn't gonna do it. I checked out the stress test from their site, the situation in which is considerably more complex than what I'm doing. Nevertheless, it peaked at 4 ms per physics update. This is on a 3GHz Core 2 Duo (I forgot the model) with a 1333 MHz FSB, and DDR2-800 MHz CL4 RAM. So I guess I find a super-fast deterministic physics engine (seems unlikely), write my own (seems REALLY unlikely), or scrap the idea altogether. The physics don't actually need to be as high-fidelity or realistic as HL2s, but still...

[Edited by - Baiame on February 1, 2008 8:27:48 PM]
Quote:I don't see how that situation would arise if the physics engine is deterministic.


There's all kinds of things that can trip it up. Start with the rounding mode and internal precision mode of the FPU, which can get changed by various shared libraries. Continue with differences in floating-point implementation between Intel and AMD. And, even worse, different code generation if you use different compilers (say, for Linux servers, or for a PowerPC version).

Then, there's the problem that a "big matrix" solver can only be deterministic if EVERYTHING is consistent. This includes things like in what order objects are added to the world. Unless you want to re-play the entire sequence of events from the birth of the world when a player joins, you will not get deterministic results. Which order an object finds itself in in some internal list or hash of some sort will matter to determinism.

Quote:3500=10(32+10+20x)


I don't understand that formula. The base TCP header is 40 bytes. The updates are MULTIPLIED per user. Let's say 10 users, 10 updates per user per tick, and 10 ticks per second with 20 bytes per update.

10*(40+20*10)*10 == 100*(240) == 24 kB/s

Perhaps you're talking about only a single channel at a time, as seen at the client? My formula is for calculating the needed upstream bandwidth at the server, so it's sending to each of the clients data about each of the clients. Plugging in 300 rigid bodies of which 60 are players:

10*(40+20*300)*60 == 600*(6040) == 3.6 MB/s or enough to almost saturate a T3 connection. Each client sees 60 kB/s, which is about half of a typical 1.5 Mbps DSL connection.


enum Bool { True, False, FileNotFound };
Quote:Original post by hplus0603
There's all kinds of things that can trip it up. Start with the rounding mode and internal precision mode of the FPU, which can get changed by various shared libraries. Continue with differences in floating-point implementation between Intel and AMD. And, even worse, different code generation if you use different compilers (say, for Linux servers, or for a PowerPC version).

Oh yeah, I was aware of floating-point issues. Guess I didn't consider how hard they would be to control when using someone else's library...
Quote:Original post by hplus0603
Then, there's the problem that a "big matrix" solver can only be deterministic if EVERYTHING is consistent. This includes things like in what order objects are added to the world. Unless you want to re-play the entire sequence of events from the birth of the world when a player joins, you will not get deterministic results. Which order an object finds itself in in some internal list or hash of some sort will matter to determinism.

I was reading about that last night on the Bullet forums. I know what you mean, but it doesn't mean you have to re-play from the very beginning; you'd "just" have to find some way of buffering the entire state of everything in the physics library after every update. Which would require lots (too much?) memory, but more importantly would require intimate knowledge of the particular library. Which would itself have to be open-source. And again, really really fast. And it'd take alot of time. And patience.

As if I weren't ready enough to give up, I worked out that one of my other requirements (that I forgot to mention) is impossible to fulfill on modern connections. Guess it was just another overambitious idea that got shot down at an early stage, but thanks for your help ensuring the "early" part, everyone.
Quote:Original post by Baiame Which would require lots (too much?) memory, but more importantly would require intimate knowledge of the particular library. Which would itself have to be open-source. And again, really really fast. And it'd take alot of time. And patience.


I don't think memory would necessarily be an issue.

You'd receive baseline state over the network anyway. That would mean that relevant dynamic shared state needs to be relatively small. Everything else would need to be either static and require no copying, or could be dynamically evaluated as needed.

Quote:you'd "just" have to find some way of buffering the entire state of everything in the physics library after every update


You need to do more than buffering. You need to make sure that all the internal data structures work the same on all nodes. This means that ordering of rows in the matrix, for example, is deterministic based only on the incoming entities and constraints (say, sorted by entity ID or similar), not on something else, like history or chance. The same problem crops up in a few different places, actually.
enum Bool { True, False, FileNotFound };
what if ObjectA is not controlled by input, it is controlled by time or a counter. If the network system just seds/receives input each machine has
its own update for ObjectA. Making synchronization a bit harder.
So you would still need one server to control the overall game behavior not to mention cheating and security.Thus taking everything back to dead reckoning or whatever method you want to use for inter/exter-polation.
If I am not mistaken valve's paper for HL2 network describes what they do in details. In summary:
Clients send their input and continue using them normally (client side prediction).
Server Handles and moves all game objects and sends correction packets from time to time.
Quote:So you would still need one server to control the overall game behavior not to mention cheating and security.Thus taking everything back to dead reckoning


Server authority and input-synchronous communication are orthogonal concepts. Just because you're server authoritative doesn't mean that you need to use dead reckoning. Read the patent I pointed you at, or try Virtual Pimp My Ride, There.com or Virtual Laguna Beach which are some of the users of that technology (with free accounts).
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement