[1.2+] Hosting Dedicated Servers on Linux

Users who are viewing this thread

Hey there! Few people asked so I figured I'd post a quick guide on setting up a dedicated Bannerlord server on Linux using the native Linux files rather than using wine and the Windows files. Mind you, this will not go deep into how to configure your server - for that, I would suggest looking at other guides like the one by Horns.

While the native files have been available for a bit now, they were previously targeting .NET Core 3.1, which has been out of support for a bit so getting things set up was a bit of a pain. Now, the required version is .NET 6, making things fairly easy. So, here's a step-by-step:

  1. Obtain the Bannerlord Server Files. You have two options:
    1. Since the tools include Windows and Linux files, you can simply download them on your PC, then upload them manually to your server (if you have one). Open Steam, go to your Library, set your filter to include "Tools" (or search for "Mount & Blade II: Dedicated Server"). Once downloaded, upload to your server in any way you want.
    2. Using steamcmd. Install steamcmd as described in the previous command, then run the following command:
      Bash:
      steamcmd +force_install_dir /path/you/want/files/at +login anonymous +app_update 1863440 +exit
    3. For updating, repeat the same process. Either manually upload or re-run the command above.
  2. Install the .NET 6 ASP.NET Core Runtime. You can find instructions on how to do so on Microsofts official page - here is a link for Debian, you can find other distributions in the navigation on the left hand side of the page.
    1. The example commands given on the page are usually for the latest version - i.e. .NET 8 as of writing this. Make sure you install .NET 6 by replacing 8 with 6 in the given commands.
  3. This part may not be required in the future, but for now it seems it is. Running the server now, you will probably see warnings for a lot of missing .dll files. Those come bundled with your .NET 6 installation, but for some reason the server files do not use them. Thankfully, there is a very simple fix for this: Just copy them over.
    1. To find the files on your system, run dotnet --info. Check the output for ".NET runtimes installed:". Find the path for Microsoft.AspNetCore.App 6.0.X (x being your exact version number, may differ depending on install time). The files you need are located at that path, plus your current version number. For me, that is currently /usr/share/dotnet/shared/Microsoft.AspNetCore.App/6.0.25/.
    2. Now, simply copy over all .dll files from that folder into /BLSERVER/bin/Linux64_Shipping_Server/.
      1. Realistically, you probably do not need *all* of them. You could start your server, see the error messages and only copy over what its complaining about - I did that on the Beta branch, gave up at around 30 files. Easier this way.
  4. Now, navigate to /BLSERVER/bin/Linux64_Shipping_Server/ and start your server using the following command:
    Bash:
    dotnet TaleWorlds.Starter.DotNetCore.Linux.dll _MODULES_*Native*Multiplayer*_MODULES_ /dedicatedcustomserverconfigfile CONFIG.txt /tickrate 240 /dedicatedcustomserverauthtoken YOURTOKENHERE /dedicatedcustomserver 7210 USER 0 /playerhosteddedicatedserver
    1. You may want to add your own Modules to the module list.
    2. Replace COFIG.txt with the name of your own config file, located in /BLSERVER/Modules/Native/.
    3. /tickrate is a new option as of 1.2. The previous, default tickrate was 60, but you may now up it to up to 240. A higher tickrate means more updates per second for the clients connected to your server, but may also increase resource usage. I would suggest playing around with this a bit and seeing what works for you and your setup.
    4. Replace YOURTOKENHERE with your auth token (as for how to obtain it, see Horns' guide I linked above). I have not yet looked into where to place the file containing the token on Linux systems, so for now its only as a parameter - let me know if you figure it out so I can list it here :smile:
    5. 7210 is the default port used by the server. Especially if you run multiple servers from the same machine, you may want to replace it with your own. Just make sure your firewall is opened for UDP and, if you want to use the webpanel and/or mapdownloader, for TCP, on that port.
    6. The rest of the options should remain as provided, unless you're sure about what you're doing.

Some troubleshooting:
  • My server starts up correctly, I can see it in the server list and I can access the webpanel, but I can not join or open the map download panel. The error I get when trying to open the map download panel shows an IP that is not mine, i.e. 0.0.0.1.
    • Edit this file: BLSERVER/bin/Linux64_Shipping_Server/TaleWorlds.Starter.DotNetCore.Linux.runtimeconfig.json. Add "System.Net.DisableIPv6": true, to the configProperties object. The full file may now look like the code in the spoiler below.
      JSON:
      {
        "runtimeOptions": {
          "tfm": "net6.0",
          "framework": {
            "name": "Microsoft.NETCore.App",
            "version": "6.0.0"
          },
          "configProperties": {
            "System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
            "System.Net.DisableIPv6": true
          }
        }
      }
    • This stops the server from using IPv6, which seems to cause such issues. You could also disable IPv6 via the global dotnet config or in your operating system, but this is probably the easiest way to do it and it only has an effect on the bannerlord server, not any other applications.
    • This may also solve the same issue on windows servers.

Aaaand... that's about it for this guide. Not usually writing guides like this one, so if you have any questions or suggestions for improvements, please let me know :smile:
 
Last edited:
Awesome, thanks for the tutorial, works so far.
One important thing to notice though is that for some reason IPv6 got bugged beyond repair in one of the previous updates.
You need to deactivate IPv6 or you are greeted with timeouts if you try to join, imho quite a dealbreaker and it makes things more complicated (like to run it via docker with IPv6 disabled).
 
Awesome, thanks for the tutorial, works so far.
One important thing to notice though is that for some reason IPv6 got bugged beyond repair in one of the previous updates.
You need to deactivate IPv6 or you are greeted with timeouts if you try to join, imho quite a dealbreaker and it makes things more complicated (like to run it via docker with IPv6 disabled).
I've run into issues with that as well, yes. Still looking for an elegant solution. I know TaleWorlds can manually fix it on their end as one of the devs was kind enough to do it for me once, but that only lasts until you restart the server.

@Dejan Could you guys look into this? It seems servers with IPv6 enabled can't be connected to. I've heard of Windows hosts easily disabling the adapter for it, but I'm not sure it's quite as easy to do on Linux, so it's a bigger hurdle. To be clear - the server in question does show up in the server list, you can access the admin panel but you can not join the server ingame or download maps from it. In my case, the IP shows as 0.0.0.1:7210 (when opening, or rather failing to open, the map download panel) which is obviously not correct.
Happy to help testing with my server if need be.
 
Oh, quick double post, think I actually found a simple solution. @Nettelbeck, can you try this and confirm if it works for you as well?

Simply edit TaleWorlds.Starter.DotNetCore.Linux.runtimeconfig.json, then add "System.Net.DisableIPv6": true, to the configProperties object inside of it. Whole file is basically this for me now:

JSON:
{
  "runtimeOptions": {
    "tfm": "net6.0",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "6.0.0"
    },
    "configProperties": {
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
      "System.Net.DisableIPv6": true
    }
  }
}

