Palforge

Getting started

Install the Palforge template, scaffold a plugin, and deploy it to your server.

This page takes you from nothing to a running plugin: install the template, scaffold a project, write a little behaviour, and deploy it to your Palworld dedicated server.

If you want the bigger picture first, read How Palforge works. Otherwise, start here.

Prerequisites

RequirementNotes
.NET 10 SDKPlugins target net10.0. The SDK builds them; the runtime is shipped inside Palforge itself.
Windows x64Palforge runs in-process inside the Windows dedicated server. Plugins are Windows/x64.
A Palworld dedicated serverWith Palforge installed — its version.dll sits next to PalServer-Win64-Shipping.exe.

Palforge is self-contained: the shipped build bundles its own .NET runtime under Palforge\Core, so the server machine does not need a machine-wide .NET install. You only need the .NET 10 SDK on the machine where you build plugins.

Install Palforge on the server

Palforge is delivered as a release bundle you unpack into your server's Win64 directory. After installing, the layout looks like this:

…\PalServer\Pal\Binaries\Win64\
├─ PalServer-Win64-Shipping.exe
├─ version.dll                 ← Palforge proxy
└─ Palforge\
   ├─ Configuration.cfg        ← runtime configuration
   ├─ Core\                    ← the managed runtime (self-contained)
   ├─ Logs\
   └─ Plugins\                 ← your plugins go here, one folder each

Start the server once with Palforge installed; you should see a Palforge Dedicated Server console and a Palforge\Logs\Palforge-<date>.log file. See Configuration for the console and logging options.

Scaffold a plugin

Install the template package, then create a plugin project from it:

Install the template

dotnet new install Palforge.Templates

Create a plugin

Scaffold a new plugin. Point --DeployDirectory at your server's Win64 folder and every build will deploy the plugin there automatically:

dotnet new palforge-plugin -n MyPlugin \
  --DeployDirectory "C:\Program Files (x86)\Steam\steamapps\common\PalServer\Pal\Binaries\Win64"

The template creates a project that references Palforge compile-only (the runtime lives on the server), plus an optional configuration file:

MyPlugin/
├─ MyPlugin.csproj              references Palforge (ExcludeAssets=runtime)
├─ MyPlugin.cs                  your Plugin subclass
├─ MyPluginConfiguration.cs     optional: register services / bind config
└─ MyPlugin.cfg                 optional: per-plugin INI settings

Build and deploy

dotnet build ./MyPlugin

Because you set --DeployDirectory, the build copies the output into …\Win64\Palforge\Plugins\MyPlugin. Leave the deploy directory empty and the build simply produces the plugin without deploying — you can copy it yourself.

The plugin's folder name, its assembly name, and its .cfg file must all match (MyPluginMyPlugin.dll + MyPlugin.cfg). Palforge discovers a plugin by looking for Plugins\<Name>\<Name>.dll. See Plugins.

Write your first plugin

The scaffolded MyPlugin.cs is an empty Plugin. Fill in OnStart:

using Microsoft.Extensions.Logging;
using Palforge.Plugins;
using Palforge.Plugins.Attributes;

namespace MyPlugin;

[Plugin("com.example.myplugin", Name = "My Plugin", Author = "you", Version = "1.0.0")]
public sealed class MyPlugin : Plugin
{
    protected override void OnStart()
    {
        Log.LogInformation("MyPlugin started");

        // Announce every player as they spawn into the world.
        Scope.OnNewObject("PalPlayerCharacter", player =>
            Log.LogInformation("Player spawned: {Name}", player.Name));
    }

    protected override void OnStop()
    {
        Log.LogInformation("MyPlugin stopped");
    }
}

Add a chat command by dropping a ChatCommandModule into the same assembly — the host discovers and binds it automatically:

using Palforge.Commands.Attributes;
using Palforge.Commands.Modules.Chat;

public sealed class FunCommands : ChatCommandModule
{
    [Command("ping")]
    [CommandDescription("Replies with pong.")]
    public void Ping() => Reply("pong");
}

With the default ! prefix, a player types !ping in chat and Palforge whispers pong back. See Commands for arguments, groups, permissions and more.

Manage plugins at runtime

Palforge registers a built-in admin command group. From in-game chat (as an admin), you can list and hot-reload plugins without restarting the server:

!plugin list
!plugin load MyPlugin
!plugin reload MyPlugin
!plugin unload MyPlugin

For a clean unload, stop anything you started outside the plugin scope (your own threads or tasks) in OnStop. The plugin's AssemblyLoadContext is collectible, and Palforge verifies it is actually collected after unload — a leaked reference keeps the old code alive. See Unload and reload.

Next steps

On this page