BasilBot Commands

Chat commands for Basil's bot account, usable in public channels, match channels, or DM to BasilBot.

The default prefix is ! (server admins can change it via Basil:Bot:CommandPrefix in appsettings.json). Direct DM to BasilBot is an exception: the prefix is optional there. Typing help or !help in DM are handled identically, since every DM sent to BasilBot is already treated as a command.

Command listings in !help/!mp help are auto-generated by BasilBot from a single source in code, not handwritten strings, so every command below always matches what the bot itself reports. !help lists only general commands (plus make/join/in/ mp help, which work outside match scope); !mp help lists the match-scoped !mp subcommands separately.

Regular Commands

Usable anywhere (public channel, match channel, DM), no special permissions required.

Command Syntax Description
Help !help Lists the general commands BasilBot supports (auto-generated from code).
Roll !roll [max] Random number in 0..max inclusive. max defaults to 100; negative, zero, or unparseable values also fall back to 100. Max allowed value 2147483647.
Where !where <username> Shows the country of username (looked up in the server's user database, works even if the player is offline).
FAQ !faq <entry> / !faq list Prints a FAQ file prepared by the server admin, one message per line; list enumerates every available entry. Entry names may contain spaces.
!help
→ BasilBot: "!roll [max] - roll a random number from 0 to max (default 100)"
→ BasilBot: "!where <username> - show a player's country"
→ BasilBot: "!faq <entry>|list - print a FAQ entry, or list every entry"
→ BasilBot: "!mp make <name> - create a tournament room from anywhere, scoping you to it"
→ BasilBot: "!mp makeprivate <name> - create a private tournament room from anywhere, scoping you to it
   (hidden from lobby, invite-only)"
→ BasilBot: "!mp join <id> [password] - join a match by id (private rooms need an invite from the
   host/a referee)"
→ BasilBot: "!mp in [match_id] - scope to a live match (DM only - needs referee permission there)"
→ BasilBot: "!mp help - list multiplayer subcommands (usable while scoped to a match)"

!roll
→ BasilBot: "PlayerOne rolls 42 point(s)"

!roll 50
→ BasilBot: "PlayerOne rolls 17 point(s)"

!where PlayerOne
→ BasilBot: "PlayerOne is in Vietnam"
   (unregistered username → "GhostUser is not registered.")

!faq list
→ BasilBot: "Available FAQ entries: rules, schedule"
   (no entries yet → "No FAQ entries available.")

!faq rules
→ BasilBot sends each line of rules.txt as a separate message
   (entry not found → "No FAQ entry found for 'rules'.")

Multiplayer Commands

Controlling matches: creating rooms, changing maps, managing players, starting matches.

Referee, Host, and Creator

Referee, host, and creator are three separate roles. Neither referee nor host automatically includes the other, but the creator always counts as a referee too.

Referee Host Creator
Who / what can they do? Granted via !mp addref, authorized to use !mp commands on that match. Physically present in the room, can change settings directly in the client (not via chat). Whoever created the room. Holds full !mp authority for the room's lifetime regardless of referee status, and is the only one who can run !mp addref/!mp removeref.
Must be in the room? No. Can control remotely via !mp in <match_id>. Yes. No.
Default assignee? The room creator. The room creator. — (set once, at creation, and never reassigned)
Can it be lost? Yes, via !mp removeref (except the creator, see below). Yes, by leaving the slot or via !mp host/!mp clearhost. Never, for the room's whole lifetime.

The room creator is always both host and referee from the moment of creation, regardless of whether the room was created via !mp make or the in-game Create Room button. Unlike an ordinary referee, the creator's referee status can never be revoked — !mp removeref against the creator is always rejected, whether run by chat or through the equivalent HTTP management API — and only the creator can run !mp addref/!mp removeref at all.

Every !mp subcommand except help/make/join/in requires you to be a referee of the currently targeted match. Lacking permission (or using an unknown subcommand) makes BasilBot reply with an error instead of staying silent. The error is posted publicly only in the match's own channel; anywhere else it is DM'd back to you, so a shared channel like #osu or #lobby never gets spammed with a failed command.

