besplash besplash - 16 days ago 10
C# Question

C# Lidgren Library - Send playerdata

I am currently writing an object oriented game with a multiplayer.
Player inherits from entity and when I send my current players properties via

NetOutgoingMessage outmsg = Server.CreateMessage();
[...]
outmsg.WriteAllProperties(p);


where p is my player object, my clients only receive properties which are declared in my players class and not from the entity class. Therefore my clients can't update the player positions etc.

Any advice?

edit:

It recognizes the inherited objects, but it doesn't send them properly. I think I might need to use some Bindingflags as there is an option to it and it should be possible to send objects which are allocated to a player too. I am using a Vector2 class to specify the position and velocity of my player, but my client either can't receive a Vector2 class or the server can't send it. If I use integers, strings, booleans or anything it works, but not with custom classes.

Answer

This should (have not tried this myself) be possible since you can serialize anything into bytes but not straight out the box. There are 3 primary conditions:

  • objects that need to be sent should be exactly the same on client and server.
  • You need to send the type of data along with the data at a expected position.
  • And most probably need to sent the amount of bytes send since NetIncomingMessage does not have read till end.

One way to send data type info is to send a enum as the first byte

enum PacketTypes
{
    LOGIN,
    MOVEMENT,
    SHOOTING,
}

out.Write((byte)PacketTypes.Login);

NetOutgoingMessage.Write can take a bytes or byte array. So you can use any method to serialize your object to bytes. Before you write it as a out message first determine the amount of bytes and write that after the packet info. Then write the data.

On the receiving end you need to determine what kind of data you received and handle that properly. if (inc.ReadByte() == (byte)PacketTypes.Login), now we know how to handle this custom package. Now read out the integer that specifies how much bytes the data is, read out that amount and deserialize it.

There are plenty of sources that explain serializing and deserialzing data so I won't go into depth here. And since you can send and receive bytes with Lidgren this really should just work. However, you should always send as little data as possible and in practice a couple of primitives are often enough. For example, the name of the player does not need to be send each time you want a position. The abilities of that player are probably even less interesting. You need to break it down in pieces, if a player moves send 2 floats. If a player gets hit send a int. For a ability being used you often only need an integer as ID.