Search Unity

  1. Unity 2020.1 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Unity Multiplayer Mirror - Networking for Unity (UNET Replacement)

Discussion in 'Connected Games' started by vis2k, Aug 11, 2016.

  1. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    Yes, tick rate drops when more players connect, that is why the latency increases.
     
  2. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    704
    The missing explanation:

    These tests show 3 transports working with uMMORPG, one of @vis2k asset's, and more or less the reason Mirror was created in the first place. The numbers measure their performance at the server (not client), in a headless linux build.

    50Hz is the frame rate at the server (not the client). You can set it to 30, which will consume less CPU, but it might increase latency a little bit. It is the tick rate at the server. You can set it as unlimited, which will go as fast as possible, but that really eats up CPU.

    The first number CCU is the amount of concurrent users. Those are bots connected to an uMMORPG server and moving around randomly.

    The second number is the RTT (Latency). How long does it take for a message to go from the client, to the server and back to the client again. This measurement includes not just the base transport latency but overhead from Mirror and uMMORPG. It is meant to reflect real world response time as seen by the user. In other words, if you click on the map, how long does it take for the character to start moving. For uMMORPG, anything about 500 ms degrades user experience. Lower is better

    The third number is the cpu usage. 100% = 1 cpu fully busy. It can go higher than 100% if you have more than one core and your application or unity use multiple threads. Lower is better.

    The 4th number is the total amount of cpu used across all cores. If you have 10 cores and use 100% of one, then you would see 10%. Lower is better.

    The last number is the amount of memory used by the server. Lower is better.

    With telepathy in 2018, you see really bad latency with 450 CCU.
    With booster you see it keep relatively low latency even at 420 CCU. Booster is a proprietary not free transport made by vis2k, which offloads TCP server to a separate process.
    We have improved Mirror/Telepathy considerably and now in 2019, it scales almost as well as Booster in these tests, it is able to keep a relatively low latency even at 420 CCU.

    The improvements are due to lots of work in both Mirror and Telepathy that eliminate allocations and in some cases change algorithms from O(n) to O(1)

    The reason these tests are done with uMMORPG, is that these are not synthetics microbenchmarks showing idealized unachievable conditions, but real world workloads that affect uMMORPG users.
     
    Last edited: Jul 18, 2019
    vis2k and hopeful like this.
  3. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,157
    It still does not change my question. The numbers are useless because they are incorrect. It’s not running at 50Hz like documented.

    Releasing a benchmark showing how many ticks per second each server can manage would be much better.
     
  4. antey3064

    antey3064

    Joined:
    Mar 21, 2016
    Posts:
    15
    How many CCU does uSurvival support on this server? At 50 Hz
     
  5. meeruTheCoder

    meeruTheCoder

    Joined:
    Jul 13, 2018
    Posts:
    9
    Mirror saved my life!!! It's just like UNet, but so much better!!
    Five Stars
     
  6. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    A few months ago we tested it with 200 CCU. Should be able to handle way more now, probably 400 CCU at least.
     
  7. dreamlarp

    dreamlarp

    Joined:
    Apr 22, 2011
    Posts:
    854
    Is there a way to have the server migrate to another client if the host player disconnects like the old p2p system?
     
  8. Refeas

    Refeas

    Joined:
    Nov 8, 2016
    Posts:
    107
    Hi there!
    In my NetworkManager, when establishing the final connection between client and server (handshake) I want to send a big byte array back to the client as a final reply. So I created new NetworkMessage class with a byte[] as a public variable. However, when I try to send the message (it's around 26 MB, it will only be sent once), I get max packet size error. Do I have to split the byte array into smaller chunks and send to the client as multiple messages (in this case it would be around 1600, considering 16K packet size, so I'm not sure if that's a good solution) or is there any way to let Mirror do that for me? Thanks!
     
  9. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    UNET had that feature, but we removed.

    If you are using Telepathy as transport then simply increase the max packet size from 16kb to 26mb. You can find that setting if you select the NetworkManager and look for the TelepathyTransport component.
    Note that the higher the max packet size, the more it opens your server up to allocation attacks where an attacker might pretend to send several 26MB packets in a row, causing the server to allocate a lot of memory for them.
     
  10. Refeas

    Refeas

    Joined:
    Nov 8, 2016
    Posts:
    107
    I only need it for the single large message for each client (it is a 4-player P2P scenario, so attacks should be a non issue here). So it is possible to change the Telepathy packet size at runtime for both server and client and after the message was successfully recevied by the client, set it back to default?

    Edit: So I fiddled around with it, and found out two things:
    1) Setting the MaxMessageSize during runtime has no effect since Telepathy .Client & .Server are initialized during Awake and those properties are never updated
    2) When I created my custom method in Telepathy to update the server & client's MaxMessageSize, the error about message being too big disappeared, but instead I got
    ReadMessageBlocking: possible allocation attack with a header of: 28036081 bytes
    .

    So... is the only safe and proper way to do this to send thousands of smaller messages to the client to put the byte array together piece by piece?
     
    Last edited: Jul 21, 2019
  11. dreamlarp

    dreamlarp

    Joined:
    Apr 22, 2011
    Posts:
    854
    vis2k said:
    UNET had that feature, but we removed.

    Yes, we understand this. But how hard will it be to add it back? We are developing a steam p2p game and would like to make sure that the host player leaving or disconnecting will not close the game. Has anyone else here added this feature back?
     
  12. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    You can still set TelepathyTransport's .server/.client .MaxMessageSize as runtime if needed.

    You could compare with the original UNET code from Unity's bitbucket and add the parts back.
    As far as I know, host migration never worked well though. This is insanely hard to get right because you have to transfer 100% of the server state to another client. It's way easier to just host a few cloud instances so people don't have to worry about host migration.
     
  13. Alexees

    Alexees

    Joined:
    Nov 8, 2017
    Posts:
    281
    @vis2k I don't want to be agressive or anything, but I opened up an issue on Github 12 days ago and nobody seemed to have looked into it. Do I need to provide a fix myself or is someone actively working on fixing issues?
     
  14. stanislavdol

    stanislavdol

    Joined:
    Aug 3, 2013
    Posts:
    279
    @vis2k
    when I try to connect to a server from a webgl, i get this error (itch.io)
    Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.


    I noticed that in your docs websocket transport looks different than the one available.

    There is no Secure tick box or Certificate input fields.
    I assume this is because of https, because when I use a http webpage, there are no issue.
    Is there a way to run it on a https page?
     
    Last edited: Jul 24, 2019
  15. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    Sorry about that. We are working on issues all the time, but we prioritize based on what affects our own game projects first.

    We'll get to yours eventually. If you want to help, try to debug it yourself and see if you can provide any additional info that might help :)

    We are currently working on websockets SSL support.
     
  16. stanislavdol

    stanislavdol

    Joined:
    Aug 3, 2013
    Posts:
    279
    Thanks, any ETA on this?(roughly)

    Also, wanted to confirm this:
    When you set the network frequency, for instance, in NetworkTransform (or any script with syncvars or any syncing),
    0 means send immediately if changed,
    0.5 - twice a second.
    But if it is set to 0.5 and there are no changes, will it send anyway every 0.5seconds or not?

    Thanks
     
  17. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    Please join our discord and talk to katori if you want to stay updated on websockets SSL :)
    syncInterval is in seconds yes. And if nothing changed, then it doesn't sync.
     
  18. Abrasive

    Abrasive

    Joined:
    Jul 24, 2019
    Posts:
    11
    Wow many thanks guys for this networking stuff! :)
    And thanks to "Noob do AAA" website for info about it!
     
    ixikos and vis2k like this.
  19. JWLewis777

    JWLewis777

    Joined:
    May 17, 2015
    Posts:
    79
    Hello,
    Currently researching tools to use for multiplayer and I had a few questions, I looked through the forums and your website but couldn't find the info, is there a FAQ available somewhere?

    I built the pong example and tested on the same machine, worked great.
    Tested it on 2 machines on the same network, worked great
    Tested it on 1 machine on a different network then another machine, opened router with DMZ but couldnt connect.

    Basically is this capable of peer 2 peer on different networks? What about Android to PC? Android to Android? Or will I have to setup a rely server system to accommodate non-lan networking?

    Thank you for any help and so far Mirror looks great!
     
  20. pit-travis

    pit-travis

    Joined:
    Sep 17, 2018
    Posts:
    14
    Sorry if this has been asked before, but is there a way to testing multiple clients (+server) from within the editor, without building the project? Currently I start the server in the editor and run clients as separate apps outside of it, but that's pretty cumbersome as you can imagine.
     
  21. pit-travis

    pit-travis

    Joined:
    Sep 17, 2018
    Posts:
    14
    Additional question: Is there a recommended workflow to have prefabs differ on clients and servers? E.g. an NPC prefab on the server has a NavMeshAgent and is only controlled server side, but the prefab (by default) spawns with NavMeshAgent on clients, too. Is there a better way to add custom scripts to these prefabs that remove/disable certain components on client startup?
     
  22. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    704
    Code (CSharp):
    1. public override void OnStartServer()
    2. {
    3.        GetComponent<NavMeshAgent>().enabled = true;
    4. }
    Please note that in host mode an object will be both client and server, so I would not disable it on client startup because then your GameObject won't work on host mode.
     
  23. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    704
    I don't think so. I always build a stand alone and test with that.
     
  24. Alexees

    Alexees

    Joined:
    Nov 8, 2017
    Posts:
    281
    I wanted to add, if the project is rather big and you're using a versioning system, you can checkout the same project as many times as you need server and clients and then run each in its own editor instance.
     
  25. meeruTheCoder

    meeruTheCoder

    Joined:
    Jul 13, 2018
    Posts:
    9
    What if I want to change the rotation axis for the network transform child? There does not seem to be an option for that, and some other features as well.
     
  26. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    What do you mean exactly?
    You should be able to sync position and rotation without problems.
     
  27. Nullxero

    Nullxero

    Joined:
    May 10, 2015
    Posts:
    2
    Hello everyone! This library looks really awesome but im having trouble understanding some simple things.
    If I want to change the Tanks demo so that a projectile hurts another tanks hitpoints, or changes the position of another tank how do I accomplish this?

    Do I make the Projectile class, which has a NetworkBehavior use its OnCollisionEnter method to fire an RPC and have the RPC make the change?
    Do I just tell the OnCollisionEnter to change the gameobject, expecting the change to be synched everywhere?
    Do I create a new NetworkMessage and use NetworkServer.SendToAll() to send my message of this hit to everyone and process it?

    Sorry but the documentation is confusing on how you are actually supposed to route messages between entities.


    If you update the Tanks example to include the full cycle of firing, damaging, and destroying other tanks it would illustrate through example the proper way of solving these problems, but right now I don't know how to proceed.

    Any insight would be highly appreciated!

    Thanks so much!

    -Ben
     
  28. thesupersoup

    thesupersoup

    Joined:
    Nov 27, 2017
    Posts:
    49
    Can NetworkManager transports be swapped programmatically at runtime? (e.g. using Telepathy for LAN games and FizzySteam for net games?)
     
  29. thesupersoup

    thesupersoup

    Joined:
    Nov 27, 2017
    Posts:
    49
    Commands go from client to server. RPCs go from server to client(s). Clients don’t necessarily need to know the HP of other clients, but that could and should probably be maintained on the server then sent out to the clients from there. Multiplayer data routing should always be client to server, then server to everyone.
     
  30. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    You can use the Multiplexer Transport for that :)
     
  31. thesupersoup

    thesupersoup

    Joined:
    Nov 27, 2017
    Posts:
    49
    Since posting, I did discover and study up on the Multiplexer. I'd like a little more control than for them to both be constantly active. I was wondering if there was some way to manipulate the transport of the NetworkManager, but after discovering the Multiplexer, I shifted toward building my own Transport with a flag I can set to make Available() return false. I basically want to force Telepathy for LAN games, and use Steamworks for internet games.

    BTW, I have a fork of FizzySteamyMirror that I updated for use with Facepunch.Steamworks. It's pretty much just a crude swap-out of all Steamworks.NET code at the moment: https://github.com/thesupersoup/FizzySteamyMirror

    I promptly decided I'd rather build my own Transport though, so I'll be working on another Steam transport using Facepunch.Steamworks as the foundation. I'll post a link here once it's functional.
     
    vis2k likes this.
  32. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    704
    You are on the right track. That will definitely work.

    We have also discussed using urls for connections. For example, if you connect to
    tcp://somehost:port
    it would use telepathy to connect to that host and port, If you connect to
    ws://somehost:port
    it would use the websocket transport. In your case, I would envision something like
    steam://pierid


    We have not implemented it, or reached a conclusion, but this seems like a good way to go in my mind.
     
  33. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    New showcase: Nestables (made with Mirror)!
     
    JohnnyCar likes this.
  34. newlife

    newlife

    Joined:
    Jan 20, 2010
    Posts:
    852
    Hello,
    Im trying to implement multiplayer in my mobile racing game Real Drift Car Racing.
    In order to avoid hacking, I need an approach based on dedicated authoritative server (not listen server).
    Is this possible and feasible with mirror? It seems that mirror is more oriented towards MMO games.
    Can it be used with racing game too?
     
  35. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    Yes, that's doable. Mirror is server authoritative by default.
     
  36. thesupersoup

    thesupersoup

    Joined:
    Nov 27, 2017
    Posts:
    49
    Presenting MirrorpunchSteam
    I'll be working on it and testing intensely throughout the week. It's likely to have problems in its current state, but it's a start.
    Questions for the more learned:
    • I wanted a way to be able to unregister events for cleaner shutdown, so in the root MirrorpunchSteam I set Action variables to lambda expressions so I could do so. Are there any issues with this approach?
    • How does the NetworkManager handle connection ids, if I'm assigning them in the transport. Is it fairly agnostic to how it routes data associated with connection ids?
     
    MaZy and Refeas like this.
  37. newlife

    newlife

    Joined:
    Jan 20, 2010
    Posts:
    852
    thanks for the reply. Does mirror also support matchmaking and room creation?
     
  38. MonkeyS_Finger

    MonkeyS_Finger

    Joined:
    Nov 11, 2017
    Posts:
    7
    there is a way co connect with another project to a main project network? I wold like to create two different unity projects that use a thirf project as server for sharing data.
    could this be possible with mirror?
    Could you please point me into the right direction?
    thanks.
     
  39. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    Latest showcase: Rogue Star Rescue - a roguelike tower defense game made with Mirror!


    It's not in Mirror by default, but you can do that with Mirror.

    We recommend using one project for everything. That's what Mirror was for after all.
     
  40. MonkeyS_Finger

    MonkeyS_Finger

    Joined:
    Nov 11, 2017
    Posts:
    7
    I know that but I need to control some parameters by a different device, and is impossible to make that project work on a very different device.
    So it's impossible to make connect two different projects?
    If I use LLAPI to create a custom socket, do Mirror could have any trouble?
     
  41. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    Not 100% sure what you mean. Perhaps our Multiplex transport is useful for you.
     
  42. antsonthetree

    antsonthetree

    Joined:
    May 15, 2015
    Posts:
    75
    Hello - I need to send a collection of structs or classes to a client using TargetRPC. The data is just a string and an int. I am currently planning on doing this as follows:

    Code (CSharp):
    1. class MyThing
    2. {
    3.     string Name;
    4.     int Age;
    5. }
    6.  
    7. void TargetSendData(NetworkConnection conn, List<MyThing> data)
    8. {
    9.     // do stuff with data
    10. }
    My question - Is this the best way to do this in regards to network performance and bandwidth? Should I use a struct instead of a class? Possibly a different type of collection vs List?

    This is not something that will be called repeatedly but I'd still like to keep it as performant as possible.

    Thanks
    Jake
     
  43. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    New Feature: SyncToOwner. Each component can be configured to sync to all observers, or only to owner. This will save large amounts of bandwidth for components like a player inventory, that shouldn't be synced to anyone else. Enjoy!



    You can't send Lists in Rpcs. Only simple types like int, string, bool, int[], string[], etc. and structs like SomeStruct, SomeStruct[], and so on. In your case, simply send an Array and make sure that it's a struct.
     
    akuno, KarlGG, psistalk and 1 other person like this.
  44. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,787
    Hi Does Mirror supports NAT punch through? Also, does it support console platforms? Has anyone shipped a game using mirror on console platforms? Or attempted?
     
    Last edited: Sep 2, 2019
  45. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,621
    Check out mirror-networking.com for our showcase.
    Mirror doesn't really care what platform you use it for, they all work.
    Check out our UDP transports, I think a few of them might be able to support nat punchthrough.
     
  46. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    704
    New Feature: Custom readers and writers.

    Since the dawn of time, HLAPI and Mirror have only been able to deal with a limited number of data types. Simple things like passing a DateTime or Uri as parameters in your [Command], [Rpc] or [SyncVar] would give you an error.

    Starting with version 3.17.2 available at https://github.com/vis2k/Mirror/releases, you can extend Mirror and add support for any type you desire. All you need to do do is add extension methods for NetworkReader and NetworkWriters. For example:

    Code (CSharp):
    1. public static class DateTimeReaderWriter
    2. {
    3.       public static void WriteDateTime(this NetworkWriter writer, DateTime dateTime)
    4.       {
    5.           writer.WriteInt64(dateTime.Ticks);
    6.       }
    7.      
    8.       public static DateTime ReadDateTime(this NetworkReader reader)
    9.       {
    10.           return new DateTime(reader.ReadInt64());
    11.       }
    12. }
    There is no reflection involved. The weaver will find your extensions and use them just as if you were writing the code by hand, there is no performance penalty at all. Thanks to @vis2k for keeping me honest and help me find the simplest way to achieve this feature.
     
    Last edited: Sep 3, 2019
    Wattosan, akuno, thesupersoup and 4 others like this.
  47. francescoStrada

    francescoStrada

    Joined:
    Oct 27, 2014
    Posts:
    4
    Hi, with mirror what are my options of sending RPC to specific clients?
     
  48. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    704
  49. antsonthetree

    antsonthetree

    Joined:
    May 15, 2015
    Posts:
    75
    Hello - I noticed in some of the comments that you have removed a lot of linq code for performance reasons. Can you talk a bit about this? I was not aware that using linq is a performance hit, and a quick google search seems to indicate that it is not. I'm just curious.
     
  50. Refeas

    Refeas

    Joined:
    Nov 8, 2016
    Posts:
    107
    A lot of the Linq functions cause allocations which are pretty performance heavy and can cause big spikes on CPU. You can observe this in the "GC Allocs" column in the Profiler.
     
    antsonthetree and vis2k like this.
unityunity