Does this sound reasonable for a packet entry size?

Started by
4 comments, last by dpadam450 11 years, 9 months ago
Hey everyone! I'm now using construct (a form of the struct library) for python so that I have better packing control over my packets.
It looks like its going to be a lot smaller overall, but I just wanted to ask a few things:

Assuming that I'm using standard floats, each is 4 bytes. Therefore, an X,Y,Z coordinate would be 12 bytes. Adding on rotation, as two floats again at 4 bytes each, that's 20 bytes. Then, adding any state data like shooting, etc which can be used as flags (in a bitmask) I would add another byte. Add one more byte for an 8 bit integer representing delta tick (from packet tick) and another to represent the packet 'type'
Thus, looking at 27 bytes per player, after adding the 4 bytes for a 32 bit integer representing the current sending game tick,
Then, If one were to have 10 players, that's 270 bytes. Is that a lot / little in terms of network throughput?
Advertisement
270 bytes is tiny - but that also depends on how often you send those 270 bytes. It's much more useful to think of throughput in terms of rate (since that's what it is) rather than just a pure volume number.


Assuming 30 ticks per second at 270 bytes per tick, you're talking about a tiny fraction more than 8KB per second. That's almost compact enough to run on a 56K modem, for reference.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


270 bytes is tiny - but that also depends on how often you send those 270 bytes. It's much more useful to think of throughput in terms of rate (since that's what it is) rather than just a pure volume number.


Assuming 30 ticks per second at 270 bytes per tick, you're talking about a tiny fraction more than 8KB per second. That's almost compact enough to run on a 56K modem, for reference.


Thanks ApochPiQ.
I find that a lot of my problems aren't so much the implementation, but the actual history and mechanics behind multiplayer itself.
+1 for help :)
That sounds like it could work.

Things to consider:

If you're running a server, you have to send data about all 10 players (or at least 9 of them) TO 10 players, so server bandwidth grows by n-squared. Thus, at 20 Hz net rate, you have to send 27 bytes times 10 players times 10 players time 20 packets per second, which would be about 54 kilobytes per second, or about half a megabit.

Position may be sendable using smaller data types. If your entire level is 1km across in each direction, quantizing position to a 16-bit integer still gives you 1/64th of a meter of resolution (about half an inch.) Heading (what you call "rotation") can similarly be quantized to two 16-bit values with very little loss of resolution. On the other hand, you probably want to add velocity as a three-vector to the update packet, which wasn't in the initially described packet.

"ticks" can be the lowest X bits of the master clock, and each recipient can use the local clock estimate to inflate it. If the value is more than 127 ticks ahead of estimated master, assume it's behind master. Or you can send a single tick value up front, and then send delta to that tick value as a single byte for each user.

If you worry about bit packing, you can pack multiple values into single bytes. For heading and attitude, you can pack two 12-bit values into 3 bytes. If X and Y are a kilometer in size, but Z is only 20 meters from low to high, you can borrow a few bits from the Z to give better resolution to the X and Y. There are lots of such tricks you will want to pull once you start worrying about what happens when you want to serve 32 players on a 1.5 megabit connection :-)
enum Bool { True, False, FileNotFound };
If you want to know more about bit packing outside of just flags you can view the code in my article on the subject. Designing a binary writer/reader can abstract away a lot of the complexity as you write networking packets. Hplus hinted at this. Basically if you need to send data it's often good to look at the resolution of the data. The article goes into this in terms of things like updating minimap data. The code includes helper functions for things like WriteCustomResolutionSingle(value, min, max, bits) which automatically calculates an encoding based on the properties of the value you're encoding. Tons of strategies along those lines.
You can further cut rotations down to a single byte by mapping 0 to 255 to 0 to 360. Rotating from 1 to 2 degrees is so small that you don't need anything really less than that for precision.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

This topic is closed to new replies.

Advertisement