> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta-core.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Modules

> How to install and make command modules for SkyNET V3.

<Warning>
  Modules are still early. Right now they can only add prefix commands and show up in help.\
  Events, MySQL, settings, and Dashboard / `!perms` access are not supported yet.
</Warning>

Starting with SkyNET **3.1.8**, you can drop extra command packs next to the bot without rebuilding SkyNET itself.\
Put them in a folder called `modules/` next to the SkyNET binary. When SkyNET updates, that folder is left alone, so your modules stay installed.

To **build** modules you need **.NET 9**. The host expects `apiVersion` **1**.

<Card title="Module SDK kit" icon="download" horizontal href="https://skynet.beta-core.net/modules/SkyNET-Module-Example.zip" cta="Download">
  SDK NuGet package, Fluxify deps, and a small StarterModule (`!hello`) to copy and rename.
</Card>

# Installing a module

1. Get a built module folder (or build the starter from the kit above).
2. Copy it into `modules/` like this:

```text theme={null}
SkyNETV3
modules/
  MyModule/
    module.json
    StarterModule.dll
```

If the module needs extra DLLs that SkyNET does not already ship, put those in the same folder.\
Do **not** copy `SkyNET.ModuleSDK.dll` here — the bot already has the SDK.

3. Restart SkyNET.
4. Check the log. You should see something like:

```text theme={null}
[Modules] Activated Starter (com.example.starter) v1.0.0 from ...
[Modules] Loaded 1 module(s) from ...
```

5. Try the command. With the default prefix that would be `!hello`, and `!help hello` for help.

To update a module, replace the files in its folder and restart.\
To remove one, delete its folder and restart.

If a module fails to load, SkyNET logs it and keeps running. Command names that already exist (built-in or another module) are skipped.

# module.json

Every module folder needs a `module.json`:

```json theme={null}
{
  "id": "com.example.starter",
  "name": "Starter",
  "version": "1.0.0",
  "apiVersion": 1,
  "entryAssembly": "StarterModule.dll"
}
```

| Field         | Description                                 |
| ------------- | ------------------------------------------- |
| id            | Unique id for the module. Keep this stable. |
| name          | Name shown in the log when it loads.        |
| version       | Your module version.                        |
| apiVersion    | Must be `1` for current SkyNET builds.      |
| entryAssembly | The DLL file name in the same folder.       |

# Making a module

1. Download the [Module SDK kit](https://skynet.beta-core.net/modules/SkyNET-Module-Example.zip) and unzip it.
2. Open `StarterModule` (or copy that folder and rename it).
3. Keep the kit’s `nuget/` folder and `nuget.config` next to the project so restore can find `SkyNET.ModuleSDK`.
4. Implement / edit `ISkyModule`. If the assembly has more than one possible type, mark the real one with `[SkyModule]`.
5. In `Load`, register your commands. Set a `Description` so they show up under **Modules** in `!help` / `!cmds`.

Reference **SkyNET.ModuleSDK** only — do not pull in SkyNET host assemblies.

The starter project already looks like this:

```xml theme={null}
<ItemGroup>
  <PackageReference Include="SkyNET.ModuleSDK" Version="1.0.0" />
</ItemGroup>
```

And a minimal module:

```csharp theme={null}
using Fluxify.Commands;
using SkyNET.ModuleSDK;

[SkyModule]
public sealed class StarterSkyModule : ISkyModule
{
    public string Id => "com.example.starter";
    public string Name => "Starter";
    public string Version => "1.0.0";

    public void Load(IModuleContext context)
    {
        context.RegisterCommand(
            "hello",
            ctx => ctx.ReplyAsync($"Hello, {ctx.Author.Username}!"),
            new ModuleCommandOptions
            {
                Aliases = ["hi"],
                GuildOnly = false,
                Description = "Say hello (starter module sample).",
                Usage = "hello",
                Examples = "hello\nhi"
            });
    }
}
```

Build it:

```bash theme={null}
cd StarterModule
dotnet build -c Release
```

Then copy `module.json` and `StarterModule.dll` from `bin/Release/net9.0/` into `<bot>/modules/MyModule/`.

# What the SDK gives you

| Member          | What it does                                                           |
| --------------- | ---------------------------------------------------------------------- |
| RegisterCommand | Adds a prefix command. If the name is taken, it is skipped and logged. |
| RegisterHelp    | Lets you change help text for a command you already registered.        |
| ResolvePrefix   | Gets the prefix for a guild (or the default if you pass null).         |
| Log             | A logger for your module.                                              |
| ModuleId        | The id from `module.json`.                                             |

`ModuleCommandOptions` can set `Aliases`, `GuildOnly` (defaults to true), `Description`, `Usage`, `Examples`, and `Notes`.\
Write usage and examples **without** the prefix.

<Note>
  Module commands are open to everyone. There is no Dashboard or `!perms` gate on them yet.
</Note>

Pick command names that do not clash with SkyNET or other modules.\
There is no hot-reload — always restart after you change something.