Please let me know if this works for you as well, so I can add it to the OP. Dejan - maybe you guys can add this as default? Can see this even working on Windows tbh.
 
Oh, quick double post, think I actually found a simple solution. @Nettelbeck, can you try this and confirm if it works for you as well?

Simply edit TaleWorlds.Starter.DotNetCore.Linux.runtimeconfig.json, then add "System.Net.DisableIPv6": true, to the configProperties object inside of it. Whole file is basically this for me now:

JSON:
{
  "runtimeOptions": {
    "tfm": "net6.0",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "6.0.0"
    },
    "configProperties": {
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
      "System.Net.DisableIPv6": true
    }
  }
}

Please let me know if this works for you as well, so I can add it to the OP. Dejan - maybe you guys can add this as default? Can see this even working on Windows tbh.
Adding Disable Ipv6 works on Linux, thanks a lot! I can finally use my control panel with native Linux binaries and activated IPv6 on the machine again!
 
This command returns me "Illegal instruction".

Command:

Bash:
dotnet TaleWorlds.Starter.DotNetCore.Linux.dll _MODULES_*Native*Multiplayer*_MODULES_ /dedicatedcustomserverconfigfile {my_config.txt} /tickrate 240 /dedicatedcustomserverauthtoken {token} /dedicatedcustomserver 7210 USER 0 /playerhosteddedicatedserver

