STYGION Documentation Search the docs

Moderation

Bans and kicks with a reason, an end, and a screen the player actually reads — one list, not two.

Keystone 0.2.8 Updated 4 min read

This page is older than Keystone 0.2.8, released 18 October 2026. Something may have changed since.

On this page 6 parts
  1. The commands
  2. The game's own /ban and /kick
  3. The screen a player is shown
  4. Discord
  5. What is not here yet
  6. Mutes

Moderation

Bans and kicks that carry a reason, an end, and a screen the player actually reads. All of it in moderation.toml and on the Players screen in the editor.

The commands

#
Code
/keystone ban <player> [for how long] [reason]
/keystone unban <player>
/keystone kick <player> [reason]
/keystone bans
/keystone history <player>

The length is an ordinary duration — 7d, 12h, 30m. Without one the ban does not end. The reason is what the player is shown, so it is worth writing for them rather than for you.

/keystone bans lists what still stands. /keystone history <player> lists everything this server has ever done to somebody, including what has expired.

The permissions are keystone.ban and keystone.kick, separately. They apply to the game's own /kick, /ban, /pardon and /banlist too when Keystone takes them over (see below). A moderator who is not an operator cannot kick or ban an operator, or anybody in a heavier group than their own.

The player really reads the reason. Every kick, ban, maintenance close, restart and failed sign-in now reads the client dry first, sends the reason and only then closes the connection. Otherwise Linux resets the connection and the player reads Connection reset by peer instead of why. A Discord ban no longer disconnects somebody off the server thread.

The game's own /ban and /kick

#
Code
moderation.take-over-vanilla = true

On (the default): the commands people's fingers already know write into this ledger, end on their own date, and show the screen you wrote.

Off: they are the game's again — which means a ban typed as /ban is invisible to /keystone bans, never expires, and shows "You are banned from this server." Leaving this off is choosing to have two ban lists.

The screen a player is shown

#

Three of them belong here, and all are overridable in operations.toml under screens:

Screen When
screens.banned A ban with no end
screens.banned-until A ban with a date
screens.kicked A kick

The text takes {reason}, {by}, {until}, {left}, {player} and {appeal}. Blank lines are allowed and worth using — this is the one thing that person is reading at that moment.

screens.appeal is where to appeal, and it fills in on every screen that carries {appeal}. A ban with nowhere to write to is a ban you never find out was wrong.

Discord

#

With the bridge on, a ban can mean it in both places:

  • discord.ban.game-to-discord — a ban in game bans on Discord too,
  • discord.ban.discord-to-game — and the other way,
  • discord.ban.who-may — whose bans on Discord are allowed to reach the game.

Both directions are off by default, because it is a decision rather than a convenience. In detail on the Discord page.

What is not here yet

#

There are no warnings in the mod yet, and a muted player can still write on signs and in books.

Mutes

#

From Keystone 0.2.4.

Code
/mute <player> <time> [reason]      30m, 12h, 7d, or forever
/unmute <player>
/mutes

Also as /keystone mute, /keystone unmute and /keystone mutes (where another mod owns /mute). Permission keystone.mute, asked again every time the command runs.

  • Into the same ledger as bans: /keystone history shows every mute with its reason, author and end; GET /v1/mutes (players.read) lists those that stand. It ends on its own date — nothing has to remember to lift it — and survives a restart and a reconnect.
  • What it closes: the player's chat, the commands in mute.blocked-commands (by default /msg, /tell, /w, /whisper, /me, /r, /reply, /teammsg, /tm — add another mod's mail or party chat by name), and what their linked Discord account writes into the bridged channel. Each try tells them the reason and how long is left. The Discord bridge never hears a muted line.
  • Never above you: nobody mutes somebody in a heavier group or an operator (unless they are one), nor anybody with keystone.mute.exempt. A mute somebody above you gave is theirs to lift: /unmute refuses you and says who. Nobody lifts their own mute. The console may do anything.
  • A second /mute replaces the first; it does not add up.
  • mute.enabled = false switches all of it off (after a restart).

Did this page help?

Opens the feedback panel with this page attached. It lands in the same queue as everything else.