Compiling Barotrauma from Source
Barotrauma is a 2D co-op survival game about navigating the depths of the Jupiter's moon Europa in a submarine. With the help of other players or NPCs, you need to operate the submarine, maintain the onboard systems, repair leaks, fight the local fish, take care of the crew and stay alive. It's sold on Steam and runs on Linux. What's better, its source code is available on GitHub for modders and limited joint development. Here's a guide on how to compile Barotrauma on Linux for Linux.
While the source for the game is publicly available, its graphical and other assets are not. To get a playable game at the end, you'll need to purchase Barotrauma on Steam both for its Content
directory containing its assets and multiplayer, which depends on Steam's match-making. Compiling from source as-is won't net you a DRM-free game. If that's your goal, you'll have to figure it out yourself, something the developer warns against in their end-user license agreement.
That out of the way, let's begin.
Setup
These instructions are written for compiling Barotrauma for Linux on Arch Linux. However, I suspect they'll apply equally well to other platforms, as beyond a few package mentions, there's nothing specific to Arch Linux. You're going to need some familiarity with the command line and developer tools. Nothing you couldn't learn now.
First, ensure you've got Git installed.
pacman -S git
Then, let's clone the Barotrauma's repository from Github. To save disk space, let's do a shallow clone that skips the history and just grabs the latest state. As of May 17, 2020, that'll be ce4ccd9, which corresponds to v0.9.9.1. In total, 138.3 MiB.
git clone --depth 1 https://github.com/Regalis11/Barotrauma.git
The game's written in C# using the .NET Core framework. We'll need its SDK installed to run the build scripts and compile the game. Arch Linux has .NET Core available in its official repositories, making the installation easy. Barotrauma's README mentions .NET Core v3.0, but v3.1 seems to work fine.
pacman -S dotnet-sdk
The rest of the game's dependencies will either be installed by the .NET Core dotnet
executable or are committed to the source repository as binary files. If I were you, I'd also now prepare an unprivileged user account or some other sandboxing to run the build under. After all, you'll be running a lot of unaudited code off the Internet. One relatively convenient sandbox utility on Linux is Firejail (Firejail on Arch Wiki).
Compiling
The primary building and packaging happens via dotnet
, a build tool that came with the .NET Core SDK. To get the Barotrauma Linux client to successfully compile, though, we'll need to download a missing controller mapping file and apply a patch to skip copying already bundled dependencies.
SDL Game Controller Mappings
For some reason the build depends, but doesn't automatically download, the game controller mapping database for SDL from SDL_GameControllerDB. Let's do so ourselves.
mkdir -p Libraries/MonoGame.Framework/Src/ThirdParty/SDL_GameControllerDB
wget https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt -O Libraries/MonoGame.Framework/Src/ThirdParty/SDL_GameControllerDB/gamecontrollerdb.txt
Those that try to run the dotnet publish
command from below before downloading the controller configuration file, will encounter the following error:
CSC : error CS1566: Error reading resource 'gamecontrollerdb.txt' -- 'Could not find a part of the path '/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/SDL_GameControllerDB/gamecontrollerdb.txt'.' [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
Skipping Compiling Bundled Dependencies
As can be guessed from its use of the SDL game controller database, Barotrauma depends on SDL. It also depends on OpenAL for audio. Actually, Barotrauma depends on the MonoGame framework, which is what seems to depend on both. Nonetheless, MonoGame seems to insist on having access to SDL's and OpenAL's dynamic libraries for all three platforms — Windows, Linux and Mac — during its build. Fortunately for us, Barotrauma's developers have included compiled versions of the former in the repository. As MonoGame is still looking for them in the ThirdParty
directory, though, we'll need to patch the build project in Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj
to not do so.
Copy the diff below to a file or just download the patch directly.
diff --git a/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj b/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj
index 7ef537f..63c1b2a 100644
--- a/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj
+++ b/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj
@@ -511,64 +511,6 @@
</Compile>
</ItemGroup>
- <ItemGroup>
- <None Include="..\ThirdParty\Dependencies\MonoGame.Framework.dll.config">
- <Platforms>WindowsGL,Linux,MacOS</Platforms>
- <Link>MonoGame.Framework.dll.config</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="..\ThirdParty\Dependencies\SDL\Windows\x86\SDL2.dll">
- <Platforms>WindowsGL,Linux</Platforms>
- <Link>x86\SDL2.dll</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="..\ThirdParty\Dependencies\SDL\Windows\x64\SDL2.dll">
- <Platforms>WindowsGL,Linux</Platforms>
- <Link>x64\SDL2.dll</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="..\ThirdParty\Dependencies\openal-soft\Windows\x86\soft_oal.dll">
- <Platforms>WindowsGL,Linux</Platforms>
- <Link>x86\soft_oal.dll</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="..\ThirdParty\Dependencies\openal-soft\Windows\x64\soft_oal.dll">
- <Platforms>WindowsGL,Linux</Platforms>
- <Link>x64\soft_oal.dll</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="..\ThirdParty\Dependencies\SDL\Linux\x86\libSDL2-2.0.so.0">
- <Platforms>WindowsGL,Linux</Platforms>
- <Link>x86\libSDL2-2.0.so.0</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="..\ThirdParty\Dependencies\SDL\Linux\x64\libSDL2-2.0.so.0">
- <Platforms>WindowsGL,Linux</Platforms>
- <Link>x64\libSDL2-2.0.so.0</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="..\ThirdParty\Dependencies\openal-soft\Linux\x86\libopenal.so.1">
- <Platforms>WindowsGL,Linux</Platforms>
- <Link>x86\libopenal.so.1</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="..\ThirdParty\Dependencies\openal-soft\Linux\x64\libopenal.so.1">
- <Platforms>WindowsGL,Linux</Platforms>
- <Link>x64\libopenal.so.1</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="..\ThirdParty\Dependencies\SDL\MacOS\Universal\libSDL2-2.0.0.dylib">
- <Platforms>WindowsGL,Linux,MacOS</Platforms>
- <Link>libSDL2-2.0.0.dylib</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="..\ThirdParty\Dependencies\openal-soft\MacOS\Universal\libopenal.1.dylib">
- <Platforms>WindowsGL,Linux,MacOS</Platforms>
- <Link>libopenal.1.dylib</Link>
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- </ItemGroup>
-
<ItemGroup>
<EmbeddedResource Include="MonoGame.bmp">
<LogicalName>MonoGame.bmp</LogicalName>
Then navigate to the source directory and pass the patch to the patch
executable. In case you're missing patch
, install it via Pacman (pacman -S patch
).
patch -p1 < monogame-ce4ccd9.patch
You could verify the patch applied correctly by checking Git.
$ git status --short
M Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj
Skipping patching the MonoGame build project before attempting to build Barotrauma results in the following errors referencing DLLs from Windows, Linux and Mac, even if you're building only for a Linux system.
Barotrauma's MonoGame compile errors
/usr/share/dotnet/sdk/3.1.103/Microsoft.Common.CurrentVersion.targets(4570,5): error MSB3030: Could not copy the file "/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/Dependencies/MonoGame.Framework.dll.config" because it was not found. [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
/usr/share/dotnet/sdk/3.1.103/Microsoft.Common.CurrentVersion.targets(4570,5): error MSB3030: Could not copy the file "/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/Dependencies/SDL/Linux/x64/libSDL2-2.0.so.0" because it was not found. [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
/usr/share/dotnet/sdk/3.1.103/Microsoft.Common.CurrentVersion.targets(4570,5): error MSB3030: Could not copy the file "/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/Dependencies/SDL/Linux/x86/libSDL2-2.0.so.0" because it was not found. [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
/usr/share/dotnet/sdk/3.1.103/Microsoft.Common.CurrentVersion.targets(4570,5): error MSB3030: Could not copy the file "/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/Dependencies/SDL/MacOS/Universal/libSDL2-2.0.0.dylib" because it was not found. [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
/usr/share/dotnet/sdk/3.1.103/Microsoft.Common.CurrentVersion.targets(4570,5): error MSB3030: Could not copy the file "/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/Dependencies/SDL/Windows/x64/SDL2.dll" because it was not found. [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
/usr/share/dotnet/sdk/3.1.103/Microsoft.Common.CurrentVersion.targets(4570,5): error MSB3030: Could not copy the file "/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/Dependencies/SDL/Windows/x86/SDL2.dll" because it was not found. [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
/usr/share/dotnet/sdk/3.1.103/Microsoft.Common.CurrentVersion.targets(4570,5): error MSB3030: Could not copy the file "/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/Dependencies/openal-soft/Linux/x64/libopenal.so.1" because it was not found. [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
/usr/share/dotnet/sdk/3.1.103/Microsoft.Common.CurrentVersion.targets(4570,5): error MSB3030: Could not copy the file "/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/Dependencies/openal-soft/Linux/x86/libopenal.so.1" because it was not found. [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
/usr/share/dotnet/sdk/3.1.103/Microsoft.Common.CurrentVersion.targets(4570,5): error MSB3030: Could not copy the file "/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/Dependencies/openal-soft/MacOS/Universal/libopenal.1.dylib" because it was not found. [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
/usr/share/dotnet/sdk/3.1.103/Microsoft.Common.CurrentVersion.targets(4570,5): error MSB3030: Could not copy the file "/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/Dependencies/openal-soft/Windows/x64/soft_oal.dll" because it was not found. [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
/usr/share/dotnet/sdk/3.1.103/Microsoft.Common.CurrentVersion.targets(4570,5): error MSB3030: Could not copy the file "/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/ThirdParty/Dependencies/openal-soft/Windows/x86/soft_oal.dll" because it was not found. [/home/user/Barotrauma/Libraries/MonoGame.Framework/Src/MonoGame.Framework/MonoGame.Framework.Linux.NetStandard.csproj]
Compiling the Game
With the SDL game controller database downloaded and MonoGame's build project patched, we're ready to build Barotrauma. For that, we'll run dotnet publish
and pass it the project file for the Linux game:
dotnet publish Barotrauma/BarotraumaClient/LinuxClient.csproj --configuration Release --self-contained --runtime linux-x64 /p:Platform=x64 /p:DebugType=None --output game
Depending on the performance of your computer, this should take 10–20 seconds. You'll find the executable files for the game in the game
directory (as requested by --output game
). As of May 17, 2020, it generates around 133.2 MiB worth of files. All that's missing now are the graphical, audio and other assets. Locate the game's directory in your Steam library and copy the Content
directory over to game
. The only conflicts you should see are *.xnb
files in Content/Effects
. Skip overwriting those.
That's it. Copy the game
directory where you see fit and run the Barotrauma
executable.
./Barotrauma
Your game preferences are in the config_player.xml
file in the game directory. If you wish to restore your video and control preferences, copy it from Steam, too. The config_player.xml
file is worth taking a look also for disabling the splash screen, analytics reporting and possible other tweaks. Barotrauma's saves are in ~/.local/share/Daedalic Entertainment GmbH/Barotrauma
, so those should be available wherever you put the compiled game.
By the way, should the command line invocation above not work by the time you're reading this, you could also review the Deploy/Linux
directory in the repository. It includes the scripts the game authors use for compiling.
Compiling the Server
If you intend to host a server with your compiled version, you'll also need to compile the server executable. Using the same dotnet publish
invocation as before, replace Client
with Server
:
dotnet publish Barotrauma/BarotraumaServer/LinuxServer.csproj --configuration Release --self-contained --runtime linux-x64 /p:Platform=x64 /p:DebugType=None --output game
This adds the DedicatedServer
executable (along with a DLL) to the game
output folder.
Build Options
The dotnet
build system takes a number of options. For the sake of reference, here are the options used above as described by dotnet publish --help
:
Option | Description |
---|---|
--configuration | The configuration to publish for. The default for most projects is 'Debug'. |
--self-contained | Publish the .NET Core runtime with your application so the runtime doesn't need to be installed on the target machine. |
--runtime | The target runtime to publish for. This is used when creating a self-contained deployment. |
/p:DebugType=None | Skips generating and copying over debug symbol files (*.pdb ). |
If you're playing on the same machine you compiled on (and have .NET Core installed), you could save a bit of disk space by not bundling the .NET Core libraries in the game output folder. Pass --no-self-contained
to dotnet
to reduce the game directory to 55.2 MiB. I think it's safer to keep them bundled, should you want to copy the game over to another computer or just uninstall the dotnet-sdk
package previously installed.