Search Unity

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
    Oh this number. Yes it was 24%, but my LLAPI is multithreaded and doesn't use resources from the main thread. There's a LOT of room left.
     
    Driiade and runningbird like this.
  2. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    767
    To keep this number in perspective:
    1. 24% cpu usage is at the server, not at the clients.
    2. 24% cpu usage with 101 clients connected to it in the same place (worst case scenario)
    3. LLAPI had about twice that cpu usage with less users
    4. TCP is happening in a background thread, so this cpu usage does not affect the main thread.
    5. memory usage was 251 MB compared to 798 with LLAPI with less clients.
    So if this number is not good enough for you, then neither is LLAPI or most other transports.
     
    Last edited: Aug 5, 2018
    mischa2k likes this.
  3. ThomasLightweave

    ThomasLightweave

    Joined:
    Sep 30, 2016
    Posts:
    26
    In our case it was due to wanting to write boilerplate communication code in low level network behaviours operating on generic typed variables then add some specific finishing implementations in top level classes, in practice it is a lovely pattern but UNET doesn't want a bar of it.

    The big issue we are having at the moment is that both UNET classic and HLAPI CE are keeling over when trying to compile any of our code once it gets to a certain complexity. It doesn't seem to matter much at all what we add, or if it is referencing UNET (or in a project with any netcode whatsoever) at a certain point it seems to just.. give up.

    Sometimes it is a null reference, sometimes it is a array out of range
    Code (CSharp):
    1. UNetWeaver error: Exception :System.IndexOutOfRangeException: Array index is out of range.
    2.   at Mono.Cecil.PE.ByteBuffer.ReadByte () [0x00000] in <filename unknown>:0
    3.   at Mono.Cecil.PE.ByteBuffer.ReadCompressedUInt32 () [0x00000] in <filename unknown>:0
    4.   at Mono.Cecil.SignatureReader..ctor (UInt32 blob, Mono.Cecil.MetadataReader reader) [0x00000] in <filename unknown>:0
    5.   at Mono.Cecil.MetadataReader.ReadSignature (UInt32 signature) [0x00000] in <filename unknown>:0
    6.   at Mono.Cecil.MetadataReader.GetTypeSpecification (UInt32 rid) [0x00000] in <filename unknown>:0
    7.   at Mono.Cecil.MetadataReader.LookupToken (MetadataToken token) [0x00000] in <filename unknown>:0
    8.   at Mono.Cecil.MetadataReader.GetTypeDefOrRef (MetadataToken token) [0x00000] in <filename unknown>:0
    9.   at Mono.Cecil.MetadataReader.ReadType (UInt32 rid) [0x00000] in <filename unknown>:0
    10.   at Mono.Cecil.MetadataReader.InitializeTypeDefinitions () [0x00000] in <filename unknown>:0
    11.   at Mono.Cecil.MetadataReader.ReadTypes () [0x00000] in <filename unknown>:0
    12.   at Mono.Cecil.ModuleDefinition+<>c.<get_Types>b__102_0 (Mono.Cecil.ModuleDefinition _, Mono.Cecil.MetadataReader reader) [0x00000] in <filename unknown>:0
    13.   at Mono.Cecil.ModuleDefinition.Read[ModuleDefinition,TypeDefinitionCollection] (Mono.Cecil.TypeDefinitionCollection& variable, Mono.Cecil.ModuleDefinition item, System.Func`3 read) [0x00000] in <filename unknown>:0
    14.   at Mono.Cecil.ModuleDefinition.get_Types () [0x00000] in <filename unknown>:0
    15.   at Unity.UNetWeaver.Weaver.Weave (System.String assName, IEnumerable`1 dependencies, IAssemblyResolver assemblyResolver, System.String unityEngineDLLPath, System.String unityUNetDLLPath, System.String outputDir) [0x00000] in <filename unknown>:0
    16.   at Unity.UNetWeaver.Weaver.WeaveAssemblies (IEnumerable`1 assemblies, IEnumerable`1 dependencies, IAssemblyResolver assemblyResolver, System.String outputDir, System.String unityEngineDLLPath, System.String unityUNetDLLPath) [0x00000] in <filename unknown>:0
    17. UnityEngine.Debug:LogError(Object)
    18. Unity.UNetWeaver.Log:Error(String)
    19. Unity.UNetWeaver.Weaver:WeaveAssemblies(IEnumerable`1, IEnumerable`1, IAssemblyResolver, String, String, String)
    20. Unity.UNetWeaver.Program:Process(String, String, String, String[], String[], IAssemblyResolver, Action`1, Action`1)
    21. UnityEditor.Scripting.ScriptCompilation.EditorCompilationInterface:TickCompilationPipeline(EditorScriptCompilationOptions, BuildTargetGroup, BuildTarget)
    Code (CSharp):
    1. UNetWeaver error: Exception :System.NullReferenceException: Object reference not set to an instance of an object
    2.   at Mono.Cecil.SignatureReader.GetGenericParameter (Mono.Cecil.GenericParameterType type, System.UInt32 var) [0x0004a] in <28cdca1704d2491781795499c297b78b>:0
    3.   at Mono.Cecil.SignatureReader.ReadTypeSignature (Mono.Cecil.Metadata.ElementType etype) [0x00153] in <28cdca1704d2491781795499c297b78b>:0
    4.   at Mono.Cecil.SignatureReader.ReadTypeSignature () [0x00007] in <28cdca1704d2491781795499c297b78b>:0
    5.   at Mono.Cecil.SignatureReader.ReadGenericInstanceSignature (Mono.Cecil.IGenericParameterProvider provider, Mono.Cecil.IGenericInstance instance) [0x00023] in <28cdca1704d2491781795499c297b78b>:0
    6.   at Mono.Cecil.SignatureReader.ReadTypeSignature (Mono.Cecil.Metadata.ElementType etype) [0x00176] in <28cdca1704d2491781795499c297b78b>:0
    7.   at Mono.Cecil.SignatureReader.ReadTypeSignature () [0x00007] in <28cdca1704d2491781795499c297b78b>:0
    8.   at Mono.Cecil.MetadataReader.GetTypeSpecification (System.UInt32 rid) [0x00019] in <28cdca1704d2491781795499c297b78b>:0
    9.   at Mono.Cecil.MetadataReader.LookupToken (Mono.Cecil.MetadataToken token) [0x000a4] in <28cdca1704d2491781795499c297b78b>:0
    10.   at Mono.Cecil.MetadataReader.GetTypeDefOrRef (Mono.Cecil.MetadataToken token) [0x00000] in <28cdca1704d2491781795499c297b78b>:0
    11.   at Mono.Cecil.MetadataReader.ReadType (System.UInt32 rid) [0x0006d] in <28cdca1704d2491781795499c297b78b>:0
    12.   at Mono.Cecil.MetadataReader.ReadTypeDefinition (System.UInt32 rid) [0x0000c] in <28cdca1704d2491781795499c297b78b>:0
    13.   at Mono.Cecil.MetadataReader.GetTypeDefinition (System.UInt32 rid) [0x00018] in <28cdca1704d2491781795499c297b78b>:0
    14.   at Mono.Cecil.MetadataReader.LookupToken (Mono.Cecil.MetadataToken token) [0x00090] in <28cdca1704d2491781795499c297b78b>:0
    15.   at Mono.Cecil.MetadataReader.GetTypeDefOrRef (Mono.Cecil.MetadataToken token) [0x00000] in <28cdca1704d2491781795499c297b78b>:0
    16.   at Mono.Cecil.SignatureReader.GetTypeDefOrRef (Mono.Cecil.MetadataToken token) [0x00000] in <28cdca1704d2491781795499c297b78b>:0
    17.   at Mono.Cecil.SignatureReader.ReadTypeSignature (Mono.Cecil.Metadata.ElementType etype) [0x0016a] in <28cdca1704d2491781795499c297b78b>:0
    18.   at Mono.Cecil.SignatureReader.ReadTypeSignature () [0x00007] in <28cdca1704d2491781795499c297b78b>:0
    19.   at Mono.Cecil.MetadataReader.GetTypeSpecification (System.UInt32 rid) [0x00019] in <28cdca1704d2491781795499c297b78b>:0
    20.   at Mono.Cecil.MetadataReader.LookupToken (Mono.Cecil.MetadataToken token) [0x000a4] in <28cdca1704d2491781795499c297b78b>:0
    21.   at Mono.Cecil.MetadataReader.GetTypeDefOrRef (Mono.Cecil.MetadataToken token) [0x00000] in <28cdca1704d2491781795499c297b78b>:0
    22.   at Mono.Cecil.MetadataReader.ReadType (System.UInt32 rid) [0x0006d] in <28cdca1704d2491781795499c297b78b>:0
    23.   at Mono.Cecil.MetadataReader.InitializeTypeDefinitions () [0x00046] in <28cdca1704d2491781795499c297b78b>:0
    24.   at Mono.Cecil.MetadataReader.ReadTypes () [0x00000] in <28cdca1704d2491781795499c297b78b>:0
    25.   at Mono.Cecil.ModuleDefinition+<>c.<get_Types>b__102_0 (Mono.Cecil.ModuleDefinition _, Mono.Cecil.MetadataReader reader) [0x00000] in <28cdca1704d2491781795499c297b78b>:0
    26.   at Mono.Cecil.ModuleDefinition.Read[TItem,TRet] (TRet& variable, TItem item, System.Func`3[T1,T2,TResult] read) [0x0003c] in <28cdca1704d2491781795499c297b78b>:0
    27.   at Mono.Cecil.ModuleDefinition.get_Types () [0x00017] in <28cdca1704d2491781795499c297b78b>:0
    28.   at Unity.UNetWeaver.Weaver.Weave (System.String assName, System.Collections.Generic.IEnumerable`1[T] dependencies, Mono.Cecil.IAssemblyResolver assemblyResolver, System.String unityEngineDLLPath, System.String unityUNetDLLPath, System.String outputDir) [0x00052] in <5825ecc105a0475f96daa8ea516acd65>:0
    29.   at Unity.UNetWeaver.Weaver.WeaveAssemblies (System.Collections.Generic.IEnumerable`1[T] assemblies, System.Collections.Generic.IEnumerable`1[T] dependencies, Mono.Cecil.IAssemblyResolver assemblyResolver, System.String outputDir, System.String unityEngineDLLPath, System.String unityUNetDLLPath) [0x0003c] in <5825ecc105a0475f96daa8ea516acd65>:0
    30. UnityEngine.Debug:LogError(Object)
    31. Unity.UNetWeaver.Log:Error(String)
    32. Unity.UNetWeaver.Weaver:WeaveAssemblies(IEnumerable`1, IEnumerable`1, IAssemblyResolver, String, String, String)
    33. Unity.UNetWeaver.Program:Process(String, String, String, String[], String[], IAssemblyResolver, Action`1, Action`1)
    34. UnityEditor.Scripting.ScriptCompilation.EditorCompilationInterface:TickCompilationPipeline(EditorScriptCompilationOptions, BuildTargetGroup, BuildTarget)

    After it breaks it just spits out all the warnings with the following tacked onto the end:
    Code (CSharp):
    1. Unhandled Exception:
    2. System.IO.IOException: Sharing violation on path D:\Projects\UGRS\Temp\Assembly-CSharp.dll.mdb
    3.  
    4.   at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x0019e] in <f826c2584fc94ec19a48a6576640bdc5>:0
    5.  
    6.   at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean isAsync, System.Boolean anonymous) [0x00000] in <f826c2584fc94ec19a48a6576640bdc5>:0
    7.  
    8.   at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access) [0x00000] in <f826c2584fc94ec19a48a6576640bdc5>:0
    9.  
    10.   at (wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess)
    11.  
    12.   at Mono.CSharp.AssemblyDefinition.Save () [0x0016b] in <1fff364146884fcdb77ba25fbd1b417a>:0
    13.  
    14.   at Mono.CSharp.Driver.Compile () [0x00309] in <1fff364146884fcdb77ba25fbd1b417a>:0
    15.  
    16.   at Mono.CSharp.Driver.Main (System.String[] args) [0x0004c] in <1fff364146884fcdb77ba25fbd1b417a>:0
    17. [ERROR] FATAL UNHANDLED EXCEPTION: System.IO.IOException: Sharing violation on path D:\Projects\UGRS\Temp\Assembly-CSharp.dll.mdb
    18.  
    19.   at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x0019e] in <f826c2584fc94ec19a48a6576640bdc5>:0
    20.  
    21.   at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean isAsync, System.Boolean anonymous) [0x00000] in <f826c2584fc94ec19a48a6576640bdc5>:0
    22.  
    23.   at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access) [0x00000] in <f826c2584fc94ec19a48a6576640bdc5>:0
    24.  
    25.   at (wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess)
    26.  
    27.   at Mono.CSharp.AssemblyDefinition.Save () [0x0016b] in <1fff364146884fcdb77ba25fbd1b417a>:0
    28.  
    29.   at Mono.CSharp.Driver.Compile () [0x00309] in <1fff364146884fcdb77ba25fbd1b417a>:0
    30.  
    31.   at Mono.CSharp.Driver.Main (System.String[] args) [0x0004c] in <1fff364146884fcdb77ba25fbd1b417a>:0

    Meanwhile I am panicking because completely reimplementing this whole system is going to be next to impossible with my current schedule .
     
  4. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Looks like you have so much code that Mono.Cecil.PE.ByteBuffer gets full.
    That is very strange. How big is your project? How many SyncVars/NetworkIdentities/Commands/etc. ?
     
  5. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Update: uploaded new DLL files with a 10% bandwidth improvement on average:

    • Message Header size reduced:
    • Messages used to have a 4 byte header consisting of content size (2 bytes) and message type (2 bytes)
    • We now use varint which results in a 2 byte header almost all the time (except for large messages)
    • This effectively reduces bandwidth by about 10%, assuming an average message size of 20 bytes (it's usually even shorter than that)
     
    LostPanda likes this.
  6. ThomasLightweave

    ThomasLightweave

    Joined:
    Sep 30, 2016
    Posts:
    26
    While the project is not "that" big it uses a metric tonne of generics, for ... complicated submodule reasons.

    for example i have classes with definitions like:

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3.  
    4. namespace Lightweave.UGRS
    5. {
    6.     public interface IBaseSessionData
    7.                 <netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>
    8.  
    9.  
    10.  
    11.        
    12.         where netMatchMan : UnityEngine.Component, IBaseNetworkMatchManager<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>
    13.         where netMatchClient : UnityEngine.Component, IBaseNetworkMatchClient
    14.         where netMatchClientMan : UnityEngine.Component, IBaseNetworkMatchClientManager<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>
    15.         where netMatchManComms : UnityEngine.Component, IBaseNetworkMatchManagerCommunicator
    16.         where netMatchManUI : UnityEngine.Component, IBaseNetworkMatchManagerUI<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>
    17.         where configurationData : class, IBaseConfiguration, new()
    18.         where configurationMan : BaseConfigurationManager<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>
    19.         where scoreMan : UnityEngine.Component
    20.         where scoreComms : UnityEngine.Component
    21.         where scoreClient : UnityEngine.Component
    22.         where scoreClientMan : UnityEngine.Component
    23.         where scoreManUI : UnityEngine.Component
    24.         where scoreMonitorUI : UnityEngine.Component
    25.         where sessionMonitorUI : UnityEngine.Component
    26.         where playerData : class, IBasePlayerData<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>, new()
    27.         where teamData : class, IBaseTeamData<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>, new()
    28.         where campaignData : class, new()
    29.         where sessionData : class, IBaseSessionData<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>, new()
    30.         where gameData : class, IBaseGameData, new()
    31.         where scoreData : class, IBaseScoreData<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>, new()
    32.         where cloudComms : UnityEngine.Component, IBaseCloudCommunicator<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>
    33.         where teamOption : BaseTeamOption<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>
    34.         where playerOption : BasePlayerOption<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>
    35.         where scoreOption : UnityEngine.Component
    36.         where playerDisplay : UnityEngine.Component
    37.         where scoreDisplay : UnityEngine.Component
    38.         where playerAddUI : BaseAddPlayerUI<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>
    39.         where sessionSetupUI : BaseSessionSetupUI<netMatchMan, netMatchClient, netMatchClientMan, netMatchManComms, netMatchManUI, configurationData, configurationMan, scoreMan, scoreComms, scoreClient, scoreClientMan, scoreManUI, scoreMonitorUI, sessionMonitorUI, playerData, teamData, campaignData, sessionData, gameData, scoreData, cloudComms, teamOption, playerOption, scoreOption, playerDisplay, scoreDisplay, playerAddUI, sessionSetupUI>
    40.  
    41.     {
    42.         /// <summary>
    43.         /// how long did it take between the end of the last game and this one
    44.         /// </summary>
    45.         string SessionId { get; set; }
    46.         /// <summary>
    47.         /// The data
    48.         /// </summary>
    49.         campaignData CurrentCampaignData { get; set; }
    50.         gameData CurrentGameData { get; set; }
    51.  
    52.         Dictionary<string, playerData> PlayerRolls { get; set; }
    53.  
    54.         float SessionGameLength { get; set; }
    55.         /// <summary>
    56.         /// how long did it take between the end of the last game and this one
    57.         /// </summary>
    58.         float SessionHandoverLength { get; set; }
    59.         DateTime SessionStartTime { get; set; }
    60.         string SessionComputerName { get; set; }
    61.         string SessionUnityVersion { get; set; }
    62.     }
    63. }
    For our usage it allows some fantastically flexible solutions and works perfectly until the UNET weaver hits it.

    I can only assume that under the hood that it compiles down to quite a complicated (but fast) mess.

    The new Progressive Compiler is able to compile the code without the error, sadly that has its own issue with UNET (race condition with locking the Assembly-CSharp.pdb)

    https://forum.unity.com/threads/unity-incremental-c-compiler.523993/page-6#post-3588180

    I suppose the biggest annoyance is that it works perfectly up to an arbitrary point where the whole thing just dies, it means a significant amount of code can be written before you find out it might not be viable :(
     
  7. MrG

    MrG

    Joined:
    Oct 6, 2012
    Posts:
    368
    Have you considered taking your code in appropriate chunks out to separate class projects and compiling it there and pushing the DLL's into Unity? You can add extra projects to the Unity Visual Studio solution and give them a post-build macro to copy the DLL's.

    mkdir "$(SolutionDir)Assets\Libs\$(TargetName)"
    xcopy "$(TargetDir)*.dll" "$(SolutionDir)Assets\Libs\$(TargetName)" /Y
    xcopy "$(TargetDir)*.pdb" "$(SolutionDir)Assets\Libs\$(TargetName)" /Y
    xcopy "$(TargetDir)*.xml" "$(SolutionDir)Assets\Libs\$(TargetName)" /Y


    "Libs" can be any folder name you want.
     
    Last edited: Aug 7, 2018
  8. ThomasLightweave

    ThomasLightweave

    Joined:
    Sep 30, 2016
    Posts:
    26
    Ohh, no I hadn't thought of that, with the submodule pattern I'm using it wouldn't be that horrible to manage. Now I will need to work out how to rip part of this code out.
     
  9. MrG

    MrG

    Joined:
    Oct 6, 2012
    Posts:
    368
    With Visual Studio open with your Unity Solution, create a class project and reference the Unity DLL's from your install directory (get path from Unity project references). Mark those as Copy Local = FALSE.

    Then you can just select and copy the .CS script files in your Assets/* folder(s) and paste the files into the new project intact....you don't have to create new files and paste the code individually.

    The big fat downside is that if you've done drag-drop inspector referencing, you MUST change them to the DLL references before you take the original scripts out of your Unity project. Otherwise you'll have a broken mess.

    Backup everything first or use version control (preferred).
     
  10. ThomasLightweave

    ThomasLightweave

    Joined:
    Sep 30, 2016
    Posts:
    26
    Thanks mate, and don't worry about backups, this is a multi project git submodule, it is so dang backed up it is not funny.

    Though currently the source control is more of a written evidence of my descent into madness.
     
    MrG likes this.
  11. ThomasLightweave

    ThomasLightweave

    Joined:
    Sep 30, 2016
    Posts:
    26
    Oh well, no-dice once unity imports the DLL it just sits trying to run the AssemblyUpdater forever. (Even if the visual studio project works). Either way I'm about 2 hours from the deadline to fix the problem properly, at which point code quality goes out the window and I'm doing a gigantic spaghett-coded monstrosity to get the functionality across the line.
     
  12. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Are you possibly running out of memory when weaving?
    It all starts here:
    Mono.Cecil.PE.ByteBuffer.ReadByte

    The ByteBuffer is used by the Mono classes internally, we don't create that in the weaver.
    There is no reason why this should run out of memory unless they are doing something wrong or your computer is out of memory.

    Maybe show the stack trace to the Mono developers, either they will fix the bug or let you know how to work around it.
     
  13. MrG

    MrG

    Joined:
    Oct 6, 2012
    Posts:
    368
    By chance did you try importing the DLL with and without the PDB and XML files?

    Also did you try putting the DLL in a top-level Plugins folder?
     
    Last edited: Aug 8, 2018
    mischa2k likes this.
  14. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Quick update: fixed the Discord invite link on the first page, sorry about that.
     
    HeadClot88 likes this.
  15. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
  16. Katori

    Katori

    Joined:
    Nov 30, 2009
    Posts:
    60
    So I can assume that HLAPI CE or some form of it will eventually support Telepathy? Thanks for all the great work you do!
     
    LostPanda likes this.
  17. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    767
    That is the main goal of Telepathy.
     
    mischa2k likes this.
  18. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    We are almost done, too. Days(or hours) away from release.
     
    LostPanda, HeadClot88 and goldbug like this.
  19. Zante

    Zante

    Joined:
    Mar 29, 2008
    Posts:
    429
    Any thoughts on whether the community edition will ever move towards supporting Steam integration? Finding information on this subject (UNET and Steam) is like trying to bleed a stone.

    Edit: bonus question - will your Telepathy solution, in combination with the CE HLAPI, be able to stand on its own after UNET is fully deprecated?

    I'm on the verge of adopting the method linked below:
    https://blog.spacewavesoftware.com/gamedev/2017-10-28-unity-unet-hlapi-and-steam-p2p-networking/
     
    Last edited: Aug 22, 2018
  20. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Never tried steam networking. Currently making the HLAPI transport backend configurable though, so you can use Telepathy / LLAPI / whatever you want.

    And yes, everything we do right now is to break free of UNET so we aren't affected when they deprecate it. We are almost done. Only need to get project drop-in work (so HLAPI can be put into your project folder instead of replacing DLLs).
     
  21. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Update: Telepathy version released!

    Download:
    We fixed an endless amount of UNET bugs, for free. If you use HLAPI_CE, please donate.

    HLAPI CE Agnostic version: Download for Unity 2017.4 LTS (recommended)
    • The Agnostic version is based on the improvements version, so it comes with all the fixes and stability improvements
    • The Agnostic version allows for different low level networking backends
    • It uses the Telepathy library (TCP) as default backend for maximum reliability. Telepathy can deal with MMO scale networking.
    • It still uses UNET's LLAPI for WebGL, because we wanted to support WebGL until Telepathy can handle it too.
    • You can still use UNET's LLAPI by setting Transport.layer = new LLAPITransportLayer(); during initialization.
    • The agnostic version will allow us to fully break free from UNET. This is the currently recommended version for HLAPI_CE. It works very well.
    • Using Telepathy as a backend makes the networking and the game faster. In a recent test on an old laptop, uMMORPG runs at 16 FPS with LLAPI and 36 FPS with Telepathy.
    • IMPORTANT: the agnostic version doesn't use channels anymore. You will have to remove channels in your project's code, for example [Command(channel=ChannelsDefaultReliable)] needs to be changed to [Command].
    HLAPI CE Improvements version: Download for Unity 2017.4 LTS
    • The improvements version has a lot of bug fixes and stability improvements for the original HLAPI. It still uses the same architecture and the same low level networking (UDP).

    HLAPI CE Fixes
    version: Download for Unity 2018.1
    • This is the original HLAPI with a few important bug fixes.
    • We recommend to stay on Unity 2017.4 LTS and use the 2017.4 HLAPI_CE versions instead. The 2018.1 version is just a courtesy because people deserve UNET bug fixes.

    Use at your own risk! In case of concerns, feel free to inspect the .DLL files with ILSpy!
     
    Last edited: Aug 24, 2018
  22. JDB-Artist

    JDB-Artist

    Joined:
    Dec 5, 2012
    Posts:
    41
    Hahaha I was waiting for this! Thank you @vis2k I will give the agnostic version a spin on Unity 2018.2
     
    mischa2k likes this.
  23. LostPanda

    LostPanda

    Joined:
    Apr 5, 2013
    Posts:
    173
    mischa2k likes this.
  24. Spartikus3

    Spartikus3

    Joined:
    Dec 27, 2013
    Posts:
    108
    Another amazing leap forward for the network/comms layer of uMMO and indie MMO development. A big thanks to vis and team for all of this network layer work. Anyone who has dabled in the multiplayer indie game world for any length of time should know how critical and complex this stuff is. Big thanks to you all.
     
    mischa2k likes this.
  25. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Thanks guys.
     
  26. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Progress: tested HLAPI_CE + Telepathy version in uMMORPG. Here is a screenshot of 195 CCU worst case scenario where every player broadcasts to every other player. We stopped after 207 CCU. Details can be found here.
     

    Attached Files:

    Joe-Censored and LostPanda like this.
  27. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    1,124
    I have two questions
    First of all I downloaded the version linked in GitHub for 2018.1 and installed it in my 2018.1.8 and it gives me a lot of compile errors and doesn't work.

    Secondly the reason that I'm trying HLAPI pro is that uNet bare-bones version cannot do a good job for me for an unkown reason. when I try to interpolate linearly between snapshots of other clients even with 500ms it is still jittery. I'm not sure if packets come late or there is some other issue. Does HLAPA Pro/CE fixes anything which might indirectly cause this to get fixed?

    Note that I'm a networking developer and implemented this several times using uLink, websockets and ENet before

    Many thanks.
     
  28. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Probably best if you show us the compile errors then.
    The whole dll-replacement installation stuff is a bit annoying and we know that. We are about to change it so you just drop it into your project, probably from the asset store. This will probably happen in the next 1-30 days.

    HLAPI CE fixes a LOT of Unet stuff. I recommend the 2017.4 unity + hlapi_ce version though. HLAPI 2018.1 has only a few critical fixes because we mostly care about LTS right now.

    If you want to see just how good HLAPI_CE works now, check out this week's uMMORPG stress test: https://docs.google.com/document/d/...JzrrBB5vxDdGfl-HhYZW3g5lLW/pub#h.h4wha2mpetsc . We were able to run 200 players with 0 packet loss, 0 disconnects, etc. With default HLAPI we receive errors after 50-70 players.

    Oh, and we also get double the frames per second with hlapi_ce. So that's something..
     
  29. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    News: we did another stress test today, this time with uSurvival!
    Our goal was 100 CCU, because that's what DayZ and Fortnite can handle on a big map.
    We tested 100 CCU worst case scenario on a small map, everyone broadcasting to everyone else.

    Looks like we made the right decisions in regards to HLAPI_CE + Telepathy. We stopped the test at 122 CCU because it got boring. 0 packet loss. 0 disconnects. 0 errors.

    It looks like HLAPI_CE is the most powerful networking solution for Unity right now. Projects can implement networking with the least amount of code, and it can handle large amounts of players without any issues, time and time again.

    Detailed screenshot with CPU + RAM + Bandwidth:
    122 far_ip_removed.png

    Video:
     
    Last edited: Aug 27, 2018
    markoal, LostPanda and goldbug like this.
  30. markoal

    markoal

    Joined:
    Aug 31, 2015
    Posts:
    30
    I have a question about Telepathy. You mention mostly MMO games, but what about others that mostly use UDP.
    I'm building a simple fast-paced game with physics where a server sends position/rotation messages over UDP and client interpolate (late and unordered packages are ignored), everything else is sent over TCP (pickup spawn, game states).
    Would game like that would benefit from Telepathy?
     
  31. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    I recommend using TCP for everything.

    We tested HLAPI CE + Telepathy for uSurvival yesterday, as you can see in the above video. It works perfectly fine, and it's fast paced too.
     
    markoal likes this.
  32. blacksun666

    blacksun666

    Joined:
    Dec 17, 2015
    Posts:
    214
    Would love to see the tests repeated with some packet loss. TCP is generally crap compared to UDP when lost packets are involved (taking about the impact on latency not bandwidth).
     
  33. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    News: we finished the drop-in feature, which required a new namespace. So HLAPI_CE is now called Mirror (please click the link and read the page) and we are now independent from UNET.

    mirror_icon_500x128.png

    Together with @goldbug we figured out a way to make this a simple drop-in solution, so there are no more DLL replacements necessary.

    Mirror will be on the Asset Store soon, installation will be as easy as downloading the asset.

    Instead of using UnityEngine.Networking; use using Mirror;
    [Migration Guide]

    There will be no more backwards compatibility because Unity officialy abandoned UNET.

    This is a huge step for all of our multiplayer game projects. There is nothing holding us back anymore.

    I fully switched uMMORPG over to Mirror, so this will be tested by thousands of people from now on.

    We have huge plans for the future. Current priority is Stability > Usability > Features.
    • Stability: there are a few more UNET bugs that we still want to fix, and couldn't before because of backwards compatibility.
    • Usability:
      • There is no reason to have [Server] and [ServerCallback].
      • There is no reason to pass connectionToClient to [TargetRpc]s.
      • There is no more reason for a packet size limit. If people want to send gigabytes of data, let them do it.
      • The current error messages suck. Users should see detailed reasons and solutions.
    • Features:
      • There are several long overdue features like [SyncToOwner].
     
    Last edited: Aug 28, 2018
    HeadHunter2009 and goldbug like this.
  34. Stamos

    Stamos

    Joined:
    Aug 25, 2014
    Posts:
    2
    This is a very exciting update! I do have a question though, when you mention "MMO-scale" does this make it inappropriate to use for other games like first person shooters? I wanted to try a server-authoritative FPS set-up, using UDP for most things, but this update makes me feel like TCP seems to be more worked on.
     
    mischa2k likes this.
  35. FlyAnvil

    FlyAnvil

    Joined:
    Aug 14, 2013
    Posts:
    9
    Please, explain in more detail what needs to be done?

    There is folders Editor, Runtime, Runtime-Editor and Telepathy.dll in the archive. What of this drop to Plugins folder?
    How tell Unity to Exclude and only include?
    Thanks
     
  36. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    767
    See the uSurvival test. That is a fast paced action game using TCP.


    That said, if you still prefer UDP, Mirror does support providing your own transport, you can replace Telepathy with any transport you want including UDP based ones. Here is a list of several transports for unity:
    https://github.com/nxrighthere/BenchmarkNet/wiki/Benchmark-Results

    You could pick anyone of them and make them work with Mirror with about 100 LOC or less. I would expect the community to come up with these adapters
     
    Last edited: Aug 29, 2018
    nirvanajie likes this.
  37. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Hey guys, here is the step by step upgrade video that I just released for uMMORPG. It will be the same workflow in all projects:
     
  38. Pineapple37

    Pineapple37

    Joined:
    Aug 10, 2018
    Posts:
    1
    Hey vis and paul, thanks for doing all of this work for everyone! You guys saved my game from being abandoned when I hit the deSerializing bug.


    I don't have very much experience in programming, and much less in c#, but I think there's a typo in the migration guide.
    The guide reads:

    Replace
    Unity.Networking
    for
    Mirror
    everywhere in your project

    but I think it's supposed to be

    Replace
    UnityEngine.Networking
    for
    Mirror
    everywhere in your project

    I might be wrong, but I couldn't find the first one anywhere.
     
    goldbug and mischa2k like this.
  39. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    767
    Thank you. Fixed.
     
  40. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    1,124
    Thanks for responding. My issue was due to a bug in our code and fixed with uNet out of the box. So I did not bother to retry using HLAPI CE. Honestly without any release notes it is a set of unknown fixes and also the fact that you are selling here that TCP can work for a fast paced game like fortnite in a real world setting is a turn off.

    This is simply not true. An old MMO like WOW uses TCP because those days bandwidth were different, update rates were different and … Not that it is impossible to make any game which is fast on TCP. I myself made a FPS coop unet game work on websockets for chrome books but latency and update rates are much different
     
    pesapower likes this.
  41. franMx

    franMx

    Joined:
    May 27, 2013
    Posts:
    30
    Hi, are there any plans to include a lobby (like unity's) ?
     
    LostPanda likes this.
  42. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    You can use any backend that you like. By default it's TCP. You can also use built in LLAPI (UDP) via Mirror.Transport.layer = new LLAPITransportLayer();
     
    pesapower likes this.
  43. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Unity's lobby was full of bugs. I used that in uMOBA originally, but I wouldn't recommend it at all.
    We probably won't include a lobby because that seems better suited for you guys to make for your own projects.
    There is no way to make a lobby that fits all projects anyway. Some want teams, some want matchmaking, etc.

    If you desperately want a basic lobby then take a look at uMOBA.
     
  44. Kobaltic1

    Kobaltic1

    Joined:
    Jan 22, 2015
    Posts:
    183
    How are the relay servers now being handled?
     
  45. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    We removed the relay feature because relaying sucks.
    Unity doesn't seem to support their relay service anyway, and anyone who ever played a game hosted on another player's computer will confirm that :)
     
  46. franMx

    franMx

    Joined:
    May 27, 2013
    Posts:
    30
    Thanks Vis2k
     
  47. Kobaltic1

    Kobaltic1

    Joined:
    Jan 22, 2015
    Posts:
    183
    So if we use mirror it is peer to peer? Are there any costs involved?
     
  48. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Peer to peer is not very smart for multiplayer games, you can not protect against cheats then.
    Mirror is free to use yes.
     
  49. sirwhatevers

    sirwhatevers

    Joined:
    Aug 25, 2017
    Posts:
    33
    Since you've removed channels, what would be the recommended way to send unreliable messages via Mirror if I were to write an adapter for LiteNetLib, for example? Same for the other methods of sending:
    • Reliable with order
    • Reliable without order
    • Ordered but unreliable with duplication prevention
    • Simple UDP packets without order and reliability
     
  50. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    Thank you! If you are working on an MMO or a slow paced or non-competitive game, fine, but to try and sell me on making a fast paced game with TCP when it literally flies in the face of what all modern fast paced shooters do is baffling and concerning to me. No multiplayer competitive shooter uses TCP, with good reason.