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

Question Custom Transport

Discussion in 'NetCode for ECS' started by chefneil, Oct 14, 2022.

  1. chefneil

    chefneil

    Joined:
    Aug 21, 2020
    Posts:
    29
    I have a webgl game that uses ECS and a custom webrtc-based transport layer. I'd like to start experimenting with netcode. Are custom transports possible using netcode?

    Cheers!
     
  2. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    774
    Yes, it is possible to implement custom transport. You need to implement a INetworkInterface that implement the in that web-etc transport layer.
    I would suggest look at the Uniyt.Networking.Transport documentation and check how they implemented, for example the WebSocketNetworkInteface or the TCP/UDPNetworkInteface
     
    PolarTron likes this.
  3. chefneil

    chefneil

    Joined:
    Aug 21, 2020
    Posts:
    29
    Thanks so much for your reply. I think I can reasonably implement the interface, but poking around the ecs parts of netcode, it didn't seem all that obvious how to bootstrap the netcode systems with my custom transport. Could you point me in the right direction there? My ctrl + click adventures always led me to the transports being constructed in the netcode internals. Is there a public API that let's me keep all of the netcode system bootstraping but simply let me provide my own transport?
     
  4. skiplist

    skiplist

    Joined:
    Nov 9, 2014
    Posts:
    45
    I think INetworkStreamDriverConstructor is what you are looking for? Keep in mind I'm basing this off of 0.51, but NetworkStreamReceiveSystem has the default implementation which calls the NetworkDriver.Create function which optionally takes a INetworkInterface argument.
     
    chefneil likes this.
  5. chefneil

    chefneil

    Joined:
    Aug 21, 2020
    Posts:
    29
    Interesting, thanks! So if I implement INetworkStreamDriverConstructor - how does it know to change the behavior of NetworkDriver.Create so that the NetworkStreamReceiveSystem uses my transport?
     
  6. skiplist

    skiplist

    Joined:
    Nov 9, 2014
    Posts:
    45
    It doesn't! If you implement INetworkStreamDriverConstructor then you are the one calling NetworkDriver.Create. In 0.51 NetworkStreamReceiveSystem has a static s_DriverConstructor member you can set which will override the default functions.

    So in short:
    1. Implement your own INetworkStreamDriverConstructor by copying the CreateClientDriver and CreateServerDriver from NetworkStreamReceiveSystem.
    2. Add your custom INetworkInterface implementation as an extra argument to the NetworkDriver.Create call in your custom INetworkStreamDriverConstructor.
    3. Set NetworkStreamRecieveSystem.s_DriverConstructor to your custom INetworkStreamDriverConstructor. Not sure if it has to be done before world creation or just very early.
     
  7. chefneil

    chefneil

    Joined:
    Aug 21, 2020
    Posts:
    29
    Thanks you so much! This is great insight, cheers!
     
  8. timjohansson

    timjohansson

    Unity Technologies

    Joined:
    Jul 13, 2016
    Posts:
    473
    It has to be done before NetworkStreamReceiveSystem.OnCreate which happens during world creation.
    When we've done this in the past we have used a custom bootstrap. Make a class extending ClientServerBootstrap and in initialize assign the driver constructor before calling base.Initialize - or if you already have a bootstrap doing something else just add assignment of the driver constructor there.

    The code you need to copy when creating a driver constructor is different in 1.0 experimental because we added support for multiple network drivers on the server. So you can have a single server accepting connections on multiple different network drivers at the same time (one for UDP and one for IPC so client hosted servers don't need a socket for example).
     
  9. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    774
    The right way to register you driver is to use as @skiplist said a custom INetworkStreamDriverConstructor.
    In 1.0-exp a custom INetworkStreamDriverConstructor looks like this:

    Code (csharp):
    1.  
    2. public struct MyCustomDriverConstructor : INetworkStreamDriverConstructor
    3. {
    4.     public void CreateClientDriver(World world, ref NetworkDriverStore driverStore, NetDebug netDebug)
    5.     {
    6.         NetworkSettings settings = DefaultDriverBuilder.GetDefaultSettings();
    7.         var driverInstance = DefaultDriverBuilder,CreateClientNetworkDriver(new MyNetworkInterface(), settings);
    8.         driverStore.RegisterDriver(TransportType.Socket, driverInstance);
    9.     }
    10.  
    11.     public void CreateServerDriver(World world, ref NetworkDriverStore driverStore, NetDebug netDebug)
    12.     {
    13.         NetworkSettings settings = DefaultDriverBuilder.GetDefaultSettings();
    14.         var driverInstance = DefaultDriverBuilder,CreateServerNetworkDriver(new MyNetworkInterface(), settings);
    15.         driverStore.RegisterDriver(TransportType.Socket, driverInstance);
    16.     }
    17. }
    18.  
    We provided a bunch of utility methods in the DefaultDriverBuilder class to get the default NetworkSettings, setup the default pipelines etc.

    You then just need to register this driver constructor in your custom bootstrap

    Code (csharp):
    1.  
    2. class MyCustomNetworkBootstrap :ClientServerBootstrap
    3. {
    4.      override public virtual bool Initialize(string defaultWorldName)
    5.       {
    6.              NetworkStreamReceiveSystem.DriverConstructor = new MyCustomDriverConstructor();
    7.              return base.Initialize(defaultWorldName);
    8.       }
    9. }
    10.  
     
  10. chefneil

    chefneil

    Joined:
    Aug 21, 2020
    Posts:
    29
    Incredibly helpful - will be trying this out. Thank you