DedicatedServerMod supports paired server/client mods through assembly metadata instead of making server owners maintain ordinary allowlists by hand.
This page covers:
S1DSClientCompanionAttributefor server-side mod assembliesS1DSClientModIdentityAttributefor client-side mod assemblies
Why This Exists
Without metadata, a server mostly sees anonymous client DLLs and hashes. With metadata:
- server mods can declare which client companion they expect
- client mods can declare a stable ID and version
- the server can verify compatibility automatically
The normal path is:
- match by
modId - enforce
minVersion - use hashes only for deny lists and optional strict mode
Server-Side Attribute
Apply S1DSClientCompanionAttribute at the assembly level in the server mod project:
using DedicatedServerMod.API;
[assembly: S1DSClientCompanion(
modId: "ghost.mycoolmod",
displayName: "My Cool Mod",
Required = true,
MinVersion = "1.2.0")]
Fields:
modId: stable identifier shared with the client companiondisplayName: user-facing name shown in verification messagesRequired: whether the client companion must be installed to joinMinVersion: minimum compatible client versionPinnedSha256: optional strict-mode hash pins
When To Use PinnedSha256
Usually, do not.
For normal compatibility-first servers, modId plus MinVersion is the intended workflow. PinnedSha256 is only for servers that explicitly enable strictClientModMode.
Client-Side Attribute
Apply S1DSClientModIdentityAttribute at the assembly level in the client mod project:
using DedicatedServerMod.API;
[assembly: S1DSClientModIdentity("ghost.mycoolmod", "1.2.3")]
Fields:
modId: stable identifier for the modversion: version string reported during join verification
The modId must match the server companion declaration.
Full Paired Example
Server assembly:
using DedicatedServerMod.API;
[assembly: S1DSClientCompanion(
modId: "ghost.marketterminal",
displayName: "Market Terminal",
Required = true,
MinVersion = "2.0.0")]
Client assembly:
using DedicatedServerMod.API;
[assembly: S1DSClientModIdentity("ghost.marketterminal", "2.1.0")]
Result:
- the server requires the client companion to be present
- the client can join if its companion version is
2.0.0or newer - no per-build hash maintenance is required unless the server enables strict mode
Optional Companion Example
If a server-side feature can work without the client mod but improves UX when present:
[assembly: S1DSClientCompanion(
modId: "ghost.mapmarkers",
displayName: "Map Markers",
Required = false,
MinVersion = "1.0.0")]
This means:
- clients may join without the companion
- if they do load it, it still must be compatible
Client-Only Mods
A mod with no server component can still declare S1DSClientModIdentityAttribute.
That is recommended because it gives server owners a stable mod ID they can:
- deny in
client_mod_policy.toml - approve in strict mode
- recognize in logs and disconnect reasons
Example:
[assembly: S1DSClientModIdentity("ghost.visualtrees", "1.0.0")]
Guidance For Mod Authors
- keep
modIdstable across releases - use a clear, author-prefixed identifier
- bump
versionon every client release - prefer
MinVersionover hash pins for normal compatibility - only ship
PinnedSha256if you intentionally support strict-mode operators
What Server Owners See
When your mod uses these attributes correctly:
- required companions are enforced automatically
- optional companions are recognized automatically
- strict-mode operators can still add hash pins if they want exact binary control
For the server-owner side, see Client Mod Verification.