aetherESDownload

Your first mod, step by step

In short: you create a project, build it, and the DLL ends up in the game’s Aether/Mods folder. When the game opens, Aether finds it by itself. No other file is needed.

1 · Create the project

Aether ships a command that sets everything up:

aether new MyMod

It creates a folder with three files: MyMod.csproj (the build recipe), Mod.cs (your mod) and a short README.md. If Aether finds your game, the project already knows where Aether’s files are.

2 · Read your mod

Mod.cs already does three things. They are numbered in the comments:

using System;
using Aether.Core.Config;
using Aether.Loader.Discovery;
using Aether.Loader.Entrypoints;
using Aether.Registry;

// This line is how Aether recognises your mod. It must stay at assembly level.
[assembly: AetherMod("my_mod", "1.0.0",
    Name = "My Mod",
    Author = "You",
    Description = "A starter mod for Aether.")]

namespace MyMod;

public sealed class ModEntry : IModInitializer, IClientModInitializer
{
    // 1. An option the player can change (BepInEx/config/aether/my_mod.json).
    public static readonly ConfigEntry<bool> EnableCustomBlock =
        AetherConfig.Bind("my_mod", "Features", "EnableCustomBlock", true, "Register the example block.");

    // 2. Runs when mods load: the place to register blocks, items and recipes.
    public void OnInitialize()
    {
        if (!EnableCustomBlock.Value) return;

        var definition = new BlockDefinition(new Identifier("my_mod", "gem_block"), "Gem Block")
        {
            Hardness = 3.0f,
            IsSolid = true
        };
        DynamicBlockRegistry.Instance.Register(definition);
    }

    // 3. Runs on the first frame, with the game alive: UI, keys, sound and scene objects go here.
    public void OnInitializeClient()
    {
        Console.WriteLine("[MyMod] ready");
    }
}
  1. An option the player can change.
  2. It registers a new block, “Gem Block”, when mods load.
  3. What you see and touch goes here (UI, keys, sound), once the game is alive.

The [assembly: AetherMod(…)] line is what tells Aether this is a mod. It must stay at assembly level.

3 · Change something

Start simple: change the name "Gem Block" to another, or the Hardness number (how hard the block is). Save the file.

4 · Check where Aether is

The project looks for Aether’s files in <game>/BepInEx/plugins/Aether/. If aether new did not find your game, open MyMod.csproj and change AetherDir, or build with -p:AetherDir=<path>. If Aether is not installed, the build stops with a message that says so.

5 · Build and install

cd MyMod
dotnet build MyMod.csproj -c Release -p:InstallToGame=true

With -p:InstallToGame=true the DLL is copied to <game>/Aether/Mods/ for you. Without it, copy bin/Release/netstandard2.1/MyMod.dll into that folder yourself.

6 · Check it

Open the game. Your mod should show in the F10 menu and in BepInEx/LogOutput.log with a line like:

[Aether] Resolved N mods in topological order:
  -> My Mod (my_mod v1.0.0)

Not there? See Build and install, which has a checklist.