As a Software Developer and a Gamer, it’s hard not to love Space Engineers, think Minecraft for engineers. When the programming block was added it allowed users to write in-game script to perform complex interactions with the local grid, essentially opening up a huge range of possibilities. Rather than needing to tie together complex chains of sensors to trigger actions, a simple script can perform the logic needed to interaction dynamically with components across the grid.

So writing C# scripts in-game is great, except the in-game editor sucks. No version control, no syntax highlighting, and no formatting.

Luckily it is possible to write scripts outside of SpaceEngineers, compile them against the SpaceEngineers codebase, and copy them into the game. This also allows us to use standard SCM, and share scripts outside of the steam workshop. Reddit user ‘valadian’ outlines how to do this in Visual Studio in a handy post, however I’ll cover how to do the same using MonoDevelop on both Windows and Linux. Currently the SpaceEngineers codebase is does not work on Linux, however it’s still possible to compile the required binaries for the ModAPI, and build against them.

To be clear this is my first forray into C#, so chances are I’ll be making some stupid mistakes, feel free to point them out so I can learn. My example repo for this guide is available here.

MonoDevelop on Windows

For Windows, the steps for setting up MonoDevelop more or less follow what ‘valadian’ posted on reddit.

First, grab a copy of MonoDevelop, which is packaged as part of Xamarin Studio here. This guide is using version 5.9.2. Alongside installing the required dependencies listed on the download page (.NET Framework and GTK), also grab a copy of the .NET SDK, which it seems is only available through the Windows SDK. The simplest way to get hold of this is to grab a copy of Visual Studio 2013 for free. If anyone has a way of getting hold of the .NET SDK on its own, please leave a comment and I will update this section.

Once you have all three packages installed, as well as MonoDevelop, open it up and create a new solution for your script, or set of scripts. This should be a barebones, empty C# project, so use the “Empty Project” template. Now your solution is created, you need to add a reference to the required SpaceEngineers library location in your Steam folder. To do so, select your solution references, and click “Edit References”.

This will bring up the “Edit References” dialog. From here, select “.Net Assembly” and browse to locate your Space Engineers steam folder.

Once you are browsing the Space Engineers steam folder, select “bin/Sandbox.Common.dll”.

Click Open, and ensure the Sandbox.Common.dll is ticked in the “Edit References”, and then click Ok.

You should see Sandbox.Common listed in your solutions references.

At this point, you can create scripts and compile them against the SpaceEngineers ModAPI. For a quick overview on how to do this, scroll down to the bottom of this guide, past the Linux guide.

MonoDevelop on Linux

The MonoDevelop setup for linux is more or less the same, however instead of being able to grab a .dll from the steam folder, we need to build one ourselves. First, grab a copy of MonoDevelop, which is packaged as part of Xamarin Studio here. For this guide I’ll be using MonoDevelop version 4.0.12.

You’ll also need to pull down the SpaceEngineers source code, and compile the “Sandbox.Common” namespace. To do this, you’ll need to install git, pull down the repo, open it in MonoDevelop, and build Sandbox.Common.

First, lets install git and cd to our workspace

sudo apt-get install -y git && cd ~/workspace

Next clone the SpaceEngineers source code.

git clone git@github.com:KeenSoftwareHouse/SpaceEngineers.git

Now open the SpaceEngineers.sln file in MonoDevelop and you should see a few errors.

These are caused by a Visual Studio specific ToolsVersion being specified in some project files. To fix this, just run this command from within your “Sources” folder.

sed -i -e ‘s/ToolsVersion\=\”12.0/ToolsVersion\=\”4.0/’ ./*/*.csproj

This will replace that tools version with one compatible with MonoDevelop. Now when you open the solution, or reload the erroring namespaces, you should not see any error messages.

Lets try and build; in the Solution Explorer, open Game and select Sandbox.Common. From here press F7 or open the Build menu and click “Build Sandbox.Common”. This may produce an error, although it’s really a warning. This is happening because in some namespaces the compiler is set to treat errors as warnings.

Since all we want are headers to build our script against, we don’t care about warnings, so we can ignore them. To do so we need to select a namespace, right click, select Options, and then under Compiler uncheck the box to treat errors as warnings.

Do this for the following namespaces:

VRage.Library

VRage.Math

VRage

Once this has been done, rebuild Sandbox.Common and you should have warnings, but no errors, and a juicy new dll will created: SpaceEngineers/Sources/Sandbox.Common/bin/x86/Debug/Sandbox.Common.dll.

Finally you can create a new solution for your scripting, loading this dll as a reference just like with the Windows example.

Scripting in MonoDevelop

At this point you should have a solution created for your script, or set of scripts, with a reference to Sandbox.Common listed. Now we can get to scripting! Just create a new empty C# file, and paste in a script from Space Engineers, or create a new one.

Space Engineers treats code a little differently than MonoDevelop does, so you’ll need to add a little wrapping code to replicate what Space Engineers does when it compiles a script.

First off you need to wrap your code in a namespace and a class, so lets start by adding those, as well as the wrapping braces. It’s also a good idea to add in comments indicating what portion of the code should be copied and pasted into the Space Engineers editor. Imports should get placed at the start of the file, which means the user would have to copy both independently. Your code should look something like this:

And at the bottom of the file:

Finally we need to add a reference to GridTerminalSystem, normally provided by the Space Engineer execution layer. We can add a dummy reference here though, since we’re only compiling the code. We’ll also need to add a static main function, however this conflicts with the Space Engineers scripting requirements. To get around this we can simply add a wrapper class with the static method, calling the main method on the script class.

That’s it! You can now use code formatting, syntax highlighting, and reference the exposed apis from Sandbox.Common in the editor. Once you’re ready to push your code up to Space Engineers, paste in the imports, and all the text in between the tags and it should compile. You can download the code listed throughout this guide from my example repository on github.

Be aware that Space Engineers has some restrictions on looping complexity and imported libraries. Just because something works in MonoDevelop, does not mean it will work in Space Engineers. Try to keep your loops to a minimum, and use timer blocks instead where possible.

**EDIT**

When moving scripts into Space Engineers there is no need to paste imports. The Space Engineers editor does not support custom ‘using’ statements.