Client Mirrors
Audience: Server operators · Prereqs: Architecture Overview
Canonical source:
server-client/start-client.js
Unlike a game server (which needs authorization), a client server needs no registration at all - anyone can stand one up pointed at your services server, the same way anyone can run a mirror of a normal website. This page covers when and how to actually do that deliberately, as part of your own deployment.
Why you'd want more than one
- Geographic spread - serving the (static, cacheable) game files from a location closer to your players reduces load time, independent of which game server region they end up playing on.
- Redundancy - if one client server goes down, players hitting a different mirror are unaffected.
- Load - the client server does real work on startup (building the browser bundle, generating the stamp spritesheet) and serves static assets afterward; spreading traffic across mirrors reduces load per machine, though a single client server can typically serve a lot of static traffic before this matters.
Setting one up
Nothing beyond a normal LegacyShell install (see Installation) plus pointing its config at your existing services server instead of a local one:
# store/config/client.yaml
port: 13370
sync_server: "ws://your-services-host:13371" # or wss:// through a reverse proxy, see Deployment
Start it with npm run client as usual. It polls services for maps/items/servers/config the same way every client server does (see Architecture Overview) - there's no separate "register this mirror" step, because the client role is stateless and unauthenticated by design.
What's shared vs. independent between mirrors
- Shared (pulled from services): maps, items, the server list, distributed config (
distributed_all.yaml,distributed_client.yaml,distributed_permissions.yaml). - Independent (local to each mirror):
client.yamlitself - port, closed mode, HTTP Basic Auth (login.enabled),this_url. Each mirror can have its ownclosed: truewithout affecting the others - see Closed Mode.
Common Issues
A mirror shows stale maps/items after I updated them on services. It hasn't re-polled yet, or the update didn't actually change what services reports as current - restart the mirror to force an immediate requestConfig, and confirm the change actually landed in services' database first (see The Database).
Mirrors need to serve different content from each other. That's not really what this mechanism is for - all mirrors serve the same game, synced from the same services server. If you need genuinely different content per audience, that's more of a plugin or separate-deployment question than a client-mirror one.
Next: Content Creation, or back to Adding Game Servers if you haven't set up your game-server side yet.
This page was drafted with AI assistance and reviewed for accuracy. If something looks wrong, please open a PR or flag it.
