Making your first mod

## Setting up a development environment

First you'll need an IDE to program in. I personally use Visual Studio Community 2019 (which you can download for free) so that's what I'll use for this tutorial, but I believe the devs use JetBrains Rider (which you can use for free if you're a student/teacher or if your project is open source and free). This page explains how to install Visual Studio: https://docs.microsoft.com/en-us/visualstudio/install/install-visual-studio (for JetBrains Rider you can apply for an open source license here: https://www.jetbrains.com/shop/eform/opensource). For the rest of this tutorial I'll assume you use Visual Studio Community 2019 on Windows 10 (2022 works pretty much the same afaik so using that is fine too, I just haven't updated yet).

When installing Visual Studio, make sure you at least check .NET Framework 4.8 or .NET Framework 4.7.2. Unity *might* work with .NET 5, but it's not supported as far as I know and users of your mod may have to install .NET 5 themselves to even be able to run it.

## Creating a new project

After installing Visual Studio, you can create a new project. Choose the 'Class Library (.NET Framework)' template. Choose a project name, and select .NET Framework 4.8 or 4.7.2 in the Framework dropdown. You now have a .cs file with a couple of system using statements at the top, followed by a class in a namespace. You can delete the Main method, we won't be using it.

To use objects and methods from the game and unity in general, you'll need references to the relevant dll files. In the solution explorer on the right, rightclick 'References' and choose 'Add Reference ...'. This will open a screen where you can browse for files. Go to your Rail Route installation's data/managed folder (default location is `C:\Program Files (x86)\Steam\steamapps\common\Rail Route\Rail Route_Data\Managed`), and add references to `RailRoute.dll`, `UnityEngine.dll`, and `UnityEngine.CoreModule.dll`. You may find that you will need to reference additional unity modules in order to use certain functions, usually the unity documentation will tell you which namespace something lives in (namespace names are almost always the same as dll names, just like .cs file names are almost always the same as the name of the class they contain).

Add using statements to your .cs file: `using Game.Context;`, `using Game.Mod;`, `using UnityEngine;`, and `using Utils;`. These will allow you to use classes without having to specify the namespace every time (you can write `IController` instead of `Game.Context.IController` if you have `using Game.Context` for example). I'll occasionally use the full name here to make clear which namespace something lives in.

## Getting the game to use your mod

The way the game loads mods is by looking for classes which implement the `Game.Mod.IGameMod` interface. It will then instantiate your class, call `OnEnable` when the game starts and mods are loaded, call `OnContextChanged` when the scene changes (e.g. from the main menu to the editor), and call `OnDisable` when the game stops. These are the main methods which are used to start your mod (or stop in the case of `OnDisable`, but that method is not always called such as when the game is forcibly shut down with alt-f4).

Therefore, you will want your main class to inherit from `Game.Mod.AbstractMod` which implements the `IGameMod` interface. In C#, this is done like this: `public class YourMainClass : AbstractMod`. Visual Studio will immediately complain about how you haven't implemented a Title or Description property, so we'll do that now: add `public CachedLocalizedString Title => "your mod title";` and `public CachedLocalizedString Description => "mod description";` to your class. These strings don't have a function yet as far as I can tell, but they probably will in the future (or if someone makes a mod manager mod, they might use these properties perhaps).

The main way you can debug your mod is by sending messages to the log file. You can do this by calling the `Debug.Log` unity function. For your first mod, let's log "hello world!" whenever the a level is started. We'll use the `OnContextChanged` method for this, which also provides us with a `Game.Context.IController` object which contains references to all other controller objects. This object is the main way in which you can access objects in the game: it contains references to a bunch of other controller objects which in their turn have useful methods or other objects. In this case we need the `CurrentMode` property. If this property is equal to `GameMode.Play`, we know that a level has started and can log "hello world!":

```
public override async Task OnContextChanged(IControllers controllers)
{
 if (controllers.CurrentMode == GameMode.Play)
 {
 Debug.Log("hello world!");
 }

 await Task.Yield();
}

```

You don't need to understand how asynchronous programming works, you can just use the magic 'async Task' and 'await Task.Yield()' words and the game will handle the rest.

## Building your .dll

Now go ahead and build your dll (F6, or use the buttons at the top of VS). You will find your dll in the bin/Debug folder in your project. Copy this file, go to the mod folder (`%USERPROFILE%\AppData\LocalLow\bitrich\Rail Route\mods`), make a new folder with your mod's name and put the dll in that folder. Having to do this every time you change something in your code is annoying, so you can automate this by right-clicking your solution in the solution explorer, going to 'Properties', then 'Build Events' and putting this in the post-build event command line:

```
echo F|xcopy $(TargetPath) "%USERPROFILE%/AppData/LocalLow/bitrich/Rail Route/mods/YourModName/$(TargetFileName)" /y
start steam://rungameid/1124180

```

This will copy the file from your build path to your mod folder (and overwrite the previous version of your dll), and then start the game via Steam. If you now start the game, open a level, and quit the game again, you can find the "hello world!" in the Player.log file (`%USERPROFILE%\AppData\LocalLow\bitrich\Rail Route\Player.log`). **You got your first mod working!**