Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to compile networking commands?

Discussion in 'Scripting' started by howaboutno000, Nov 13, 2020.

  1. howaboutno000

    howaboutno000

    Joined:
    Nov 13, 2020
    Posts:
    20
    How to package the information? I don't need help with creating a networking library, I already have a library that sends and receives data. The question is, how do I send and receive information from server to client, how do I transform it from concept to bytes, to concept? What is the data structure that I compile the data with then to decompile it? I need to transfer a command, and then its parameters. There's two solutions with separate drawbacks:

    Simple string or enum command:
    "mycommand" "mydata1" "mydata2"

    But there are problems:
    - Which requires me to type perfect commands 4 times (read/write client, read/write server) for every command
    - Second is performance issue. Many switch string evaluations could have significant impact.

    Enum with struct
    commandType "serializedData"

    - Requires me to pass the name of the enum, which then needs to be put through switch to then be deserialized as the type which is a very painful switch() boggle. Which kills readability (its 3 lines + break, for every command).

    Preferably that methodology would allow me for very standardized commands (which makes it very clear for server to create and client to interpret) whilst maintaining readability. Is that a thing? How do I structure the data I'm sending in a way that makes relatively easy to compile, decompile and not make future programmers tear their eyeballs out?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    I think you'd be surprised. Package things up as JSON and send them over. Make nice small compact objects obviously, don't be a pig about it, but since 100% of what goes over the internet is just strings anyway, why not embrace it and send them out yourself!

    Bonus: it's super-easy to debug each packet by studying it when you can pull it up in a text editor or print it onscreen.
     
    Joe-Censored likes this.
  3. howaboutno000

    howaboutno000

    Joined:
    Nov 13, 2020
    Posts:
    20
    That is my current situation :).
    But even then, as I package that data as JSON. Once I package it, how would I go about it?
    If I turn a class into JSON, client still needs to interpret it, which is what the original question is about.

    I want to put whatever command through that function, then to transport library, then client takes the string and pushes it through simple function and somehow interprets.

    The question is, what is the least hassled way to do it? How do I ensure the integrity and auto-complete (like exploring JSON->struct object) without ending up with a painful switch with tons of statements for each, balance between most functional and readable. How do I tell client what struct to decompile it to, and if I pair it with a type, how would server deduct this type, this would be done by checking the type and then sending it to networking. I'm already here, before you know it, it turns into counterintuitive mess. If something happens I won't be able to fix week after I finish writing it.

    As for
    "Many switch string evaluations could have significant impact"
    That's not for JSON decode, that's for bruteforcing through type to have client guess what type the package is to cast it to.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    What you describe is basically an RPC, or remote procedure call. That should give you some googling. Unity had a system but they deprecated it apparently.
     
    Joe-Censored likes this.
  5. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Are you using a specific networking API already? Are you rolling your own network API? Many networking systems for Unity already have this higher level functionality built in, but how to use it would depend on the specific API chosen.

    As far as performance, have you benchmarked these performance issues already? When I was creating my own networking system I was just sending all my complex data first as CSV files, and then when I settled on exactly what data needed to be sent I then wrote "proper" serialze/deserialize methods directly to byte arrays. This made the data far more compact, but the CPU performance gain from switching from string parsing to using mostly BitConverter straight from the byte array was rather trivial in the grand scheme of things. You're probably not sending enough data for that to really show up in comparison to the actual simulating the game part.

    I came up with a few solutions to avoid monolithic switch statements. For more lower level type messaging, I actually do use switch statements based on an ID for the type of message. But these switch statements usually don't get more than 10 or so items, and are mostly used for things like "Create Character" or server to server communications. Most messages instead are directed by the system to a specific script on a specific networked GameObject, based on the ID of the object and the index of the target script. From there the message either updates synced variables on the script or if an RPC it is sent to the correct index of the RPC receiving method. So the receiving RPC only ever gets exactly what it expects to get.

    The point is the script which finally receives the message is the only one which needs to know what the data actually is used for, not the script which first processes the incoming message. All that first script needs to know is that the message needs to be directed to whatever GameObject has the specific ID it sees. Then it just passes it off. (I took some inspiration from the Unet HLAPI, since I was converting the game from Unet, though took no code from it)
     
    Last edited: Nov 14, 2020