How commands work
Challenger Bot doesn't fire on every single chat message. Viewers collectively
unlock a challenge by hitting a message threshold — 10 messages by default,
configurable per streamer in config.toml. Once unlocked, the
challenge runs for its duration (30 seconds by default), then the bot enforces a
cooldown (60 seconds by default) before that same challenge can trigger again.
Individual commands can override any of these three numbers — !AltTab,
for example, needs 30 messages instead of the usual 10 before it fires, since
it's disruptive enough to warrant a higher bar.
The threshold counter is shared across the whole chat, not per viewer, so a busy stream with dozens of active chatters unlocks challenges much faster than a quiet one — which is by design, since the bot is meant to reward and reflect how lively the chat actually is at any given moment. Once a challenge is unlocked and running, it occupies the "active challenge" slot for its full duration; no second challenge can start until the first one finishes and its own cooldown has cleared, which keeps the streamer's screen and input from being hit by two effects layered on top of each other.
Keyboard and mouse commands
These are the core of the bot and the reason it needs AutoHotkey installed —
several of them are literally AutoHotkey scripts the bot triggers on your
machine (WtoS.ahk, AtoD.ahk, and similar), not raw
key-press injection from Python.
Challenger Bot is Windows-only for exactly this reason: it leans on
AutoHotkey to remap keys at the OS level, on win32api to talk to
the display driver, and on pynput for the pure key-spam commands
like !Jump and !DropIt that don't need a script file
at all. When a challenge with an AHK component ends, the bot's process
manager kills the running AutoHotkey.exe instance to make sure
the remap doesn't outlive its configured duration — so a chaotic
!WtoS run can't accidentally strand a streamer with permanently
swapped movement keys if something goes wrong mid-stream.
| Command | What it does | Duration |
|---|---|---|
!AtoD | Swaps the A and D keys | 45s |
!WtoS | Swaps the W and S keys | 45s |
!MouseFlip | Flips mouse-movement axis | 45s |
!MouseToWS | Maps mouse movement onto W/S keys | 30s |
!Random | Shuffles which keys do what, with a sound cue | 30s (default) |
!AltTab | Spams Alt-Tab to yank focus off the game | 30s (default), 30-message threshold |
!Jump | Spams the jump key | 30s (default) |
!DropIt | Spams the 'G' key (drop-item in most games) | 30s (default) |
Display commands
There's only one display command today, and it earns its own category rather
than living under keyboard/mouse because it doesn't touch input at all — it
calls into win32api to flip the physical display orientation.
It's disorienting in a way key-remapping isn't: the streamer's whole point of
view flips upside down while everything else about the game keeps running
normally, which is part of why it's popular as a one-off "gotcha" moment
rather than something chat spams back-to-back.
| Command | What it does | Duration |
|---|---|---|
!Rotate | Rotates the streamer's screen 180°, then back | 30s (default) |
Overlay commands
Overlay commands work differently from the keyboard and display commands above: instead of remapping input or flipping the physical screen, they draw a borderless window on top of whatever the streamer is running, using wxPython to build the overlay itself. That means overlays don't touch the game process or its input handling at all — they sit purely on the visual layer, which is part of why they tend to be the safer, more configurable option for streamers who are nervous about anything that resembles input injection.
| Command | What it does | Duration |
|---|---|---|
!Gray | Desaturates the screen with a gray/blur overlay | 30s (default) |
!Black | Drops a black square overlay over part of the screen | 30s (default) |
!Tunel | Tunnel-vision overlay that closes in on the center | 40s |
Voice commands
!Word is the odd one out — it doesn't run for a fixed duration like
the others. A viewer supplies a word in chat, the bot speaks it out loud via
text-to-speech, then changes VoiceMacro's active trigger word to that same word
for the rest of the stream (until the next !Word). This is the only
command that touches voice output; everything else here is visual or input-based.
Under the hood, the text-to-speech step runs through gTTS to render a short
announcement — "New word is! <word>", not just the bare word by itself —
to an MP3 file, plays it back through the streamer's audio output via
playsound3, then deletes the temporary file once playback
finishes, so nothing lingers on disk between calls. The VoiceMacro handoff runs
as a separate four-step sequence right after: the bot kills any running
VoiceMacro.exe process, copies a Copy.xml template to
a temporary file and swaps its FirstWord placeholder for the new
word (keeping a .bak backup of that intermediate file), copies the
result over VoiceMacro's live VoiceMacroData.xml, then relaunches
VoiceMacro.exe from the configured path. Both the VoiceMacro
executable path and its config directory come from
VOICE_MACRO_PATH and VOICE_MACRO_CONFIG_DIR —
optional .env settings a streamer can add by hand, not fields the
setup wizard's UI currently prompts for. Leave either one unset and
!Word still speaks the word aloud; it just skips the VoiceMacro
handoff and logs that the path isn't configured, rather than failing the
command outright.
Command cooldowns and rate limits
Every command shares the same 60-second cooldown floor by default — once a
challenge fires, that specific command can't fire again for 60 seconds even if
chat immediately re-hits the message threshold. This stops one command from
dominating a stream. Streamers can raise or lower any of the three numbers
(threshold, duration, cooldown) per command in config.toml; the
values above are what ships by default.
Cooldowns are tracked independently per command, not globally, so !Jump
being on cooldown doesn't block !Gray or !Rotate from
triggering in the meantime — chat just needs to build up the message threshold for
whichever command it wants next. In practice this means a lively chat can cycle
through several different effects back-to-back over the course of a few minutes,
while any single command settles into a rhythm dictated by its own cooldown.
Streamer dashboard controls
Command thresholds, durations and cooldowns aren't edited by chat commands — they're configured through Challenger Bot's own setup wizard and dashboard, which opens in your browser when you run the app. See the setup guide for how to reach it.
The dashboard itself is a small local web app the bot spins up alongside the Twitch connection — a first run walks the streamer through a four-step wizard before the bot ever starts listening to chat. Step one, Activate, starts a free 7-day trial or accepts a paid license key. Step two, Connect Twitch, hands off to Twitch's own device-code flow: the wizard shows a short code and a verification link, the streamer opens that link and enters the code on Twitch's own site in another tab, and the dashboard quietly polls in the background until Twitch reports the authorization as complete — there's no form asking the streamer to paste in a Twitch application's client ID or secret by hand. Step three, Your Channel, asks which channel login the bot should join. Step four, Ready to Launch, is a single button that starts the bot once the three steps before it are done. Once that's done, the same dashboard is where thresholds, durations and cooldowns for every command in this reference get tuned per-streamer, live stats about top chatters and recently triggered challenges are shown, and the bot can be restarted without touching a config file by hand. None of that configuration surface is exposed to chat itself — viewers can trigger commands, but only the streamer, from their own dashboard, decides how easy or hard each one is to unlock.