Packet Data For Multiplayer Network Games by Christopher Harmason
A primer for setting up packets for a multiplayer server, with examples of creating data for multiplayer shooter games, and chess.
<p>by Christopher Harmason
<h1>Introduction</h1>
The data size of packets sent is often the deciding factor in the
performance of a game over a network.
This article introduces examples of data sizes for reaches a packet
size of up to ten to twelve bytes per player. Understand that the bit
sizes are for the number of bits that need to be sent and copied into
a data buffer, where the sign bit is optional. A header file storing
macros of binary numbers with and without the sign bit is viable
as a choice.
<h1>What Data Do We need</h1>
For now let'slook at the data needed, since there are libraries such as enet,RakNet, and Winsock.
<h1>Explaining the Concept</h1>
Numbers and letters are simple and indexing into arrays of bits can be
simpler than sending characters that are indexed with their values
from an ASCII chart to match
number ranges.
Example for reference:
An integer ID ranging from 0 to 4 can be represented by characters in
an ASCII chart simply by choosing 4 characters whose ASCII value are
next to each other in
numerical order. Now, on to simpler interpretation.
<h1>Representing Data</h1>
Below is a listing of the number of data items that need to be
represented, an index range in terms of C/C++ arrays,
and below that a series of bits count for bits needed to store the
number range for that data item if the option to write
a chosen number of bits is supported in what is used to build a
networking solution. In C or C++, this can be done using
some standard features of the language. I will also list data sizes
used when only bytes and 32 bit integers are supported.
by Christopher Harmason
16
player id 0 to 15
3
player type 0 to 2
2
item 0 to 1
7
weapons 0 to 7
Example: pistol,smg,assault rifle,machine gun,turret
gun,grenade,rocket launcher/missile
15
weapon ammo 0 to 14
Note: weapons have a number of reloads,and the type determines damage
as well as firing rate,
some fire in burst such as an smg for 2 shots or assault rifle for 3,
6 to 14 for a machine gun or or more for turret
multiplied by 15 is the in game ammo count
So 30 for an smg, 45 for an assault rifle, 84 to 196 for a machine
gun, 98 for turret,
while sniper rifles, pistols,grenades, and rockets are one shot bursts
with varying firing rate
7
vehicles 0 to 6
Example: motorcycle,jet ski, sled boat, helicopter, jet,armored
transport,tank
Note: these are in order of strength of their armor rating, meaning
that this data can be used for armor value as well as Id for the
vehicle type, freeing up bits
for things like a time value
7
health 0 to 6
15
vehicle health 0 to 14
3
vehicle weapon 0 to 3
3
vehicle item 0 to 3
7
vehicle armor 0 to 6(index of weapon that can damage it, order from
weakest to strongest)
so bit counts
4
2
1
3
4
3
3
4
2
2
3*-redundant data depending on how things are handled
=31 bits
plus sign but for if it is new data
for 32 bits total
= 4 bytes
Note about bit counts:
the above builds on presenting a case for writing and sending the
number of bits needed that can be
copied and used, which are then stored as they would be with a sign
bit.
In many cases the sign bit takes up the first bit written, increasing
the bite count by 1 for each unique
value(variable) used when it is stored resulting in
5
3
2
4
5
4
4
5
3
3
4
where 42 bits are being used.
Since the order of vehicle types is in order of how they are armored,
free up 3 bits removing an armor value allows for a 4 bit timer, 4 bit
data use of choice, or 3 bits data of choice keeping a sign bit
12 bits, 2x6 bit orientation
36 bits, 3x12 bit position
total 48 bits
= 6 bytes
Note that 24 bits can be used for XYZ position as an alternative, or 2
12 bit numbers storing position as XY, think height maps, for more
precision
reducing this to 4.5 bytes
OR
48 position
8 bit y rotation
8 bit x rotation
=8 bytes
10 to 12 bytes
OR
96 bits position(x y and z)(three 32 bit numbers)
8 bit y rotation(indexes rotations in increments of 2 degrees, from 1
to 180, for 360 degrees rotation)
8 bit x rotation(indexes rotations in increments of 2 degrees, from 1
to 180, for 360 degrees rotation)
When storing With bytes and 32 bit numbers
16
player id 0 to 15, can be more
3
player type 0 to 2
2
item 0 to 1
7
weapons 0 to 7
Example: pistol,smg,assault rifle,machine gun,turret
gun,grenade,rocket launcher/missile
15
weapon ammo 0 to 14
Note: weapons have a number of reloads,and the type determines damage
as well as firing rate,
some fire in burst such as an smg for 2 shots or assault rifle for 3,
6 to 14 for a machine gun or or more for turret
multiplied by 15 is the in game ammo count
So 30 for an smg, 45 for an assault rifle, 84 to 196 for a machine
gun, 98 for turret,
while sniper rifles, pistols,grenades, and rockets are one shot bursts
with varying firing rate
7
vehicles 0 to 6
Example: motorcycle,jet ski, sled boat, helicopter, jet,armored
transport,tank
Note: these are in order of strength of their armor rating, meaning
that this data can be used for armor value as well as Id for the
vehicle type, freeing up bits
for things like a time value
7
health 0 to 6
15
vehicle health 0 to 14
3
vehicle weapon 0 to 3
3
vehicle item 0 to 3
redundant since another number can be used that already would be taking
up storage----------
|
|
x7x <--------------
xvehicle armor 0 to 6(index of weapon that can damage it, order from
weakest to strongest)x
also vehicle items 3 bits can be used for vehicle health cross checked with the ID number
for vehicle type, storing 2 bits for vehicle health, and freeing 15 plus 1 bits for ID of player
that last damaged the player whose packet is being sent
16
player ID of player that last dealt damage
2
vehicle weapon 0 to 3
When using bytes and 32 bit numbers only
ten 8 bit numbers, so ten bytes
(80 bits)
Using Player ID Wisely to Free Up And Keep a Timer</h2>
Player ID can be handled in a way where any positive value
larger than the number of player subtracted by the number of players
results in the ID of the last player attacked. This allows tracking
of player and of those last attacked by them.
<h2>Example</h2>
Player 2 is attacked by Player 16.
Instead of sending 2 values
with unsigned 0 to 255
attacking player times max number of players
plus player ID can be sent
and ranges indexed
240 to 255 = attacked by player 16
224 to 239 = attacked by player 15
208 to 223 = attacked by player 14
192 to 208 = attacked by player 13
176 to 191 = attacked by player 12
160 to 175 = attacked by player 11
144 to 159 = attacked by player 10
128 to 143 = attacked by player 9
112 to 127 = attacked by player 8
96 to 112 = attacked by player 7
80 to 95 = attacked by player 6
64 to 79 = attacked by player 5
48 to 63 = attacked by player 4
32 to 47 = attacked by player 3
16 to 31 = attacked by player 2
0 to 15 = player ID, deduct points if the same
when health reaches 0
[(attacking player) * (max players)
-(playerID - 1)* 16 ] + (playerID - 1)
Here player 16 attacking player 2 results in a value of 241
Freeing up 1 byte(attacking player ID) for use as say a timer
Remember what was mention where either vehicle items or vehicle armor can
be replaced where its data storage is used for the ID
of last attacker to do damge
If vehicle armor is replaced by attacking player ID, then the vehicle items'
number range indicating what unique abilities are not functioning due to damage
can indicate damage done to the vehicle.
and
96 bits position(x y and z)(three 32 bit numbers)
8 bit y rotation(indexes rotations in increments of 2 degrees, from 1
to 180, for 360 degrees rotation)
8 bit x rotation(indexes rotations in increments of 2 degrees, from 1
to 180, for 360 degrees rotation)
(112 bits)
for a total of 24 bytes
The same number of bytes can be used, in a different data send, for
stats
Player ID Name Kills Deaths Score Assists Killed With Last Attacked By
1 chris101a 12 3 12345 2 Weapon/Vehicle ID othrplaya
indicator
1 byte 9 bytes 1 byte 1 byte 1 byte 1 byte 1 byte 9 bytes
24 bytes again
24x16 players=384 bytes
24x12 players=288 bytes
12 players is one way of grouping things for a number below 300 bytes
recap
for 10 bytes
10x16 players=160 bytes
10x12 players=120 bytes
for 12 bytes
12x16 players=192 bytes
12x12 players=144 bytes
<h2>Simplifying Using Simpler Shooter Design Approach</h2>
by Christopher Harmason
Say there is a deathmatch thing with no vehicles with the
following weapons
shotgun(3 shot kills far range, 1 shot kills close range)
machine gun(2 seconds of firing hits kills)
pulse rifle(1 to 1.5 seconds of firing kills)
warp burst gun(stuns and slows movement while dealing damage)
rocket launcher with 1 redirection angle trace
atomic bake gun(like an insta death ranged thing)
9 bytes
48 bit position)(6 bytes)
wpn/ammo(stored as 1 value, indexed and tracked like the
playerID/attacked by thing)
health(used with indexed effect for whether or not player has flag,
team they're on, how this is indexed determines if it is a team match
and the type)
(can be indexed where every 16 is range for in or out of a vehicle
like the players attacked by, removing need for some values, where
those things are indexed and interpreted in part of program from the packet along with player type/class)
player ID/attacked by
144 bytes for 16 players
<h1> Simple Chat</h1>
u there?
Player ID and 8 byte name
Player ID and 8 byte message as above
9x16 players = 144 bytes
288 bytes max per packets
Stats
Player ID Name Kills Deaths Score Assists Killed With Last Attacked By
1 chris101a 12 3 12345 2 Weapon/Vehicle ID othrplaya
indicator
1 byte image,ID indexed 1 byte 1 byte 1 byte 1 byte 1 byte image,ID indexed
8 bytes
Score handled with a scale where a multiplier
is used with a number going up to 127 with experience points and number of kills
50 to 100 works as a scale multiplier
Or 25 for example, where kills or taking a flag is 4 points, for a score
total of 100 per flag take, and kills are 25
115 as a multiplier gives a nice ceiling to the experience thing, for max
of 14605
Sending only the bits of data to be copied is what led to approaching
things where the byte count can
be reduced to 10 to 12, or at larger size 24 bytes, enabling text
phrases every other packet
at the size of "are we there yet maybe?" at 23 bytes.
<h2>Interesting Points</h2>
Note that important things such as interpreting the index for weapons
in a particular order to determine if a weapon can damage a vehicle is
important to storing and
sending less data. Here, the strength of a weapon
should be its index, allowing the armor value to be the minimum damage
value needed to damage a vehicle, which is my approach, along with
storing two rotations for
aiming, one for looking left and right and another for up/down. For
things like a fighter jet leaning into a turn, the game engine can
interpret this to tilt and
rotate the jet plane, or frames of animation are stored that tilt the
plane left and right. I have tried both approaches and they work
seamlessly regardless of which
is chosen when time is taken.
For 27 bits
9 bit health indexing ranges based on weapon player has and player number
9 bit position index into game map
9 bit index into rotations X and Y tabl
For a chess game.
64 spaces on board
ID number of 0 to 7 (3 bits) specifying
empty,pawn,knight,bishop,rook,queen,king
1 bit value for whether black/white, storing as positive or negative
number
64 times 4 bits = 256 bits
Indexing alternating from the top left square on board and designating
black or white board squares based on the whether the index is even or
odd results in
64 spaces on board
ID number of 0 to 7 (3 bits)
specifying empty,pawn,knight,bishop,rook,queen,king
64 times 3 bits = 192 bits
allowing for sending of a byte as player ID
for 0 to 255
OR
if signed up to 128
where if the value is negative then the player ID is inactive
to track 64 possible matches.
This does not resolve tracking the taking of pieces
8,2,2,2,1,1
are the numbers of pieces that can be taken of each type in
order
pawn,knight,bishop,rook,queen,king
to track pieces taken
pawn
4 bits
track 0 to 7
if another is taken when the value is seven, set the sign bit
knight
2 bits
bishop
2 bits
rook
2 bits
queen
1 bit
king
1 bit
requiring an additional 12 bits total.
<h1>Conclusion</h1>
A followup is intended for this article where more will be talked
about with specifics on the headers and such for sending network data,
and the use of RakNet and enet libraries for setting up clients and
host.</p></p></p>
My Article for Network Game Packets(FPS,Chess examples)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement