Skip to content

Sides and hosting

Enshrouded ships two binaries: enshrouded_server.exe, the dedicated server, and enshrouded.exe, the client. The loader runs in both.

side: in the manifest says where a mod’s features belong:

  • SERVER: server features. The dedicated server loads the mod, and so does the client, to run them while it hosts a game.
  • CLIENT: client features only. The dedicated server skips the mod.
  • BOTH: features on both, such as content or a value the client’s interface also reads.

A client that hosts a game, solo play included, runs the whole server on a thread of its own, GameServer, beside its own world. Every mod must work there as on a dedicated server, so the server features act whenever the client hosts:

  • game events, the world reads, the scheduler, inventories and actions serve the built-in server from its first step until the game stops;
  • each hosted game starts with WorldLoaded and ends with ShutdownStarted. The next game has a new server, a new thread and new entities, so reset state tied to one game, such as entity ids, on ShutdownStarted;
  • while no game is hosted, the server features rest: the world reads return nothing and no game events come.

Host::hosting tells whether this process runs a server now: always on the dedicated server, on the client from the built-in server’s first step until the game stops.

fn acts() -> bool {
enshwick::host().is_some_and(|host| host.hosting())
}

Server systems run only in the server’s world, but some game functions serve both worlds of a hosting client, such as cursor checks and base stock. A hook on one of them acts for the server only after it asks ecs::Worlds:

fn init(load: &mut enshwick::Load<'_>) -> Result<(), enshwick::Off> {
let worlds = enshwick::ecs::Worlds::resolve(load)?;
// In a hooked system, with its context `ctx`:
// if unsafe { worlds.is_server(ctx) } { ... }
Ok(())
}

is_server(ctx) is always true on the dedicated server. Entity ids of the two worlds are unrelated. ECS inside systems has more.

The client binary holds its own copies of the server’s functions, at other addresses. A mod that pins server symbols itself pins them for the client too, in a build row with side: CLIENT. When a mod’s server and client halves hook the same function, one link answers for both. See Finding the game.