The bot that runs the department
Nearly everything SAPD does day to day passes through one bot. It keeps the roster level with the CIT forum, works out who is due a promotion, posts reports and requests to the forum for you, watches the map for high wanted criminals and calls for backup, moderates the server, and writes the log lines moderators paste onto the forum.
You can reach it from three places, and they are all the same thing underneath. Type a command in Discord. Type the same command in game chat. Or fill in a form on this website. Whichever you use, it lands in the same place.
Every arrow points both ways. That is the part worth understanding, and the next section is about what it means in practice.
Do it anywhere, see it everywhere
The site and the bot share one database, so neither has to tell the other anything. Something done on the website shows up in Discord. Something done in Discord shows up on the website. There is no delay and no syncing step, because there is nothing to sync between.
- You fill in the formHost, date, everyone who came, marks and comments.
- It is saved hereBefore anything is sent anywhere else.
- Posted to the forumWritten out as BBCode and posted for you.
- Logged in DiscordOne entry with a link straight to the post.
- Counted on profilesEveryone listed has it added to their record.
- You run the commandAnd give your CIT account name.
- The link is savedYour Discord account is tied to your member record.
- Your profile updatesThe site now knows the two are the same person.
- Your face appearsYour Discord picture shows on the roster and profile.
It works the same way for the rest of it.
| What you do | Where | What happens elsewhere |
|---|---|---|
| File a training report | Website | Posted to the forum, logged in Discord, added to every participant's record |
| Request a vacation | Discord | Posted to the forum, stored here, shown on your profile |
| Apply to join | Either | Goes to the voting channel, and into the review queue on the site |
| Approve an application | Discord | Recorded here, the applicant is messaged, the site shows the decision |
| Request a promotion | Either | Leadership get the buttons in Discord, the request is on the dashboard here |
| Ask for a unit number | Website | Posted to the forum, and the number is held so nobody else takes it |
| Get promoted on the forum | In game | The roster here moves you, and your promotion clock starts again |
| Lock a staff account | Discord | That login stops working on the site immediately |
Every command
The bot answers on a plain ! prefix. Nothing is hidden behind a slash menu, which is what lets the same commands work from game chat.
Everything below works in Discord, and almost all of it works from game chat as well. Only two kinds do not. role means it needs a rank, and game chat carries no ranks. you means the bot has to know which account is yours, and a line of game chat does not say. Everything unmarked works in both.
Using it without leaving the game
Game chat is mirrored into Discord already. The bot reads that mirror, and when a line turns out to be a command it runs it and sends the answer back the same way. You never alt tab.
- You type in game!backup, or !play, or anything else.
- The line is mirroredGame chat appears in Discord as it is typed.
- The bot spots a commandIt reads your name and what you asked for.
- It runs as normalThe same code that runs it in Discord.
- You get the answerBack in game chat, in plain text.
Answers are cleaned up first
Bold, emoji and channel links all render as junk in game chat, so they are stripped out and the reply is folded onto one line before it goes back.
Names get the same treatment in the other direction. Some relay bots wrap your name in bold, which would otherwise end up printed in the embed.
Tagging people from in game
Writing @Name in game pings that person's Discord. It matches on roster
name or CIT account name, and falls back to roles, so @SAPD Officer
pings the role.
Each person is pinged at most once every ten seconds, and no more than three per line, so it cannot be turned into spam.
Music is the one that needed thinking about. An in game name does not tell the bot which Discord account you are, so it cannot look at which voice channel you are in. Instead it stays in the channel it is already in, and if it is not in one it joins the busiest channel with people in it.
Backup calls, and criminals nobody spotted
The bot watches a live feed of wanted players every minute. That is what fills in !backup for you, and it is also watched on its own.
When you call for backup
You type !backup with an optional message. The call goes to the field
channel wherever you typed it, and carries the whole picture without you having to
describe it.
- Who is asking, and what they said
- How bad it is, from the highest wanted level in game
- Every wanted player, worst first
- How many criminals, and how many cops are online
- How fresh the information is
When nobody calls
The moment somebody hits five or six stars, the bot raises it by itself and pings the backup role. Nobody has to be watching for it.
You get told once per criminal. Going from five stars to six does not ping again, and somebody who leaves and comes straight back will not either. Alerts clear themselves after fifteen minutes, because old information about where a criminal was is worse than none.
One small thing that matters more than it sounds. The line above every alert says the whole situation in plain words, with no formatting at all: who is asking, how many criminals, how many cops, and the names of the worst ones. On a phone that line is the entire notification. It is what decides whether somebody logs in.
The log lines moderators paste
Every group action taken in game gets announced in chat: promotions, demotions, kicks, warnings, rewards, joins and leaves. All of it then has to be written onto the forum log by hand, worded the right way, with the right date.
The bot does that writing. It reads each announcement, tidies the names by stripping rank prefixes, group tags and unit numbers, and posts it to the moderator channel as a clean entry with the mod role pinged.
- Something happens in gameSomeone is promoted, warned, kicked or rewarded.
- It is announced in chatAs a plain line of text, names and tags and all.
- The bot reads itPulls out who, what, why, and by whom.
- Moderators get itA tidy entry, with the forum line already written out.
The last part is the useful part. Every one of those entries ends with a ready made line for the forum log, already worded and already dated. It gets copied across as it is.
| Event | What the entry carries |
|---|---|
| Promotion | Who was promoted, from which rank to which, who signed it off, the account, the reason and the date |
| Demotion | The same, the other way |
| Kick | Who was removed, the rank they held, who did it and why |
| Warning | Who was warned, by whom, the reason, and the percentage added |
| Reward | Who was rewarded, by whom, the reason and the percentage |
| Join | Who joined, and the date |
| Leave | Who left, and the date |
Applications
Submitted, accepted or denied in game, it reaches the notification channel with the badge holders who vote already pinged.
Rank aware mutes
You cannot mute somebody at your own level or above it. The Chief and Head Leader sit outside the check.
Server log
Messages, joins, leaves, bans, timeouts, role and channel changes, voice moves. Each one names who did it and shows what changed, with buttons to jump straight there.
Login greetings
Every SAPD login is announced. The bot welcomes members back by name and clears the greeting a minute later so the channel stays readable.
Website threats
Suspicious traffic to the site raises an alert in Discord with ban and unban buttons on it, so it is handled where it is seen.
Unverified members
Somebody posting without a linked account gets pointed at verification once, with a wait before it happens again.
Keeping the roster true
The forum is the authority on who is in SAPD and at what rank. Nothing here changes that. Every ten minutes the bot re-reads it and brings this site back in line.
- Read the changelogEvery promotion, kick, warning, vacation and name change since last time.
- Apply each oneRanks move, statuses change, people who left are marked.
- Read the rosterRank by rank, plus each member's account name and playtime.
- The site followsRoster, profiles and promotion clocks all read from it.
The changelog is read before the roster, and the order is not arbitrary. If somebody changed their name, that has to be picked up first. Otherwise the roster step looks for a member it has known for two years, fails to find them under the new name, and adds them a second time.
Two lighter jobs run alongside. Every five minutes the bot checks who is in game and matches them to the roster. Every five minutes it also reads the CIT live boards, and says something in Discord when SAPD moves up or down against the other law groups.
Nobody pastes BBCode any more
Training reports, patrol reports, vacations, promotions, tests, badges and unit numbers all end up as a post on the CIT forum. You fill in a form and the bot writes the post.
- Your form is savedFirst, before anything is sent out. It cannot be lost after this point.
- The post is writtenNames become links to profiles here, the report number links back to the full report.
- It goes to the forumPosted under the department account, in the right topic.
- You get the linkStraight to your post, not to page forty of a thread.
If the forum is down, you are told so plainly and given a Retry button, and only then does the BBCode appear so you can paste it yourself. When it worked there is nothing to copy, so you just get the link.
How promotions are worked out
Every rank up to Inspector has a minimum time to serve and a set of patrols and trainings to do. The bot works out where you are against them and !checkpromotion tells you what is left.
Chief Inspector and above is staff and leadership, and those seats are the Chief's to give. Working out a percentage for them only ever produced a number nobody was going to act on, and left a Superintendent queued behind a Constable.
| Rank | Promotes to | Min days | What you need to have done |
|---|---|---|---|
| Trial | Recruit | 7 | 2 patrols |
| Recruit | Constable | 14 | 2 patrols, 1 training |
| Constable | Officer | 14 | 3 patrols, 1 training |
| Officer | Station Officer | 14 | 5 patrols, 3 trainings |
| Station Officer | Sergeant | 30 | 10 patrols, 1 training hosted, 1 patrol hosted |
| Sergeant | Staff Sergeant | 40 | 12 patrols, 2 trainings hosted, 2 patrols hosted |
| Staff Sergeant | Inspector | 50 | 5 trainings hosted, 5 patrols hosted |
| Inspector | Chief Inspector | 60 | 8 trainings hosted, 8 patrols hosted |
Time served and activity are not the whole of it. The marks you were given in the reports you appear in count too, and they count for more the higher you go. At Trial they barely register. By Inspector they are about a third of the picture.
- The bot names youOnce a day it posts whoever has newly qualified. Nobody is named twice for the same promotion.
- A request goes inYou press the button, or staff file it for you.
- Leadership decideApprove, deny or hold, each with a reason that gets kept.
- The forum makes it realIt is posted, and when it reaches the changelog your rank moves here too.
Recruitment
Joining works the same whether you start on the website or in Discord. It used to be a second bot with its own database, which meant two records of the same application that slowly stopped agreeing. Now there is one.
- Three short formsOne at a time, so there is no wall of questions to lose.
- It reaches the channelWith Approve and Deny for the members who hold forum rights.
- A decision with a reasonWhich is stored, and sent to you.
- Nothing is overwrittenThe record keeps every step it went through, not just the ending.
The rest of what it runs
Music
A full player with buttons, a queue, loop, shuffle and seek. It reads several sources and switches to another when one refuses to play.
The AI channel
!ask follows a conversation for an hour so you can ask follow ups.
!image draws things and works anywhere. !mode switches
between a straight answer and a sarcastic one.
Keyword reactions
Staff teach the bot a word, a reply and the emoji to react with. Only one fires per message, and several channels are left out.
Role centre
One panel. Some roles you take yourself, the rest go to leadership. Both the request and the decision are logged with everyone named.
Birthdays
Saved once and announced on the day. The month's list and whose is next are a command away.
Events
An event made through the bot gets a countdown page on this site and a post in Discord linking to it.
Forum backup
Every hour the department's forum posts are copied and kept, with a fuller copy overnight. If a post is ever wiped, what is needed to rebuild it is already saved.
Programming lessons
A lesson series with tasks, homework and a leaderboard, posted into its own channel on a timer.
Pictures on the roster
Discord profile pictures are kept against member records and refreshed on a schedule, so the roster shows faces without asking Discord every time somebody opens it.
What it does without being asked
| How often | What happens |
|---|---|
| Every minute | Checks for five and six star criminals, and calls the backup role if there are any |
| Every 5 minutes | Reads who is in game and matches them to the roster |
| Every 5 minutes | Reads the CIT live boards, and says something when SAPD moves |
| Every 5 minutes | Works out everyone's time in rank again |
| Every 10 minutes | Re-reads the forum changelog and roster |
| Every 30 minutes | Recounts patrols and trainings per member |
| Every hour | Backs up the department's forum posts |
| Every day at 18:00 | Posts whoever has newly qualified for promotion |
| Every night at 02:00 | Locks staff website accounts nobody has used |
| Every night at 03:30 | Takes the full forum backup |