How do I use the Binary Data object to Send a Message with the Multiplayer Plugin?

2 favourites
  • 7 posts
From the Asset Store
This is a single chapter from the "Construct Starter Kit Collection". It is the Student Workbook for its Workshop.
  • Hi,

    Has anyone figured out how to use the Binary Data plugin with the Multiplayer Plugin to send a message? After struggling for a few weeks trying to conceptualize binary data as well as Scirra's plugin, I'm hoping to get some guidance.

    The multiplayer message I am trying to send contains the following data (for multiple peers):

    PeerID: 4-5 alpha/numeric characters

    X Position: 1-5 digit integer

    Y Position: 1-5 digit integer

    Direction: 0, 1, 2 or 3

    Currently I'm sending this data as a string with separators to distinguish between the variables as well as the peers. I know this isn't best practice, but the aim is to "shrink" the data with the Binary Data object. I guess what's confusing me is how to setup the actions/events to load the data into (and read the data from) the Binary Data object, and I'm not sure if multiple Binary Data objects are needed.

    Side notes:

    - If anyone has a Binary Data plugin example file that they would be willing to share, that would be super helpful! I haven't come across any on the forums nor is there a tutorial.

    - I'm not using the built-in multiplayer sync, and instead I'm using "send message" to send data to specific peers.

    Regards,

    Adrian

  • So if you want to use a binary packet format you are going to need a well defined structure to it. Anything without a fixed size will need an extra field to tell you how long the data is going to be, otherwise you will not be able to read it back.

    In terms of your chosen data for each peer you have:

    • PeerID (unsure if sized)
    • Position X (sized)
    • Position Y (sized)
    • Direction (sized)

    PeerID is somewhat frustrating, I can't tell from the documentation if it's always a fixed length. If it is then we only need 1 size value for the whole packet, but if it isn't then we need one for each peer! I think we will have to assume that it can vary in length.

    We will need to store an integer value at the start of our packet that contains the number of peers. Then for each peer we need to store 2 integers ( direction, peer id length ), 2 floats (position x, position y,) and then a string ( peer id ).

    For writing strings you will need a second binary data object to write the string into, then copy the contents of that object into the main one. This limitation is due to it being hard to know how many bytes you need to store a string until you try to write it.

    Example serialisation

    1. First we need to calculate how big the buffer needs to be, we need to loop through each peer and add up the sizes of the data. Let's use uint8 for the integers (max value is 255) and float64 for the fractional values. This gives us the size for each peer (2 x 8) + (2 x 1) + (peerIDByteLength) then add the size of the peer count ( 1 x 1 ).

    2. Create a new buffer with the calculated size.

    3. Write the number of peers as a uint8.

    4. Loop through each peer

    4a. Write peer ID length as uint8

    4b. Write peer direction as uint8

    4c. Write peer position X as float64

    4d. Write peer position Y as float64

    4e. Write peer ID as string

    You will have to keep track of the current byte offset while writing the data, you don't want to just keep overwriting the value at index 0. For each uint8 written increate the offset by 1, for float 64 by 8 and for a string the number of characters. Deserialisation is simpler, as we don't have to pre calculate the buffer size. But we will still have to keep track of the byte offset as we read values.

    1. Read peer count as u8.

    2. Repeat by peer count.

    2a. Read peer ID length as uint8

    2b. Read peer direction as uint8

    2c. Read peer position X as float64

    2d. Read peer position Y as float64

    2e. Read peer ID as string, using length from step 2a

    This technique does make a small assumption that you don't have more than 255 peers... You can use a larger integer size if that's a requirement, but somehow I don't think it will be.

  • Amazing Nepeo! I had already received some much appreciated help from Eleanor to get this working but your post has helped round out my knowledge further (especially if wanting to send a string!).

    I appreciate it. I'll look to share a Multiplayer Template for anyone interested in doing something similar.

  • Amazing Nepeo! I had already received some much appreciated help from Eleanor to get this working but your post has helped round out my knowledge further (especially if wanting to send a string!).

    I appreciate it. I'll look to share a Multiplayer Template for anyone interested in doing something similar.

    HI,Badmiracle

    Can you share one Multiplayer Template with me?

    Thanks~

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I know you've got your solution. But I did something very similar in my recent project, so I thought I should share how I did it. Let's say in your case, I would make a Function that takes in the 4 parameters, and then 'send message' as one single string. On Peer end, I would have a function to 'decode' that string.

    This is how I would arrange the string:

    First character will be the direction

    Next five characters will be the X position (filled with zeros initially, e.g. 00532)

    Next five characters will be the Y position (same as above)

    Next remaining characters will be the PeerID (so it doesn't matter what size it is)

    Decoding can be done easily by using the mid function (https://www.construct.net/en/make-games/manuals/construct-3/system-reference/system-expressions that can extract any desired portion from the string.

    Then convert to integer, where necessary.

  • Here's a super super simple project to get you started and to learn from:

    drive.google.com/file/d/1r14eVFcBZZutylM39oHzPSpYRfElh4-t/view

    Here's the same project with some basic client side deadreckoning:

    drive.google.com/file/d/1u03rWmvxjaTLwK06Ig5hFVrYJa7uoefc/view

    If those are useful to you make sure you credit me in your game.

    Please don't sell these or share them on the unofficial construct community discord or i'll be really mad and will stop making more examples like this available in public spaces if you don't respect my wishes

    And if you like this and/or want more project examples like this maybe consider donating to my Patreon patreon.com/strawberrypunch every little bit helps and motivates me to share my expertise with other cool construct 3 users

    You can always ask me questions on the forums and I'll reply to them if they're simple enough but for voice chat or more in depth help you can always visit my discord at discord.strawberrypunch.com

    Don't hesitate to get in touch I love discussing construct 3 my favorite game making tool and you're not bothering me at all!!

    Good luck on your projects!

    - Eleanor

  • Hi,

    maybe you can check my tutorial on multiplayer card game where I do some serialzation between peers using json.

    youtu.be/BpnkIL7XvvA

    Hope it helps

    Cheers!

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)