Installed this:

Bash:
dotnet --list-runtimes


Microsoft.AspNetCore.App 6.0.25 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]

Microsoft.NETCore.App 6.0.25 [/usr/share/dotnet/shared/Microsoft.NETCore.App]


Any suggestions? tx
 
Last edited:
This command returns me "Illegal instruction".

Command:

Bash:
dotnet TaleWorlds.Starter.DotNetCore.Linux.dll _MODULES_*Native*Multiplayer*_MODULES_ /dedicatedcustomserverconfigfile {my_config.txt} /tickrate 240 /dedicatedcustomserverauthtoken {token} /dedicatedcustomserver 7210 USER 0 /playerhosteddedicatedserver

Installed this:

Bash:
dotnet --list-runtimes


Microsoft.AspNetCore.App 6.0.25 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]

Microsoft.NETCore.App 6.0.25 [/usr/share/dotnet/shared/Microsoft.NETCore.App]


Any suggestions? tx
Never seen that before. Is "Illegal Instruction" all it says? What distro and, if you kow, what CPU?
 
Never seen that before. Is "Illegal Instruction" all it says? What distro and, if you kow, what CPU?
Yes, no much more. Yes, it looks like an arch problem...

Bash:
journalctl:
kernel: traps: dotnet[7530] trap invalid opcode error:0 in libFairyTale.Library.so[7f9cc588e000+a0000]

Im using a Debian 12 and Intel Xeon E3-1225v2
 
Last edited:
Yes, no much more. Yes, it looks like an arch problem...

Bash:
journalctl:
kernel: traps: dotnet[7530] trap invalid opcode error:0 in libFairyTale.Library.so[7f9cc588e000+a0000]

Im using a Debian 12 and Intel Xeon E3-1225v2

Tested on Debian 11 and fails too :S
 
Tested on Debian 11 and fails too :S
Do you have any Modules besides Native and Multiplayer in your Modules folder at the moment? I've had issues with that, reported it to TW already.

Or is that really the only line it prints out? In that case I'm afraid I don't think I can help you :neutral:

When you say you tried Debian 11, I'm guessing you also re-downloaded the files for it? If you're uploading from your PC, try verifying file integrity via Steam.
 
Do you have any Modules besides Native and Multiplayer in your Modules folder at the moment? I've had issues with that, reported it to TW already.

Or is that really the only line it prints out? In that case I'm afraid I don't think I can help you :neutral:

When you say you tried Debian 11, I'm guessing you also re-downloaded the files for it? If you're uploading from your PC, try verifying file integrity via Steam.
Hello, no, it is the first installation and the server is new, I tried two OS to rule out problems with the new Debian.

Both times I tested it using option 2 (steamcmd). But I think that before I discard using a linux server, I will try to transfer the files with scp to server.

I have suspicions that these dll's don't work well with my CPU architecture or something else escapes me, the journalctl shows the kernel error. I have tried several kernels without result. I've been playing with dotnet and it works fine.

Cheers
 
Do you have any Modules besides Native and Multiplayer in your Modules folder at the moment? I've had issues with that, reported it to TW already.

Or is that really the only line it prints out? In that case I'm afraid I don't think I can help you :neutral:

When you say you tried Debian 11, I'm guessing you also re-downloaded the files for it? If you're uploading from your PC, try verifying file integrity via Steam.

Finally, It works changing CPU, drastic but effective change, thanks for the guide.

