Jump to content

Debugging .Net Server API Mods


Recommended Posts

Hey Moddaaars!


I figured out how to make real live debugging of mods in Unity 5.3 games (like 7DTD) possible.




/** Credit: This wouldn't have been possible without the work of olizit, who wrote the original tutorial and custom mono.dll for RimWorld, and who also was helpful via email. Thank you! **/


Installation with Visual Studio 2017


  1. Install 7DTD Dedicated Server locally on Windows.
    (Debugging should also work remotely, but you have to hassle with ports, ip's, firewalls, etc. You can figure this out later yourself.)
  2. Install Visual Studio 2017 with the "Game development with Unity" workload
  3. Replace the game's <7dtdt server directory>\7DaysToDieServer_Data\Mono\mono.dll with this modified mono.dll:


  4. Set this environment variable with this command in a batch file.
    set MONO_MOD_DEBUG=--debugger-agent=transport=dt_socket,address=,server=y,defer=y

    You can put it in your startdedicated.bat file or define the variable globally in Start -> System -> Advanced System Settings -> Tab Advanced -> Environment Variables. See this tutorial for details. You need to restart VS and the 7DTD server to apply the changes!

  5. Copy your mod and all dependencies in Mods folder.
  6. Open mod solution file with Visual Studio
  7. You need to create a Mono debug symbol file (.mdb), because the normal .Net debug symbol file (.pdb) doesn't work for Mono. You can use the pdb2mdb tool:
    Add this pdb2mdb NuGet package to your project. Alternatively, you can download and install Mono, which has the tool in <Mono_install_path>\bin\pdb2mdb.bat.
    Set your project to build in debug mode. Debug info must be enabled (default).
    Option A - Use post build event:
    Open Project settings and add this post build event:
    ..\packages\Mono.pdb2mdb.\tools\pdb2mdb.exe "$(TargetPath)"

    Adjust the tool path accordingly if you are using the full Mono installation.
    Option B - Use MSBuild scripting:
    If you know a bit about MSBuild scripting, you can embed the pdb2mdb tool in your build script (.csproj). This is what I have added:

      <!-- Create Mono CLR symbol files (.mdb) -->
     <Target Name="GenerateMonoSymbols" AfterTargets="AfterBuild" Condition=" Exists('$(OutputPath)\$(AssemblyName).pdb') ">
       <Message Text="$(ProjectName) -> $(TargetPath).mdb" Importance="High" />
       <Exec Command="$(MonoMdbGenerator) $(TargetPath)" WorkingDirectory="$(MSBuildProjectDirectory)\$(OutputPath)" />

    This step converts the .pdb file to a .mdb file. After a sucessfull build your mod assemblies must contains 3 files <name mod>.dll <name mod>.dll.mdb and <name mod>.pdb. Check if these 3 files are there!

  8. Start up the 7DTD server normally on your local machine (where VS is installed).
  9. In Visual Studio click on Debug->Attach Unity Debugger->Input IP
    Enter parameters matching your local address and port as set in the environment variable.
    Click OK
  10. Set some breakpoints and execute mod functionality in game.
  11. Profit!


Installation with Visual Studio 2015


I haven't tested this, but reportedly it works as well, but you need the VS2015 Tools for Unity extension. See original tutorial for details.



Installation with Xamarin Studio (all platforms)


It should be possible to get debugging going on non-Windows platforms or without Visual Studio, although maybe not as comfortably. Check out the original tutorial about how to install and run Xamarin Studio.





  • Test if your environment variable is set:
    Enter "set" on a command line. One of the variables should be MONO_MOD_DEBUG.
  • Execute on command prompt to test if the game is listening for a debugger on port 56000:
    netstat -n -a | find "56000"

    It should print a line with TCP, the ip, port and LISTENING status. Otherwise the game is not ready for debugging. Check the mono.dll and environment variable again.

  • Is the port free? If the above command returns a LISTENING port before you started the game, some other program may be using the port. Try to change to use a different port.
  • Test connection to the game debugger (only if netstat test worked):
    telnet 56000

    If screen clears, the connection is ready. Try Visual Studio now.
    If "connection timed out" or some other error appears, the game is not listening on that port for a debug session. Check if you mono.dll is replaced and the environment variable is set. If you don't have the telnet command, see: https://technet.microsoft.com/en-us/library/cc771275(v=ws.10).aspx

  • Check your firewall settings if anything prevents connecting to the ip/port!
  • The game doesn't start or crashes with the modified mono.dll?
    The modified dll is only for Unity 5.3 and only tested with 7 Days to Die version A16.1. Other games may or may not work. If your game doesn't work, there is not much you can do, unless you want to get into modifying and compiling mono.dll yourself.
  • Debugging server startup code
    You can debug you Api constructor or Api.GameAwake calls when you omit the ,defer=y from the Mono environment string. Then the server will upon start immediately go into pause mode and wait for your debugger to connect. You then *must* attach the debugger so that the server continues to start.


Let me know whether you made it work or if you hit any problems. I'll update the troubleshooting section for common problems.


.oO( djkrose )Oo.

Link to comment
Share on other sites

Here are some additional options to use in the --debugger-agent parameter:


Usage: --debugger-agent=[<option>=<value>,...] ...    

Available options:
 transport=<transport>        Transport to use for connecting to the debugger (mandatory, possible values: 'dt_socket')    
 address=<hostname>:<port>    Address to connect to (mandatory)    
 server=<y|n>                 Mandatory for being the debug target
 loglevel=<i>                 Log level (defaults to 0)    
 logfile=<file>               File to log to (defaults to stdout)    
 suspend=<y|n>                Whether to suspend after startup.    
 timeout=<i>                  Timeout for connecting in milliseconds.    
 defer=<y|n>                  Whether to allow deferred client attaching.    
 onuncaught=<y|n>             Break on uncaught exception
 onthrow=<y|n>                Break on thrown exception


Most importantly, defer=y makes the game start with or without a debugger attached, and you can always attach a debugger later. Even if you don't, it has the benefit that your log file contains nice stack traces with exact source file and line number.


I don't recommend to set that on production servers, but theoretically you could. -- And since I'm a badass, I have set this on my 16 slot production server. ¯\_(ツ)_/¯

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...

I think i could use some help.


I set everything up succesfully. But when i attach unity debugger to dedi the outputlog shows loading a bunch of gameassemblies and then gets spammed with a thread exited code 0.


Have seen this b4? Im using visial studio 2015 with latest Unitytools. Is 16.3 still using same mono.dll version?


Game is just running fine, but no breakpoint gets caught. I think due to the treadexit.


Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\Mono.Posix.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\Mono.Security.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\System.Configuration.dll

Loaded: Module: C:\Servers\7n2l_16.3\Mods\mod7n2lite\mod7n2l_lite.dll

Loaded: Module: C:\Servers\7n2l_16.3\Mods\Allocs_WebAndMapRendering\MapRendering.dll

Loaded: Module: C:\Servers\7n2l_16.3\Mods\Allocs_CommonFunc\7dtd-server-fixes.dll

Loaded: Module: C:\Servers\7n2l_16.3\Mods\Allocs_CommandExtensions\AllocsCommands.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\Boo.Lang.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\UnityScript.Lang.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\System.Xml.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\System.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\System.Core.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\LitJson.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\System.Windows.Forms.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\System.Drawing.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\EasyAntiCheat.Server.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\EasyAntiCheat.Client.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\CodeProfilerRuntime.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\NCalc.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\enum2int.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\NSpeex.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\LogLibrary.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\libnoise.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\ICSharpCode.SharpZipLib.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\AmplifyMotion.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\UnityEngine.Networking.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\UnityEngine.UI.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\Assembly-UnityScript.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\Assembly-UnityScript-firstpass.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\Assembly-CSharp.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\Assembly-CSharp-firstpass.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\UnityEngine.dll

Loaded: Module: C:\Servers\7n2l_16.3\7DaysToDieServer_Data\Managed\mscorlib.dll

The thread 0x5dfbce60 has exited with code 0 (0x0).

The thread 0x5dfbccf0 has exited with code 0 (0x0).

The thread 0x5dfbcb80 has exited with code 0 (0x0).

The thread 0x5dfbca10 has exited with code 0 (0x0).

etc etc




-edit- owkey. the spam i was able to stop. I had a seperate thread running within the mod and when i didnt let it start, attaching the unity debugger now loads up the game dll's and shows in output log pane. But as soon as i use the mod in any way (do a command for example) it still does not break and only 1 entry of "The thread exited...." shows up.


Any ideas where i should be looking for a solution?


-edit2- installing vs2017 Enterprise now. Maybe its a vs version thingy.


-edit3- nope vs2017 same behaviour

Link to comment
Share on other sites

I think i could use some help.


I set everything up succesfully. But when i attach unity debugger to dedi the outputlog shows loading a bunch of gameassemblies and then gets spammed with a thread exited code 0.


Have seen this b4? Im using visial studio 2015 with latest Unitytools. Is 16.3 still using same mono.dll version?


Game is just running fine, but no breakpoint gets caught. I think due to the treadexit.



I haven't seen this problem before, but from what you are describing you did everything correct. I'm using A16.2, but I think A16.3 should also work. Try 16.2 just to be sure...


When your VS output shows the loaded assemblies, that means it could already connect to the debugger, so that's good. Just to confirm, VS switches over to the Debug view and you see the [pause] and [stop] toolbar icons?


If that's all working, you probably don't have the .pdb and .dll.mdb files generated and put next to the .dll file in the Mods folder. Have you done that?



Link to comment
Share on other sites

  • 3 months later...
  • 1 year later...
  • 3 months later...


This topic is now archived and is closed to further replies.

  • Create New...