Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Showcase Mirror - Open Source Networking for Unity

Discussion in 'Multiplayer' started by mischa2k, Aug 11, 2016.

  1. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Probably a good idea to join our discord and talk to the UDP transport devs, namely Coburn and Petris.
    We have Ignorance(ENET), Litenetlib, LLAPI as options for UDP. I recommend trying all three transports to see which one works best in your situation.
     
  2. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Small Update: Mirror's default Telepathy (TCP) transport now works with both IPv4 and IPv6!
     
  3. abdulraheem_taha

    abdulraheem_taha

    Joined:
    Jun 26, 2018
    Posts:
    2
    I'm a beginner in Networking so excuse my question. Is it possible to use a Shared Hosting Server with Mirror? Or you need a Dedicated/VPS server to make it work properly (Regardless speed and bandwidth differences).
     
  4. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    VPS/Dedicated are required
     
  5. CameronBondeSAE

    CameronBondeSAE

    Joined:
    Feb 9, 2017
    Posts:
    6
    Howdy, I added an AnimationCurve variable and now Mirror is complaining. The first error is the main one (which then causes loads more)

    Code (CSharp):
    1. Mirror.Weaver error: UnityEngine.AnimationCurve is not a supported type
    2. UnityEngine.Debug:LogError(Object)
    3. Mirror.Weaver.CompilationFinishedHook:HandleError(String) (at Assets/Plugins/Mirror/Editor/Weaver/CompilationFinishedHook.cs:42)
    4. Mirror.Weaver.Log:Error(String) (at Assets/Plugins/Mirror/Editor/Weaver/Program.cs:20)
    5. Mirror.Weaver.Weaver:Error(String) (at Assets/Plugins/Mirror/Editor/Weaver/Weaver.cs:174)
    6. Mirror.Weaver.Readers:GetReadFunc(TypeReference, Int32) (at Assets/Plugins/Mirror/Editor/Weaver/Readers.cs:97)
    7. Mirror.Weaver.Readers:GenerateStructReadFunction(TypeReference, Int32) (at Assets/Plugins/Mirror/Editor/Weaver/Readers.cs:273)
    8. Mirror.Weaver.Readers:GetReadFunc(TypeReference, Int32) (at Assets/Plugins/Mirror/Editor/Weaver/Readers.cs:92)
    9. Mirror.Weaver.NetworkBehaviourProcessor:ProcessNetworkReaderParameters(TypeDefinition, MethodDefinition, ILProcessor, Boolean) (at Assets/Plugins/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs:613)
    10. Mirror.Weaver.RpcProcessor:ProcessRpcInvoke(TypeDefinition, MethodDefinition) (at Assets/Plugins/Mirror/Editor/Weaver/Processors/RpcProcessor.cs:26)
    11. Mirror.Weaver.NetworkBehaviourProcessor:ProcessClientRpc(HashSet`1, MethodDefinition, CustomAttribute) (at Assets/Plugins/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs:782)
    12. Mirror.Weaver.NetworkBehaviourProcessor:ProcessMethods() (at Assets/Plugins/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs:732)
    13. Mirror.Weaver.NetworkBehaviourProcessor:Process() (at Assets/Plugins/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs:47)
    14. Mirror.Weaver.Weaver:ProcessNetworkBehaviourType(TypeDefinition) (at Assets/Plugins/Mirror/Editor/Weaver/Weaver.cs:215)
    15. Mirror.Weaver.Weaver:CheckNetworkBehaviour(TypeDefinition) (at Assets/Plugins/Mirror/Editor/Weaver/Weaver.cs:441)
    16. Mirror.Weaver.Weaver:Weave(String, IEnumerable`1, IAssemblyResolver, String, String, String) (at Assets/Plugins/Mirror/Editor/Weaver/Weaver.cs:577)
    17. Mirror.Weaver.Weaver:WeaveAssemblies(IEnumerable`1, IEnumerable`1, IAssemblyResolver, String, String, String) (at Assets/Plugins/Mirror/Editor/Weaver/Weaver.cs:646)
    18. Mirror.Weaver.Program:Process(String, String, String, String[], String[], Action`1, Action`1) (at Assets/Plugins/Mirror/Editor/Weaver/Program.cs:34)
    19. Mirror.Weaver.CompilationFinishedHook:OnCompilationFinished(String, CompilerMessage[]) (at Assets/Plugins/Mirror/Editor/Weaver/CompilationFinishedHook.cs:129)
    20. UnityEditor.Scripting.ScriptCompilation.EditorCompilationInterface:TickCompilationPipeline(EditorScriptCompilationOptions, BuildTargetGroup, BuildTarget)
     
  6. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    That type can't be serialized by Mirror. Are you sure you want to send an Animation Curve over the network?
    Usually they don't change at runtime, you might not need to sync it.
     
  7. CameronBondeSAE

    CameronBondeSAE

    Joined:
    Feb 9, 2017
    Posts:
    6
    Ah, ok. Yeah I guess it's not usually needed. I'm making a 12 Oculus GO's synced VR Cinema app and cave set up. From the server I send a serialisable object with the video clip details of what clip to play to each headset (but the clips themselves are local to each headset).
    This is just for simplicities sake as I'm always changing the master playlist on the server. This way I don't need to sync them. I can also change the playlist on the fly.
    I might have to just send the whole playlist over as JSON and read the curves locally (Anim curves serialise fine to JSON)
    The curves themselves are for motion sickness profiles, so which bit might make people feel like puking :) That way I can draw in the periperal vision, or blank it out for those bits.
     
  8. LeetRooster

    LeetRooster

    Joined:
    Jul 20, 2013
    Posts:
    18
    Hi, I was wondering if it makes sense to compose SyncLists/SyncDictionaries

    I.e. imagine having a SyncDictionary of SyncDictionaries. If you modify a key/value pair in the inner SyncDictionary, is Mirror intelligent enough to only update the one entry in the inner dictionary? OR will it try to serialize the whole inner SyncDictionary, which would be expensive and kind of defeat the purpose?
     
  9. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Mirror doesn't support composing those types, sorry.
     
  10. stanislavdol

    stanislavdol

    Joined:
    Aug 3, 2013
    Posts:
    282
    Hi, wanted to ask whether using [command]s to send Inputs to the server is the best way to make a fully authoritative server logic using Mirror. Or may be there are benefits of using NetworkMessages or SyncVars instead?
     
    LeetRooster likes this.
  11. LeetRooster

    LeetRooster

    Joined:
    Jul 20, 2013
    Posts:
    18
    Hi, I am trying to understand the situations where you would use a [ClientRPC]/[TargetRPC] over the use of NetworkMessages/NetworkServer.SendToAll(msg).

    Both of these seem to allow you to send an RPC Server->Client. However, it seems that you can write a custom serializer for the message in NetworkServer.SendToAll();

    In my case, I want to send a message which can contain a complex structure (List, Dictionary or Array). Am I forced to use the SendToAll approach? Or can the parameters to the [ClientRpc] contain a the complex structure, and can I somehow specify how that is serialized/deserialzed?

    The other approach I can think of is to send every element in my structure one at a time with a ClientRPC. But I am unsure if there are guarantees that every message is sent, and if they are send in order.
     
  12. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    That depends.
    For example, Minecraft mostly sends inputs to the server. If you press the inventory key then it sends that key to the server. Then the server opens the inventory.

    Other games don't send all the input to the server. You most likely don't need to let the server decide when to open/close the inventory, it's fine if that is client sided. Additionally it would also avoid any delays when opening the inventory, since you don't have to wait for the server's reply.

    Rpcs only work for simple types, e.g. int, string, bool, Array.
    If you need custom serialization then create a new NetworkWriter, write whatever you need into it, then send it via Rpc (by using .ToArray() and sending a byte array) or SendToAll.
     
  13. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Progress: we have been working on several smaller performance improvements to reduce GC spikes and support more CCU.

    New Showcase: One More Night by Big Red Planet is using Mirror!
     
  14. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Important Update:
    NetworkReader reimplemented. Benchmark with 1000 readers:

    Before:


    After:


    • Memory usage reduced from 250 KB to 48 bytes.
    • CPU time reduced from 3.82ms to 0.33ms.
     
  15. unity_Cn_9LZVSq85wBA

    unity_Cn_9LZVSq85wBA

    Joined:
    Apr 30, 2019
    Posts:
    5
    Hi @vis2k, would you please help me to figure it out ?
    I have a function with the tag "Command" , this function is supposed to execute on server ? because when I log isServer in this function I have false

    I have this code attach to player prefab

    Code (CSharp):
    1.  public void SetAuth(NetworkIdentity identity)
    2.    {
    3.        if (isLocalPlayer)
    4.        {
    5.  
    6.            CmdSetAuthority(identity);
    7.        }
    8.    }
    9.  
    10.    public void RemoveAuth(NetworkIdentity identity)
    11.    {
    12.        if (isLocalPlayer)
    13.        {
    14.  
    15.            CmdRemoveAuthority(identity);
    16.        }
    17.    }
    18.  
    19.    [Command]
    20.    void CmdSetAuthority(NetworkIdentity identity)
    21.    {
    22.        var currentOwner = identity.clientAuthorityOwner;
    23.  
    24.        // hasAuthority : true if host, false if client
    25.        Debug.Log("localPlayer" + identity.hasAuthority );
    26.        // Debug.Log("SERVER" + isServer);
    27.        // Debug.Log("owner" + currentOwner);
    28.        // Debug.Log("connect" + connectionToServer);
    29.  
    30.        if (currentOwner == connectionToServer)
    31.        {
    32.            return;
    33.        }
    34.        else
    35.        {
    36.            if (currentOwner == null)
    37.            {
    38.                Debug.Log("OK");
    39.  
    40.                identity.AssignClientAuthority(connectionToServer);
    41.            }
    42.            else
    43.            {
    44.                Debug.Log("Not OK");
    45.            }
    46.        }
    47.    }

    In another script I search all the player prefab in the scene and call the function SetAuth, then I check if the player instance is local then call the Command function, but in the function CmdSetAuthority when I log isServer I received false. And I can't AssignClientAuthority because i'm not in server
     
  16. FoleyX90

    FoleyX90

    Joined:
    Dec 7, 2012
    Posts:
    3
    I can't seem to find anything on Host Migration. Could someone point me to the right place?
     
  17. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    We removed that feature
     
  18. Deleted User

    Deleted User

    Guest

    @vis2k the reason I am using Mirror is, because it's the better UNET. The reason I was using UNET is because we also support UWP. I now found out that the LLAPITransport script does not support UWP, even though the UNITY LLAPI does. We also use Dissonance voice, which, according to the docs, needs an UDP transport, preferably Ignorance, which does not support UWP...
    Is there even one possible combination that allows me to use Dissonance on UWP?
     
  19. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Why does the LLAPI transport not work on UWP?
    Is there an error that you encountered? It really just wraps the built in LLAPI, and if that worked for you own UWP then this should work too.
     
  20. Deleted User

    Deleted User

    Guest

    Your whole LLAPITransport.cs script is wrapped in a directive that avoids its usage as a component on UWP. How does this work with running the NetworkManager on different platforms? Do i need to add it on all other platforms but remove it on UWP? Do I need to use a different script then?
     
  21. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Feel free to remove the #if and see if that works. We initially added them because LLAPI wasn't found on UWP. Not sure why that works for you with UNET then.
     
  22. Deleted User

    Deleted User

    Guest

    I will.
    We have an application running that uses the portal and Hololens and is happily networking using UNET for 1,5 years now
     
  23. YuriPetskus

    YuriPetskus

    Joined:
    Jun 22, 2018
    Posts:
    18
    Are there any plans to optimize for mobile?
     
  24. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Any optimization/fix that we make applies to all platforms :)
     
  25. YuriPetskus

    YuriPetskus

    Joined:
    Jun 22, 2018
    Posts:
    18
    I understand ))
    Is there optimization for cases that only appear on mobile devices?
    For example, when the Internet disappears in subway.
     
  26. Mr-Berni

    Mr-Berni

    Joined:
    Aug 29, 2017
    Posts:
    9
    Hey vis I saw your post on the forums -- Update: NetworkTransform now uses .localPosition and .localRotation for proper VR support  --

    I'm trying to sync up hands and head that are children of the player prefab in ummorpg.

    At this point I'm just trying to get a child cube transform to be tracked across the network and I'm having trouble...

    I know that you cant just sync up the rig through the network (I have been through this with pun in other projects). So i have seperate head and hand object following the pos and rotation of the clients camera rig. I want to send the transform of those 3 gameobjects. They are children of the player prefab in ummorpg. They spawn great but the transforms dont update when I have other users move around.

    Please help! :(
     
  27. stanislavdol

    stanislavdol

    Joined:
    Aug 3, 2013
    Posts:
    282

    Currently TransformBase works only with local authority models, correct?
    I mean, it doesn't seem possible to use it with authoritative server and client-side prediction for lag compensation, since it will overwrite position/rotation of a local player.
    And it only sends position/rotation, there is no server timestamp (only local one) to compare with an old position(not a previous received one, but a position of a local player at a certain moment in time)
     
  28. robochase

    robochase

    Joined:
    Mar 1, 2014
    Posts:
    244
    hey i stepped away from this scene for a while, but i'm glad to see it's still thriving. I've been thinking a lot about networking solutions lately, and I keep coming back to UNET for alot of reasons, so this project is pretty compelling.

    It looks like cecil was moved into the source code huh? so this should effectively be future proofed if/when unity shuts off UNET and cecil? so we can still do command/rpc architecture and cecil injects repetitious code at compile time.

    Also, how easy is it to plug in different low-level transports? i see on the github page a variety of transports are supported, but i'm curious about ones that aren't listed. steamworks is a big one for example. i think the oculus storefront also provides their own networking solution that would be cool to tap into.
     
  29. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    We use a custom Cecil version, which is based on latest Cecil from the original Cecil developer (not Unity's version), with one bug fix applied to it for the Weaver.
     
  30. JLJac

    JLJac

    Joined:
    Feb 18, 2014
    Posts:
    36
    Hello and thank you for making and maintaining this!
    I'm doing my multiplayer "hello world". Got some synchronized little players running around on two builds using the NetWorkManagerHUD default LAN stuff, but now I want to test over the internet. I want to host it on one computer and enter the IP on another, like this stuff from the old NetworkLobby asset:



    Has anyone created a NetworkLobby like that for Mirror? Or is this actually something super obvious and easy that I'm missing?

    Thanks!
     
  31. stanislavdol

    stanislavdol

    Joined:
    Aug 3, 2013
    Posts:
    282
    Also, I just noticed:
    In documentation it says:
    The GetParameterAutoSend and SetParameterAutoSend functions can be used to control which individual animator parameters should be automatically synchronized.

    However, these functions are missing from Network Animator
     
  32. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Check out the examples folder that comes with Mirror.
    MrGadget created a lobby already.

    Those aren't needed anymore :)
     
  33. JLJac

    JLJac

    Joined:
    Feb 18, 2014
    Posts:
    36
    Thanks for your answer. In the examples I can find several LAN examples, as well as one List Server example (the tank game). What I want is just:

    - A text label that shows my IP.
    - A host button and a join button.
    - A text field where I can enter my friend's IP and press join.

    So, skipping the entire "matchmaking" step - I'll get to that later, but first I just want two computers to talk to each other in the simplest way possible, ie by manually entering the IP. Is this possible? I'm very confused that I can't find examples of this anywhere in online tutorials, as I feel it would be the very natural first step (rather than building some big lobby infrastructure with dedicated list servers etc) and I am wondering if I am missing something obvious.
     
  34. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    News: we have been doing MAJOR performance improvements to Mirror. The screenshot shows the uMMORPG stress test from last year, and from today. Notice how in the third table (which was today), raw Mirror+Telepathy is now almost as fast as the booster, and around 10x faster than last year (when considering latency at 400+ CCU).

    Just to be clear, this is the current Mirror master. Nothing experimental, this is available to everyone right now!

     
    hopeful likes this.
  35. antey3064

    antey3064

    Joined:
    Mar 21, 2016
    Posts:
    15
    Please do the stress test of the USurvival asset. Since dynamic MMOFPS and MMORPG are completely different things.
     
  36. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Still nonsense numbers, what are the tickrates?

    What indicates that the new builds are faster? What are the updates per second? Only difference I see is higher latency?

    Or are you telling me the ms is the ticktime??
     
  37. blacksun666

    blacksun666

    Joined:
    Dec 17, 2015
    Posts:
    214
    I assumed the tick rate was 50Hz? Can anyone confirm this? Also what the network latency is this was tested across i.e. lan speed network,etc?
     
  38. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Oh right.. now it makes even less sense. I didnt notice the 50Hz.

    Assuming both run 50 ticks per second, and use the same amount of CPU. That tells me no speed improvement. (Because it uses the same amount of CPU for the same amount of work). Instead a speed degredation. The old version handled 450 at 96% and the new one handles 420 at 97%. So it's worse results. ASSUMING that they both run exactly 50 ticks per second. Which probably isnt the case since you are maxing your CPU. You probably set TARGETframeRate to 50 and called it the day.

    Instead, dont lock the tickrate. Let both run, and see how many ticks per second each build can pump. That way you get meaningful results. If the new build runs twice as many iterations per second, it's twice as fast. Simple. But I assume you probably have tons of variables in your benchmarks, such as graphics and stuff.
     
    Last edited: Jul 11, 2019
  39. gianelli98

    gianelli98

    Joined:
    Mar 15, 2017
    Posts:
    8
    Hi, I was using your network solution on my project in Unity Version 2017 and it worked so well, after few months of development I decided to recreate(from scratch) my project in Unity 2018.4 but I got a problem now, the objects already in scene with network identity only spawn in Server and not in Client, what am I doing wrong?

    Edit: I tried with build/build and build/editor also.
     
    Last edited: Jul 11, 2019
  40. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Did you try to delete your library folder and then reimport it?
    Do you get any error messages?
    Are all the prefabs added to the NetworkManager's spawnable prefabs list?
     
  41. MedoMelo

    MedoMelo

    Joined:
    Jul 5, 2019
    Posts:
    42
    Hi!

    I'm a indie and I'm making a multiplayer game (4 players), in a persistant environment.
    I'm looking for tools to create a p2p authoritative architecture as I'm not into network programing.

    Am I knocking at the right door? Would Mirror be suited for that?

    Thank you for your answer :) !
     
  42. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Try it :)
     
  43. MedoMelo

    MedoMelo

    Joined:
    Jul 5, 2019
    Posts:
    42
    That means it should handle p2p pretty well haha !

    I'll try it for sure, and thank you for your work here. Very much
     
  44. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    456
    Doesn't ms dictate the speed? Could you elaborate on this further?

    Thanks!
     
  45. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    The benchmark results are mostly about latency.
    If the server chokes, the latency goes up. If the latency stays low, the server can handle the players well.
     
  46. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Ms is milliseconds. It's not documented what this is, I'm assuming latency. Latency is not neccecarly the same as tickspeed. Because they both run at 50hz. So I have no clue how the F*** one would produce such garbage results as 1k ms. I'm assuming by like processing one packet per tick.
    So they are not running at 50hz like documented? Why don't you release one showing how many ticks per second each can produce? That way you can see a straight difference.
     
  47. blacksun666

    blacksun666

    Joined:
    Dec 17, 2015
    Posts:
    214
    @vis2k I'm still not sure what the benchmarks are showing. Do they show the server sending out updates every 20ms (50Hz) but those updates take the stated latency to affect the clients (due to server,network and client delays)? Given the CPU usage on the main thread how sure are you that the updates are still maintained at 20ms intervals?
    Basically trying to find out if the clients have a steady 20ms update but the updates are delayed by the stated latency based on the number of CCU or if the client sees their update rates drop to the stated latencies?
     
  48. mischa2k

    mischa2k

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

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    766
    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
    mischa2k and hopeful like this.
  50. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    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.