In case it helps anyone, (I'm not sure why) with Debian without a graphical interface I had problems with "librgl.so", I was able to fix it by installing the OpenGL dependencies.

Happy new year!
 
Finally, It works changing CPU, drastic but effective change, thanks for the guide.

In case it helps anyone, (I'm not sure why) with Debian without a graphical interface I had problems with "librgl.so", I was able to fix it by installing the OpenGL dependencies.

Happy new year!
So you installed the Debian 11 package called `libgl1` but did you install the 64 bit or 32 bit version (amd64 or i386?)
 
So you installed the Debian 11 package called `libgl1` but did you install the 64 bit or 32 bit version (amd64 or i386?)

Well, I'm finally using debian 12. (64bits), but you need to configure the x86 architecture as well.

It's a step when installing steamcmd:

* https://developer.valvesoftware.com/wiki/SteamCMD#Debian

Bash:
sudo dpkg --add-architecture i386

Regarding opengl dependencies, this guide helped me to launch the server: (Only step 1)

* https://dev.to/mohimamimino11/a-guide-to-set-up-opengl-projects-in-debian-2mi7
 
Last edited:
Hi, I copied all the dlls, it says they're all already there. But I get these logs, where can I setup the path ?

[10:15:43.245] Couldn't find .dll: ../../Modules/Multiplayer/bin\Win64_Shipping_Client/TaleWorlds.MountAndBlade.DedicatedCustomServer.dll

[10:15:43.245] Couldn't find .dll: ../../Modules/Multiplayer/bin\Win64_Shipping_Client/TaleWorlds.MountAndBlade.DedicatedCustomServer.Official.dll

[10:15:43.245] Couldn't find .dll: ../../Modules/Multiplayer/bin\Win64_Shipping_Client/TaleWorlds.MountAndBlade.DedicatedCustomServer.WebPanel.dll

[10:15:43.245] Couldn't find .dll: ../../Modules/Multiplayer/bin\Win64_Shipping_Client/TaleWorlds.MountAndBlade.ListedServer.MapServer.dll

[10:15:43.245] Couldn't find .dll: ../../Modules/Multiplayer/bin\Win64_Shipping_Client/TaleWorlds.MountAndBlade.DedicatedCustomServer.ClientHelper.dll
 
Hi, I copied all the dlls, it says they're all already there. But I get these logs, where can I setup the path ?

[10:15:43.245] Couldn't find .dll: ../../Modules/Multiplayer/bin\Win64_Shipping_Client/TaleWorlds.MountAndBlade.DedicatedCustomServer.dll
[10:15:43.245] Couldn't find .dll: ../../Modules/Multiplayer/bin\Win64_Shipping_Client/TaleWorlds.MountAndBlade.DedicatedCustomServer.Official.dll
[10:15:43.245] Couldn't find .dll: ../../Modules/Multiplayer/bin\Win64_Shipping_Client/TaleWorlds.MountAndBlade.DedicatedCustomServer.WebPanel.dll
[10:15:43.245] Couldn't find .dll: ../../Modules/Multiplayer/bin\Win64_Shipping_Client/TaleWorlds.MountAndBlade.ListedServer.MapServer.dll
[10:15:43.245] Couldn't find .dll: ../../Modules/Multiplayer/bin\Win64_Shipping_Client/TaleWorlds.MountAndBlade.DedicatedCustomServer.ClientHelper.dll

These dlls are from the game itself, not from the dotnet installation. I think those messages are fairly "normal". According to Cerwin (TaleWorlds), they might not even be accurate [1].

Does your server start up? If it does, and you can open the web panel, those files have definitely been found. If it does not, please share more details about how you set things up and what config and starting parameters you are using.


[1]
bSTqJ.png

Source (from modding discord): Click
 
These dlls are from the game itself, not from the dotnet installation. I think those messages are fairly "normal". According to Cerwin (TaleWorlds), they might not even be accurate [1].

Does your server start up? If it does, and you can open the web panel, those files have definitely been found. If it does not, please share more details about how you set things up and what config and starting parameters you are using.


[1]
bSTqJ.png

Source (from modding discord): Click
yes, it launched and connected, thank you for the tutorial
 
Back
Top Bottom