Skip to main content
Version: 0.1.1

Getting started

Server-side mods run inside the OblivionMP relay server. They can register their own networked components, attach them to existing archetypes, run gameplay systems on the server tick, and handle RPCs sent by clients.

A server-side mod is a .NET class library referencing the server SDK, defining a single class extending ServerModBase. Its assembly is placed directly in the server's server_mods/ directory — a separate location from the client-facing mods/ folder — where the mod loader picks it up and instantiates the class when the server starts.

Start from the template

The official OblivionMP mod template already wires up a server project next to its client and shared projects, with a working example and a packaging script. Clone it and follow the README rather than setting the references up by hand.

Minimal server mod class
using ReadyM.Relay.Server.Sdk;
using ReadyM.Relay.Server.Sdk.Ecs.Components;

public class MyServerMod : ServerModBase
{
protected override void RegisterComponents(IComponentRegistry registry)
{
// register your networked components here
}

protected override void Init()
{
// register systems, RPC handlers, and modify archetypes here
}
}

RegisterComponents runs first, before the server's ECS schema is finalized — this is the only place you can register new networked components. Init runs afterwards and is where you resolve services, register systems and RPC handlers, and attach components to archetypes.

Registering components and archetypes

Just like on the client, a networked component must be declared with [DeriveINetworkedComponent] — see Custom components for the full pattern. On the server, register it in RegisterComponents, then attach it to an archetype in Init:

Registering a component and attaching it to the global player archetype
public class MyServerMod : ServerModBase
{
protected override void RegisterComponents(IComponentRegistry registry)
{
registry.RegisterComponent<WalletComponent>();
}

protected override void Init()
{
var registry = Services.Resolve<IArchetypeRegistry>();
var archetypes = Services.Resolve<OblivionArchetypes>();

registry.ModifyArchetype(archetypes.GlobalPlayerArchetype, archetype =>
{
archetype.Add<WalletComponent>();
});
}
}

A wallet is persistent, player-scoped data, so it belongs on the global player entity: one entity per connected player that lives for the whole session, regardless of which area or cell the player is in. Data that describes the character's presence in the world (position, vitals, equipment) belongs on the main character instead. See Archetypes and components for what each archetype carries.

important

A networked component's shape and its archetype membership must match between the server mod and every client mod. Ship server-side and client-side mods together as versions of the same package.

Reading and writing entity data

Inside your mod, use EcsApi (resolved via Services.Resolve<EcsApi>() or injected into your class) to query and modify entities:

Querying entities
ecsApi.Query<WalletComponent>((ref wallet) =>
{
wallet.Balance += 1000;
});

Query overloads support up to six component types at once. See Custom RPC for how a query like this is typically triggered by an incoming client request.

Feature status

FeatureStatus
Networked componentsdone
Gameplay systemsdone
Server RPCdone
Mod manifests🔜 not enforced in 0.1.0