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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question How do we achieve a Minecraft-style client/server playmode?

Discussion in 'NetCode for ECS' started by AlexHolderDev, Apr 10, 2023.

  1. AlexHolderDev

    AlexHolderDev

    Joined:
    Jul 2, 2014
    Posts:
    35
    Hey team, just trying to build my definitely-not-a-Minecraft-clone game and stumbling into blocking, unclear Netcode functionality.

    My game is targeting consoles. Dedicated servers are optional -- the clients must be able to be servers and clients at the same time, much in the same way that Minecraft clients can host worlds on any platform whether they're dedicated servers or hybrid/listen servers.

    Essentially, I need to be able to run a situation where the client hosts a server in the same process as the client, and other clients from devices around the world can connect to that client-hosted server.

    I have:
    • WebSockets (not IPC!) set up as my network interface and that can easily swap to UDP if needed
    • builds across different devices on my network
    • manual control over the server & client worlds and their connection settings & state, since some platforms require you to arrange network permissions before initiating any network requests/listening.
    ...but the clients can't connect to these client-embedded servers unless they're extra copies of the game running on the same device due to how Netcode falls back to loopback connections.
    Again, that doesn't work for console games.

    I'm unsure how to work around what Netcode is providing or enforcing to achieve this;
    • Documentation, specifically this page, implies that ClientAndServer should be the playtype/playmode (which label?) that I want, however...
    • The SanitizeConnectAddress function within the NetworkStreamDriver forces all connections on Client/Server clients to run in loopback mode.
    • Embedding Netcode and then removing that chunk of "sanitization" causes additional errors about invalid RPC protocol versions that I can't fix, even with the one forum thread that suggests rebooting the editor PC and reimporting all project assets. An additional thread with a mysterious Unity ticket has no conclusion.
    • Making things work via a custom edit to an embedded package is not good for project longevity anyway.
    • The Netcode Sample repository has plenty of samples that involve Relay (an additional cost, especially since I'm in the Australia region -- no thanks!) or more loopback connections, not helpful.

    So, what is the point of the "client/server" Netcode playmode?
    Can it achieve what I want to do here regarding Minecraft-style client/server playmode? How?
    What resources should I be looking at to do this?
     
  2. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    806
    Hey,
    Using Client/Server is correct and allow you to connect client from wherever you want.
    The Client/Server mode is made for this and work on console too.. Mobile as well..

    There was a bug in the SanitizeConnectAddress that has been already addressed. There is a thread in the forum for that.
    The Local client (the player that bost host and play) MUST connect to the loopback, the other clients should not.

    this is because you are trying to connect a client to that server but he have a different set of RPCs. This usually happen if you try to connect using the Editor and Netcode embedded because we have RPC in tests.

    You need to enable the use of DynamicAssemblyList in the RpcSytem. This thread posted by @Occuros say more about that and the SanitiseAddress too https://forum.unity.com/threads/1-0-0-pre-65-short-guide-for-creating-fully-working-builds.1419512/.

    We have also Relay sample has well. And you must use that if you want people around the world to connect to you. There is no way without some form of UDP hole punching and NAT traversal (that we don't provide) to connect any device on the internet.
    And even with that, depending on the Router and Firewall configuration it may be still not possible. Of course, you can use port-forwarding and some other stuff to proper setup the router to allow incoming connections to port X but again, depending on the ISP that may be not sufficient.
     
  3. AlexHolderDev

    AlexHolderDev

    Joined:
    Jul 2, 2014
    Posts:
    35
    Thankyou for the speedy response!

    I'll give Relay a try throughout the week and re-read the Netcode for ECS samples involving Relay -- I really hyper-focused on ignoring Relay before, I was so sure this could be done without a relay system. I've fixed things per everything else you've said too but the using Unity Relay or some other relay system really does seem to be the lynchpin in it all.
     
  4. AlexHolderDev

    AlexHolderDev

    Joined:
    Jul 2, 2014
    Posts:
    35
    As a follow-up on this, I don't have a pretty solution to share just yet that would meet standards of my usual educational work but I do currently have UDP punchthrough & programmatic port forwarding working, meeting the needs I mentioned in the OP.

    The more I looked into Unity Relay, the more I realised it really isn't suitable for what I want to do. It's been great to dig into it to learn more about networking concepts, for sure, but it really solidifies to me that I shouldn't use it.
    • It has a high cost if your game is successful. Seriously - check game analytics websites to find concurrent players of successful, similar games to your own and think about how much Unity Relay would cost those games. Thousands per month just to let players connect to each other -- that's not even the cost of actually hosting game servers, too.
      • Can't use the free relays provided by some of the platform managers (eg. Steam, Nintendo) if you want cross-platform multiplayer, too.
    • It introduces more, critical dependencies. If Unity Relay goes down, your game's multiplayer stops working. If Unity Authentication goes down, Unity Relay goes down. If you can do multiplayer without it, do it without it purely for stability/security reasons.

    And then to top it all off, as someone building definitely-not-a-Minecraft-clone, I got the greatest confirmation that I'm on the right track with what I'm doing:


    This punchthrough is working without a mediation/rendezvous/etc server in the middle, too. This is done by mapping multiple ports; one port for a general punchthrough and basically a handshake to identify actual game client/server connection info. Then another port to actually run client/server connections. All works well so far!

    From what I can find when digging around online, the failure rate on this can be anywhere from 1% to 9%. Numbers reported can be higher sometimes, but a lot of the reports with higher numbers are also extremely old and thus don't represent modern NAT device capabilities. The project with a 1% punchthrough failure rate is the most-recent anecdote I can find about this technique from a mere 5 months ago, and they used a relay service as a fallback to cover that 1% of failing connections. So I might revisit relay integrations at a far later date but it just comes across as a low priority now.

    I'm currently tidying up the proper flow of NAT setup for this demo project, then will transplant it to my actual game project to sort out multiplatform stuff, and then will reshare what I'm doing in more detail after that's all sorted out.

    I don't do gamedev as my dayjob so it may be a while before I have anything to show off, but if anyone wants to try and mess around with this on their own just try out these libraries:
    But yeah. This works. This works great.

    As much as I might come across as "hurr durr Relay is the devil", it's been really helpful to learn about it, learn what problems it solves, learn how it solves those problems, and then dig around to find the not-Relay way of solving those problems. It's all been really useful. I've learned so much in figuring this stuff out during the week!
     
    tmonestudio and Occuros like this.
  5. PolarTron

    PolarTron

    Joined:
    Jun 21, 2013
    Posts:
    87
    I have really mixed feelings about Unity Relay as a service.

    I understand that UDP requires a relay service to achieve close to 100% connection rate but I do not understand why NAT Punchthrough isn't included by default. I can see that it's "Under Consideration" on the roadmap but it doesn't make sense that such an essential part of UDP networking is just "Under Consideration". I mean, we used NAT Punchthrough back when RakNet was a thing. Why can't Unity provide a NAT Punchthrough server for us to punch some nats? Just do it!

    So right now I'm loving Netcode for Entities. It's everything I've ever dreamed of. But this tiny little thing just really feels like Unity is forcing us to use their paid service by omitting this feature from the package.

    At least Steam Datagram Relay is 100% free so I'm hoping for someone to just make a wrapper for that. Right now I just want to get this game done so I'm using Unity Relay (but I'm not happy).
     
    AlexHolderDev likes this.
  6. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    806
    Unity Relay still has free tier. But indeed is not completely free.
    The OpenNAT and Mono.NAT IIRC use UPNP to configure the router, they are not using punch-trough (that always requires an external STUN/TURN/ICE server.

    There are open and free stun server available on the internet. We don't provide in transport the option to use STUN/ICE to implement a proper hole-punching. That work fine for most case scenario (apart symmetric NAT, that most people does not have.
     
  7. Serrakuzz

    Serrakuzz

    Joined:
    Apr 30, 2023
    Posts:
    1
    Have you tried looking into any other game engines or frameworks that might offer more flexibility in terms of Netcode? I know there are a lot of options out there, so it can be overwhelming, but sometimes just trying out a few different options can help you find the one that works best for your needs. Also, have you considered reaching out to any other developers who have tackled similar challenges? I've found that online communities can be really helpful when it comes to problem-solving. Speaking of online communities, have you checked out https://minecraft.menu? It's a great resource for finding awesome Minecraft servers to play on, and you might be able to connect with some other developers who have experience with Netcode as well.
     
    Last edited: May 1, 2023