Which match are you currently scoped to? By default, the match linked to the chat channel you're in. Use !mp in <match_id> to control a match without being in its room — DM only, refused (with a DM'd error) if run in any channel. Once set, this scope always takes priority over the current channel until changed. A scoped subcommand run anywhere except the match's own channel — a DM, or any other channel like #osu — always replies privately (DM'd back to you, prefixed with [#id], with an unprefixed copy mirrored into the room) rather than posting into whatever unrelated channel you happened to type it in.

Rooms created via !mp make do not auto-close when empty. Only !mp close ends them. Rooms created normally in-game still auto-close when empty, regardless of remaining referees.

Chaining multiple commands

Referees can chain multiple !mp subcommands in one message (not make/join/in/help, nor !roll/!where/!faq):

Operator Meaning
; Next command always runs, regardless of whether the previous one succeeded.
&& Next command runs only if the immediately preceding command succeeded.
!mp lock; !mp start 30
→ BasilBot: "Locked the match"
→ BasilBot: "Match starts in 30 seconds"

!mp map 123 && !mp start
   (countdown only starts if the map change succeeds)

To use ;/&& literally inside a parameter, wrap it in quotes: !mp name "Round 1; Group A". Within quoted strings, use \" for a literal quote and \\ for a literal backslash.

If any segment of a chain is not a valid !mp subcommand, BasilBot rejects the entire chain: no segment runs.

1. Create, join & target a match

Command Syntax Description
Make !mp make <room name> Creates a new match. Usable anywhere, including DM to BasilBot.
Join !mp join <id> [password] Join a public match by the id BasilBot replied with when it was created. Private rooms require an invite.
In !mp in [match_id] Switches scope to another match without physically being in it.
Private !mp private [0|1] Show or set the room's private status. Referee only.
Make private !mp makeprivate <room name> Same as !mp make, but the new match starts hidden from the lobby and invite-only.

You are automatically placed in slot 0 as host and added as a referee on creation. BasilBot replies with the match ID (#<id>). This is the id used by !mp in and by the Basil API's match routes. No name given defaults to "<your name>'s match".

!mp make Group A: Team Alpha vs Team Beta
→ BasilBot: "Created the match #42 Group A: Team Alpha vs Team Beta. You are now scoped to this match, and
   added as a referee."

!mp makeprivate Staff Test Room
→ BasilBot: "Created the match #43 Staff Test Room (private). You are now scoped to this match, and added
   as a referee."

!mp in 42
→ BasilBot: "Now targeting match #42 Group A: Team Alpha vs Team Beta."
   (not a referee → "You're not a referee of match #42.")
   (id doesn't exist → "No active match with id #42.")

!mp join 5
→ BasilBot: "Joined match #5 test match"
   (private room → "Cannot join match #5, the room is private. Ask a referee for an invite.")

!mp private 1
→ BasilBot: "The match is now private. It will be hidden from the lobby."

2. Room configuration

Command Syntax Description
Settings !mp settings Shows room name, map, team type, win condition, mods, and slot list.
Lock / Unlock !mp lock / !mp unlock Prevents/allows new players joining.
Size !mp size <1-16> Sets the number of available slots.
Move !mp move <name> <slot 1-16> Moves a player to another slot.
Host / Clear host !mp host <name> / !mp clearhost Transfers or clears the host.
Name !mp name <new name> Renames the room (truncated at 50 characters).
Password !mp password [password] Sets a room password; omit to clear it.
Invite !mp invite <name> Sends an invite to an online player.
Team !mp team <name> <red|blue> Assigns a team to a player.
Map !mp map <beatmap id> Changes the selected map, unreadies all players.
Mods !mp mods <mods> Sets common mods for the entire match.
Set !mp set <teammode 0-3> [scoremode 0-3] [size 1-16] Sets team mode, win condition, and size in one command.
!mp settings
→ BasilBot: "Room name: Group A: Team Alpha vs Team Beta (#42)"
→ BasilBot: "Beatmap: 111222 Camellia - Frontier [Insane]"
→ BasilBot: "Team mode: TeamVs, Win condition: ScoreV2"
→ BasilBot: "Active mods: DoubleTime, Freemod"
→ BasilBot: "Players: 2"
→ BasilBot: "Slot 1  Not Ready 7 PlayerOne       [Host]"
→ BasilBot: "Slot 4  Not Ready 12 PlayerTwo       [NoFail]"
Basil has no online match-history or public profile pages, so !mp settings shows raw numbers instead of links: #42 for the match, raw user ids (7, 12) for players. Look up a username from an id via the Basil API's GET /users/{id} (admin-key gated) or the tournament match report's live.slots[].userId field.
!mp map 111222
→ BasilBot: "Changed beatmap to Camellia - Frontier"
   (id not in local DB → "No beatmap with id 111222 found locally.")
!mp map only accepts a beatmap id. Unlike the original osu! Bancho, it does not also accept a game-mode parameter.

!mp mods has 3 usage modes:

!mp mods HR DT HD NF
→ BasilBot: "Enabled NoFail, Hidden, HardRock, DoubleTime, disabled FreeMod"

!mp mods Freemod
→ BasilBot: "Enabled FreeMod"
   (speed mods DT/HT/NC stay at match level; remaining mods become individual host mods)

!mp mods None
→ BasilBot: "Disabled NoFail, Hidden, HardRock, DoubleTime, disabled FreeMod"
Supported mod codes: NF, EZ, HD, HR, SD, DT, RX, HT, NC, FL, SO, AP, PF. Unrecognized codes are silently ignored.

!mp set: only <teammode> is required.

!mp set 2 3 16
→ BasilBot: "Changed match settings to 16 slots, TeamVs, ScoreV2"

!mp set 0
→ BasilBot: "Changed match settings to HeadToHead, Score"
Team mode: 0 HeadToHead, 1 TagCoop, 2 TeamVs, 3 TagTeamVs. Score mode: 0 Score, 1 Accuracy, 2 Combo, 3 ScoreV2. No pp option, since this server never uses pp as a win condition.

3. Player & referee management

Command Syntax Description
Add / Remove referee !mp addref <name> / !mp removeref <name> Creator only — an ordinary referee cannot run either subcommand. A match must always keep at least one referee: removing the last one is rejected, and the creator can never be removed at all.
List referees !mp listrefs Lists the match's referees.
Kick !mp kick <name> Removes a player from the room (rejoin allowed).
Ban / Unban !mp ban <name> / !mp unban <name> Kicks + permanently blocks rejoin, or lifts that block.
Ban list !mp banlist Lists currently banned players for this match.

Kick and ban can never target a referee (the creator included) — remove referee status first with !mp removeref. kick requires the target to actually be present in the room (seated, or an IRC session in its chat) and does not block rejoining. ban has no such presence requirement — it can be issued by name/id against anyone, online or not, evicts any live presence they currently have, and blocks every future join attempt until !mp unban.

!mp addref RefereeName
→ BasilBot: "Added RefereeName to the match referees"

!mp kick TrollPlayer
→ BasilBot: "Kicked TrollPlayer from the match"

!mp ban CheaterPlayer
→ BasilBot: "Banned CheaterPlayer from the match"

4. Match control

Command Syntax Description
Start !mp start [seconds] Starts immediately, or counts down then auto-starts if seconds is given.
Timer !mp timer [seconds] Countdown like start but does not auto-start (default 30s).
Abort timer !mp aborttimer Cancels a running countdown (from either start or timer).
Abort !mp abort Aborts the in-progress match, resets ready/loaded state, closes the current round.
Close !mp close Closes the match immediately, kicks everyone, records the end time.
!mp start 30
→ BasilBot: "Match starts in 30 seconds"
   (then broadcasts to match chat: "Queued the match to start in 30 seconds" → "Match starts in 10 seconds"
    → "Match starts in 5 seconds" → ... → "Good luck, have fun!")

!mp abort
→ BasilBot: "Aborted the match"
   (not in progress → "Match is not in progress.")

!mp close
→ BasilBot: "Closed the match"

Commands not implemented here (mappool tooling, the scrim engine, !mp force, personal chat commands, and others) are out of this server's scope by design. See the project's docs/for-developers/working-scopes.md for the full rationale.