Search Unity

Unity Multiplayer UNET and Steamworks

Discussion in 'Connected Games' started by JonDadley, Jun 30, 2015.

  1. JonDadley

    JonDadley

    Joined:
    Sep 2, 2013
    Posts:
    139
    I'm looking at adding multiplayer to an existing game using UNET as the API and Steam (via Steamworks) to matchmake / connect users.

    As understand it, Unity's matchmaking and user connection service will be a paid service. Am I correct in saying that I could use Steam (via Steamworks) to do this side for free while still using the UNET API to hook up all the data that needs moving around?

    As you can imagine, I'm very new to networking principles so I'm still quite hazy on how this all fits together, even after reading all the blogs and info on UNET I could find.
     
  2. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,033
    Hi!

    No, this is not possible. If you want to use steams networking API (including their peer-to-peer connection, automatic proxy, nat-punch-through, etc.) you have to write your own networking layer on top, or use a third party solution which allows you to switch out the underlying networking layer (like Bolt).

    If you want to use UNET, you have to go through matchmaking and connection service.
     
    Zorranco and JonDadley like this.
  3. JonDadley

    JonDadley

    Joined:
    Sep 2, 2013
    Posts:
    139
    Ahhh, ok. Thanks for the info!
     
  4. S4UC1SS0N

    S4UC1SS0N

    Joined:
    May 29, 2014
    Posts:
    30
    I dont see why it would not be possible to use Steamworks to connect players with NAT punchthrough to a unet host (and then avoid the unity relay server) :s
     
    Last edited: Jun 21, 2016
  5. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    777
    Yeah, it is totally possible to use steamworks lobbies for basic matchmaking at the very least. All you're doing is passing around connection info so there's no reason steam lobbies would work any less than some webservice or w/e other matchmaking you would use.
    Code (CSharp):
    1. SteamMatchmaking.SetLobbyData(steamIDLobby, "publicIP", externalIP);
    2. SteamMatchmaking.SetLobbyData(steamIDLobby, "internalIP", internalIP);
    Using the actual steam connection and punchthrough I suspect is also possible using https://docs.unity3d.com/ScriptReference/Networking.NetworkTransport.ConnectEndPoint.html but I have not tested so I could be totally wrong about that one.
     
    Last edited: Jun 21, 2016
  6. S4UC1SS0N

    S4UC1SS0N

    Joined:
    May 29, 2014
    Posts:
    30
    Being able to use Steamworks NAT punch through have the huge advantage of not needing to host a NAT facilitator yourself (of course you need to be on Steam first...)

    Maybe that's a feature you should add to your plugin thegreatzebadia ;)
     
    thegreatzebadiah likes this.
  7. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    777
    Don't worry @S4UC1SS0N, it's all in the works (assuming it's even possible).
     
  8. S4UC1SS0N

    S4UC1SS0N

    Joined:
    May 29, 2014
    Posts:
    30
    If you release it as a cheaper and dedicated plugin, tell me ;)
     
  9. Razmot

    Razmot

    Joined:
    Apr 27, 2013
    Posts:
    262
  10. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    777
    @Razmot Unfortunately no progress on that front yet. It probably won't be until after my studio releases our game sometime around the start of the year. Until then I'm pretty much booked solid.
     
    Last edited: Sep 26, 2016
  11. rempelj

    rempelj

    Joined:
    Aug 3, 2013
    Posts:
    47
  12. stevesalmond

    stevesalmond

    Joined:
    Aug 14, 2013
    Posts:
    7
    Thanks so much for sharing! I'll be sure to give this method a go. Your write-up looks great, but would it be OK to ping you with a question or two if I run into difficulties?
     
  13. rempelj

    rempelj

    Joined:
    Aug 3, 2013
    Posts:
    47
    Yes! And please share if you find a better way to do something.
     
  14. kexar66

    kexar66

    Joined:
    Feb 27, 2013
    Posts:
    34
    Nice! Is it possible to use oculus matchmaking in a similar way?
     
  15. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    6,289
  16. rempelj

    rempelj

    Joined:
    Aug 3, 2013
    Posts:
    47
    I've never worked with Oculus networking so can't say for sure. I had a quick look at their P2P docs and yeah, it looks like you could probably implement it in a similar way.

    Edit: To expand on my answer a bit... Simplified from my article posted above:

    The 3 main pieces you need to work out are:

    1. Connecting:
    -Host creates room/lobby
    -Clients join and request p2p connection
    -Host accepts p2p connection
    -Both client and host create NetworkConnections to represent the p2p connection

    2. Sending data:
    -NetworkConnection.TransportSend is overridden to send data directly to the peer instead of through UNET

    3. Receiving data:
    -Poll for data and pass it to the appropriate NetworkConnection's TransportReceive function


    Oculus networking seems to have everything you need to accomplish this.
     
    Last edited: Nov 1, 2017
  17. stevesalmond

    stevesalmond

    Joined:
    Aug 14, 2013
    Posts:
    7
    Hey @rempelj, I've had a go at porting my existing UNET stuff across to Steam P2P using your approach. Thanks again for the awesome docs and sample project!

    So far, it seems to basically work, but with some serious performance issues. In my initial testing with a single client and host, the client starts off synchronized, but drops further and further behind as the game progresses. I'm streaming state updates from the host to client and a decent rate (up to 30Hz depending on what's happening in the game world.) It feels like Steam P2P messages are not being sent in real time, but are being queued up and arriving effectively 0.5x realtime or thereabouts.

    Perhaps the P2P traffic is being throttled by Valve somehow? Don't think I'm sending a totally crazy amount, typically somewhere in the region of 10kB/s I would guess. Maybe there is something I have to do in the Steamworks app configuration side of things.. I was wondering, have you encountered anything like this during your dev efforts, and/or are you aware of any Valve/Steam tools I could use to diagnose the issue?

    Cheers!


    EDIT: Think I've figured out what was going on - the Update() method in SteamNetworkManager appears to only process a single P2P packet per frame. I'm sending a bunch of packets per frame, so it's inevitably falling behind over time.

    Changing:
    if (SteamNetworking.IsP2PPacketAvailable(out packetSize))
    to
    while (SteamNetworking.IsP2PPacketAvailable(out packetSize))

    seems to fix things nicely! Not sure if this will help anyone else, but may as well post it up in any case.
     
    Last edited: Nov 7, 2017
    rempelj likes this.
  18. rempelj

    rempelj

    Joined:
    Aug 3, 2013
    Posts:
    47