Search Unity

Bandwidth Overheads of UNET HLAPI headers / features (ClientRPC, Command, SyncVar)

Discussion in 'UNet' started by moco2k, May 17, 2016.

  1. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    Hey,

    optimization of bandwidth consumption is an essential issue for multiplayer games.

    Unfortunately, I have not found a documentation of the bandwidth consumptions / overheads of UNET HLAPI features such as ClientRPC, Command and SyncVar.

    Especially in order to create a decent network architecture design, I would like to know how much bandwidth is basically consumed by these functions at bare bones (e.g. header data only, without the actual data). This information seems to be crucial in order to implement proper designs and bandwidth optimizations.

    For example, if I send a ClientRPC with just a single byte, how much bandwidth does it actually consume in total?
    Same question for SyncVar and Command.

    Any help is much appreciated.
     
    Last edited: May 17, 2016
    DamonJager likes this.
  2. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    1,124
    Well I can not say it for sure how much is added but at least for ClientRPC and Command there is an additional NetworkHash128 (128 bits) for the name of the method in question.
     
  3. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    Really? 16 bytes? That seems a little excessive. Couldn't they generate hashtable or something with single byte keys?
     
  4. Oshroth

    Oshroth

    Joined:
    Apr 28, 2014
    Posts:
    99
    If I remember correctly, the hash is used to identify the function and is unique across the entire build. If you used a single byte you would be limited to ~256 clientRPC/Commands across the build or would need to track hashes in a more possibly unreliable way. The hash is stored in a static dictionary on NetworkBehaviour or NetworkIdentity with the class type and function associated with it.

    The packet payload for a RPC message is 2 bytes for size, 2 bytes for RPC message type, packed 1-5 bytes for hash, packed 1-5 bytes for netid plus any arguments passed to RPC function.
     
    moco2k likes this.
  5. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    Thanks for the input guys.
    So, without any arguments, a ClientRPC would consume 6 bytes at min. and 14 bytes at max in the very worst case.

    What about SyncVars and Commands?

    @aabramychev, it would be nice if a UNITY staff member would jump in to make sure that such information are added to the docs.
     
    Last edited: May 18, 2016
  6. Oshroth

    Oshroth

    Joined:
    Apr 28, 2014
    Posts:
    99
    Command message: 2 bytes size, 2 bytes Command type(5), packed 1-5 bytes hash, packed 1-5 bytes netid plus arguments.

    SyncList<T> message: 2 bytes size, 2 bytes SyncList type(9), packed 1-5 bytes netid, packed 1-5 bytes CmdHash?, 1 byte SyncList operation, packed 1-5 bytes itemIndex plus arguments.

    SyncVar message: 2 bytes size, 2 bytes SyncVar type(8), packed 1-5 bytes netid, plus (either all syncvars or dirty syncvars + packed 1-5 bytes for dirty bits) for each dirty NetworkBehaviour. A SyncVar message is set for each dirty channel for each NetworkIdentity.
     
    nxrighthere and moco2k like this.
  7. K1kk0z90_Unity

    K1kk0z90_Unity

    Joined:
    Jun 2, 2013
    Posts:
    90
    What about the bandwidth of a NetworkTransform? They are 9 floats, each 4 Bytes, right? So it should be 36 Bytes. But here are my doubts:
    1. Does it synchronize always all nine values or it only sends changed ones?
    2. Does it compress the data?
    3. How much is in size the header of the packet sent?
    So, how much data does it send a NetworkTransform?
    Thanks in advance!
     
  8. Oshroth

    Oshroth

    Joined:
    Apr 28, 2014
    Posts:
    99
    It uses the SyncVar message, It seems to sync all values when dirty bit is set, rotation and spin axis will be compressed based on Compression Value. Rotation and Spin axis will only be sent if Axis Sync is set.
    For SyncTransform arguments are: 12 bytes position, 0-3 rotation angles based on axis sync * (2 or 4 bytes based on compression)
    For Sync2D arguments are: 8 bytes position, 8 bytes velocity, (2 or 4 bytes) if axis sync, (2 or 4 bytes) if sync spin
    For Sync3D arguments are: 12 bytes position, 12 bytes velocity, 0-3 rotation angles based on axis sync * (2 or 4 bytes based on compression), 0-3 spin angles based on axis sync and sync spin * (2 or 4 bytes based on compression)
    For SyncCharacterController arguments are: 12 bytes position, 0-3 rotation angles based on axis sync * (2 or 4 bytes based on compression)
     
  9. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    1,124
    Actually there are more reliable ways to compress hash values and recurring strings like Huffman coding but i'm not sure if it is worthwhile here or not.