Jump to content

Unified Network Code

martyj

953 views

I though it would be best to share a lesson that I've learned while working on the networking aspect of my game.

 

In my game I use C sockets for network code. The server side is written in Golang. With game networking, you can't really use JSON as a data layer as the performance hits for serializing and deserializing data are too big. So the best option is to write out your data in a "file" struct format.

 

My game has a few types of structs.

 

PacketHeader, PlayerPosition, PlayerInit, PlayerQuit, PlayerMessage, ItemPickup, ItemDrop, StatusEffect.

 

I ran into a problem with writing code to handle players dropping items across all clients.

 

Sample Struct:

struct ItemDrop
{
unsigned short itemId;
float positionX;
float positionY;
float positionZ;
}

 

On the Golang side the struct was something like this:

type ItemDrop struct {
ItemId uint16
X	 float32
Y	 float32
Z    float32
}

 

They look exactly alike!

 

In C++, sizeof(ItemDrop) => 16.

 

In Golang, unsafe.Sizeof(ItemDrop) => 16

 

Everything should be perfect right? No. Notice how there are 3 float32s giving us 12 bytes, a uint16 should only be two bytes. Yet it takes up 32 bits of data.

 

On network serializing: binary.Size(ItemDrop) => 14.

 

This means that when the C++ side sends 16 bytes, golang reads 14 bytes, then re-transmits as 14 bytes. There are two problems that occurs. When a client is expecting to read a packet size of 16, it blocks on the read when Golang only sends 14 bytes. This also means that when Golang reads 14 bytes instead of the full 16, it corrupts future packets from that buffer by shifting the data 2 bytes.

 

So why Golang for the server code? Easier to write. C/C++ networking is a pain. Golang has the native support that C/C++ has, with nice modern libraries built out for it.

 

Because of situations like this, I will be re-writing the network code for client and server to use golang.



1 Comment


Recommended Comments

normally you reduce the rotation on the axis down to an int 1Byte.

Nearly no one can see the difference between rotating on 4 Byte or 1 Byte.

if 255 degrees is to less for you then use a unsigned short with 2 Bytes.

But do not waste bandwidth.

often it is more reduced by only sending the 'relevant' axis like y.

Or somtimes it is a pattern what you want to send.

small 1 axis int, again, again, and then a full float 3 axis, small, small, small, big

 

i think you got the point.

Share this comment


Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...