Skip to content

Server Admin Guide

For the person standing up a fork and running it, not the person authoring content (02_ADDING_AN_ITEM.md) or writing a module (01_WRITING_A_MODULE.md). Read 00_GETTING_STARTED.md first to get a server running at all — this page picks up from there.


1. Becoming an admin

Nothing in this project can grant you a permission by clicking something in-game — that first grant has to come from outside the game, checked once when your character is created or loaded:

  1. Create a CharacterConfiguration asset (.characterconfig) in your addon's Assets/ folder — see Architecture/05_CONFIGURATION.md for how a configuration override works in general.
  2. Add your own SteamID64 to BootstrapAdministratorSteamIds.
  3. Leave BootstrapPermissions as its default (admin.bulletin, admin.give, admin.moderate, admin.teleport, admin.noclip, admin.spectate) unless you're adding your own admin-gated feature and want it granted the same way — see that field's own doc comment in Code/Characters/CharacterConfiguration.cs for why this is an explicit list, not a wildcard.
  4. Restart the server (configuration is read once at boot, like every other configuration asset), then create or reload your character. You now hold every permission listed.

This bootstrap only ever grants, and only to accounts listed in the asset — it has no notion of "make someone else an admin" by itself. Once you hold admin.moderate, though, §2's AdminPanel does: it can grant/revoke any other currently-connected player without editing this asset or restarting the server. The bootstrap is how the first admin on a fresh fork gets in at all; the panel is how every admin after that manages everyone else.

2. The AdminPanel and dev menu

Press the admin_panel keybind to open a live grant/revoke/kick panel for every currently-connected character (Code/Admin/Ui/AdminPanel.razor), dev_menu for an item/job browser with a spawn/join button, module boot-order status, a live config inspector, and a log tail (Code/Admin/Ui/DevMenuPanel.razor), or player_list for a sortable name/distance/position list of every connected character (Code/Admin/Ui/PlayerListPanel.razor, Milestone 11 — no textured minimap, see its own README entry for why). All three require the matching permission (admin.moderate for the admin panel and player list, admin.give for the dev menu) — see Code/Admin/README.md for what each one actually does and doesn't cover (/ban//unban//mute//unmute below have no panel button of their own).

Under the hood these panels are a GUI front end for ordinary commands (/grant, /revoke, /kick, /give, /team) — see §3 below and Code/Commands/README.md for how commands in general work. Nothing about them requires the panel; typing the command directly (once a Chat text-input surface exists — it doesn't yet) works identically.

2.1. Movement commands (Milestone 11)

Six more commands, gated by their own permissions rather than folded into admin.moderate — see Code/Admin/README.md and Architecture/22_PLAYER_PRESENCE_AND_ADMIN_TOOLS.md §3:

Command Permission Does
/goto <characterId> admin.teleport Teleports you to that character.
/bring <characterId> admin.teleport Teleports that character to you.
/tp <x> <y> <z> admin.teleport Teleports you to the given coordinates.
/noclip admin.noclip Toggles noclip for yourself.
/spectate <characterId> admin.spectate Follows that character's camera.
/unspectate admin.spectate Stops spectating.

No panel button for these yet — same "typed command, no reply-to-caller" limitation as every other command (§2 above). None of them have a distance or affordability check: these are admin powers, not proximity or economic ones.

2.2. Real ban records and mute enforcement (Milestone 11)

/ban <characterId> <reason...> [durationMinutes] and /unban <characterId>, plus /mute <characterId> [durationMinutes] and /unmute <characterId>, all gated by admin.moderate — see Architecture/22_PLAYER_PRESENCE_AND_ADMIN_TOOLS.md §6. durationMinutes is optional on both, and omitting it means permanent. /ban's <reason...> must come before durationMinutes; a reason that itself ends in a number (e.g. "used exploit 5") will misparse as a 5-minute ban — named, not solved, since there is no chat text-input surface yet for an admin to trip over this by hand-typing anyway. /mute takes no reason.

A ban blocks new character creation for the account behind the target — checked in CharacterNetworkComponent.RequestCreateCharacter, the only real network entry point into character creation/loading today. It does not disconnect anyone already connected; pair it with /kick if you want that too. A mute blocks every chat channel for the account behind the target — checked at the top of ChatRouter.SendAsync. Same target-resolution limitation as every other command here: /ban//mute can only target a currently-connected character, not an offline SteamId directly. Muting an already-banned account (or the reverse) replaces the older moderation record — there is no "both at once" state.

3. Testing content you just added

Once you're an admin (§1), /give <itemAssetId> [count] — or the dev menu's "Give" button — adds an item straight to your own inventory — the thing 02_ADDING_AN_ITEM.md §5 needs once you've authored a new .item asset and want to actually hold it, rather than only finding it in the S&box editor's asset browser. count defaults to 1. See Code/Inventories/README.md for /give specifically.

4. Choosing which content ships

Every .item and .job asset under Assets/ is loaded automatically (ResourceLibrary.GetAll<T>(), per Code/Items/ItemsModule.cs and Code/Jobs/JobsModule.cs) — there is no separate enable/disable list to maintain. To remove a piece of shipped content from your fork, delete or rename its asset file; to add your own, drop a new one in following 02_ADDING_AN_ITEM.md. If another item's ParentId still points at something you deleted, that's a load-time failure naming the broken reference (Architecture/09_ITEM_FRAMEWORK.md §6), not a silent gap.

5. What this page doesn't cover yet

  • Banning or muting an account that isn't currently connected — every moderation command here (§2.2) targets a live character id, the same as /kick; see Code/Admin/README.md "Not responsible for."
  • A typed player name as a moderation target — every AdminPanel action targets a character id from its own live player list, not a hand-typed name.
  • Tuning prices, cooldowns, and decay rates — that's 00_GETTING_STARTED.md §6, not this page.