Advertisement

My Article for Network Game Packets(FPS,Chess examples)

Started by February 18, 2016 04:21 AM
-1 comments, last by RiggedNet 8 years, 9 months ago

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>

This topic is closed to new replies.

Advertisement