Setup
Now that you know the general structure of a mod for DEETS++, let’s get into making our first mod. Let’s just call it author.sample_mod for now.
First, try to make sure that very basics of your mod’s file structure is ready. This would be a good starting point:
Directoryres://
Directory_mods/
Directoryauthor.sample_mod/
- metadata.json
Alright! Then, fill out the metadata:
{ "id": "author.sample_mod", "version": "0.0.1", "name": "Sample Mod", "desc": "Basic description", "author": ["Author"], "class": "Author.SampleMod", "dependencies": {}}Note how the class parameter is called Author.SampleMod… we’ll get to that later.
Now that we have that out of the way, let’s open the mod’s root folder in the terminal and let .NET know that we want to make a library.
It’s not required to do this per se if you just want to make a super simple mod where you change graphics around, but anything involing code you’ll have to do through your own library.
With that said, let’s type this into our terminal:
dotnet new classlibYou’ll probably get this as an output:
The template "Class Library" was created successfully.Processing post-creation actions...Restoring (DEETS++ Project Root)\_mods\author.sample_mod\author.sample_mod.csproj:Restore succeeded.This is good! We now have a .NET project on our hands.
Next, we want to modify the .csproj file so that when we build it, DEETS++ will be happy when it’ll try to load it in.
Use this as a template:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> <OutputPath>./</OutputPath> </PropertyGroup> <ItemGroup> <PackageReference Include="GodotSharp" Version="4.8.0-dev.1" /> </ItemGroup> <ItemGroup> <ProjectReference Include="../../DEETS++.csproj"> <PrivateAssets>All</PrivateAssets> </ProjectReference> </ItemGroup></Project>This tells .NET a few things
- Targets the framework to .NET 8.0 (which is what Godot uses)
- Allow unsafe blocks in code in case you want to do some crazy stuff with C# itself (you can turn this off if you’d like)
- Sets the output path to your mod’s root directory
- Reference Godot’s C# bridge and DEETS++’ source code
The last thing we have to do is take care of that Class1.cs .NET generated for us. Let’s rename this to the name of our mod, which in this case would be SampleMod.cs.
Let’s open it up:
namespace author.sample_mod;
public class Class1{
}We need to change a few things here. Remember how we told you that the class parameter in our metadata corresponds to the “entrypoint class”?
"class": "Author.SampleMod"DEETS++ will take whatever C# class that’s in DEETS.Mods corresponding to the class parameter in our metadata and use that as the mod’s entrypoint.
As such, all we have to do is change it to this:
using Godot;namespace DEETS.Mods.Author;public partial class SampleMod : DEETS.Modding.Mod { public override void _Ready() { GD.Print($"[{this.ModID}] Hi from C#!"); }}SampleMod extends DEETS.Modding.Mod, which is a class that extends Godot’s Node class. DEETS.Modding.Mod has some extra variables to offer that DEETS++ fills in before adding it to the scene tree:
ModID, the mod’s IDManifest, the mod’s metadata / manifest
Note how we use the class’ ModID variable to print out that text in its _Ready function! Let’s save it, and run the game to see if it worked.
If everything worked right, you should see something like this in the output:
[DEETS++] Loading mod "author.sample_mod"...[author.sample_mod] Hi from C#!Great! It worked! We’re ready to actually stuff to the game now!