
Admin and moderation
Most moderation on BattleSpades is automatic — grief and AFK kicks, team balance, look-alike name protection, protocol checks. This guide shows how those systems work, how to tune them, and how to step in yourself.
Becoming admin
- 01Set a password
[admin] passwordmust be at least 12 characters and notchangeme; otherwise/adminlogin is disabled and startup logs a warning. Containers useBATTLESPADES_ADMIN_PASSWORD. - 02Log in
In game chat type
/admin <password>(or/login). The session lasts until you disconnect. - 03Check
/helpnow also lists the admin commands.
- Passwords are compared in constant time and never written to the log (the command log shows
<redacted>). - After
[anticheat] admin_login_attempts(3) wrong guesses from one address within 10 minutes, the player is kicked and the address is banned for 10 minutes. - Everyone who knows the password is a full admin; there are no separate moderator levels in the game server. Share it carefully and change it (then restart) when someone leaves your team.
- Players (not admins) are rate-limited to a burst of 5 commands, then one per second.
Everyday actions
| Goal | Command |
|---|---|
| Remove someone now | /kick Name reason |
| Keep someone out for a while | /ban Name 2h reason — durations 90 (s), 30m, 2h, 1d, 1w |
| Keep someone out for good | /ban Name perma reason (or no duration) |
| Stop chat spam | /mute Name / /unmute Name (ends when they reconnect) |
| Watch a suspect | /tp Name to move to them, /acreport Name, /acstats Name |
| Talk to everyone | /say Server restarts in 5 minutes |
| Fix uneven teams | /balance |
| Stop a broken round | /restart or /endround |
Commands find players by a case-insensitive name prefix and act on the first match, so type enough of the name to be unique. /acreport and /acstats also accept #id. Everything is in the commands reference.
Bans and unbanning
Bans are stored by IP address in bans.json (or [admin] bans_path) and survive restarts; timed bans remove themselves when they expire. There is no unban command. Stop the server, delete the entry, and start it again (the running server rewrites the file on every ban, so edits made while it runs can be lost).
{
"203.0.113.55": {
"name": "Griefer",
"reason": "team killing",
"until": 0
}
}until is a Unix timestamp; 0 means permanent. Banned players are refused at connect with the retail “banned” or “temporarily banned” message.
Player kick votes
Players can start the retail kick vote from the game UI. The server enforces the retail limits and sends the stock refusal message (spectator, self-kick, kicking the host, vote in progress, too soon, not enough players).
| Setting | Default | Meaning |
|---|---|---|
[lobby] votekick_cooldown_seconds | 300 | Wait before the same address can start another vote |
[lobby] votekick_cancelled_cooldown_seconds | 45 | Shorter wait after cancelling your own vote |
[lobby] votekick_min_team_players | 3 | Players (bots included) needed on the starter's team; 0 disables |
[game_rules] RULE_VOTES_REQUIRED_FOR_KICK | 50% | Share of votes needed: 25%, 50% or 75% |
Anti-cheat
The server is authoritative: it simulates movement itself and validates shots, tools and builds. On top of that come two layers.
1. Enforcement switches
| Switch | Default | What it enforces |
|---|---|---|
kick_on_protocol_violation | true | Immediate kick for packets the stock client never sends (NaN values, forged tools) |
enforce_shot_origin | false (log-only) | Shots/builds must start near the server's eye position (shot_origin_tolerance blocks) |
enforce_aim_direction | false (log-only) | Shot direction must match that frame's aim (aim_direction_tolerance_deg) |
enforce_input_starvation | false (log-only) | Airborne players fall and silent clients time out when input stops |
enforce_input_backlog | false (log-only) | Players with a long input queue (fake lag) are caught up |
enforce_block_interval | false (log-only) | Retail minimum of 0.1 s between one player's block builds |
2. Suspicion report
Every summary_interval_seconds (60) the server scores each human on statistical signals — headshot ratios, per-weapon accuracy against the population, aim snaps onto heads, reaction times, shotgun pellet-seed skew and repeated log-only violations — and appends flagged players to logs/anticheat.jsonl. It never kicks; it tells you whom to watch. Review in game with /acreport (top 5) and /acreport Name (reasons), and /acstats Name for raw counters. All thresholds are in the [[anticheat] reference](/guides/server/configuration#config-anticheat).
Griefing, AFK and names
Team griefing
Players earn grief points for hurting their own team: grief_team_damage_points (1) per 100 HP of teammate damage and grief_team_kill_points (3) per team kill — including a teammate killed by a landmine you set off. One point decays every grief_decay_seconds (60). Everything within grief_incident_seconds (3) is one incident capped at grief_incident_max_points (6), so a single accidental grenade cannot kick. At 5 points the player gets a private warning; at 10 they are kicked with the retail griefing reason. With the defaults, roughly three team kills within a few minutes lead to a kick. Destroying teammates' builds is not scored — digging and rebuilding is normal play.
[conduct]
grief_kick_enabled = true # false: warn only
grief_kick_points = 8.0 # kick sooner
grief_warn_points = 4.0
grief_exempt_admins = trueAFK
Only real input resets the idle clock (movement keys, fire, aim or a visible turn); the clock pauses while loading, dead, or between rounds. A warning comes at afk_warn_seconds (9 min), the kick at afk_kick_seconds (10 min; 0 disables). Spectators get afk_spectator_kick_seconds (30 min; 0 exempts them). Admins are exempt by default. These times are BattleSpades choices; retail only had the kick reason.
Names
Always on: names are normalised, invisible characters removed, and uniqueness is checked on a look-alike skeleton (case, accents, Cyrillic/Greek look-alikes, 0/O, 1/l/I, rn/m, vv/w). A joiner imitating an online player gets a ~N suffix; imitating a logged-in admin becomes Player~N; staff-like names (Server, Admin, Console, System, Moderator, BattleSpades, [Admin] tags…) and anything in [conduct] reserved_names become Player.
[conduct]
reserved_names = ["MyClan", "ServerOwner"]
announce_kicks = trueTeam balance
[teams] auto_balanceplaces joiners on the smaller team when their pick is alreadybalance_threshold(2) players larger, and refuses team switches that would unbalance./teamand the team menu follow the same rules, plus a 5-second change cooldown.balance_mid_matchrepairs drift during a match: after an imbalance lastsbalance_grace_seconds(5), a dead bot switches sides; afterbalance_bot_wait_seconds(10) a bot is retired and replaced; last, the most recently joined dead human moves — never a live player, carrier, VIP or last survivor, and nobody twice withinbalance_player_cooldown(600 s).- Zombie, the Tutorial and Map Creator sessions are never balanced;
/balanceforces a pass now with the same safety rules.
Other server-wide switches
- Music:
[audio] mode_start_music = trueplays an in-round music bed from round start. Retail rounds were silent (map ambience only) until the final minute; setfalsefor that. - Spectators:
RULE_ENABLE_SPECTATORSin[game_rules]. - Friendly fire / block damage:
[game] friendly_fire,build_damage. - Welcome message:
[server] join_greetingandmotd. - Plugins: trusted Python files in
plugins/; copyplugins/_example_plugin.pyto a name without the leading underscore to enable it. Plugins are not sandboxed — only install code you trust.
Common questions
How do I unban someone?+
Stop the server, remove their IP entry from bans.json, and start it again. Timed bans expire by themselves.
Can I have moderators with fewer rights?+
Not in the game server: anyone with the [admin] password has every admin command. The AoSPlay website has its own staff roles for the public listing, which are separate from in-game admin.
Will anti-cheat kick legitimate players?+
Only kick_on_protocol_violation kicks by default, and only for packets the stock client never produces. The other checks are log-only until you enable them, and the suspicion report never kicks.


