-
-
Notifications
You must be signed in to change notification settings - Fork 3
Testing Guide
A structured reference for verifying correct plugin behaviour across every match phase, configuration permutation, and edge case. Work through sections at your own pace — each section is self-contained.
- Start small. Sections 1–3 cover the minimum setup and sanity checks. Complete them before any other section.
- Work top-to-bottom within each section. Each numbered step depends on the ones above it.
- Use the checkbox format. Copy the section you are testing and tick boxes as you go.
-
Console shortcut — add bots fast:
bot_add_ct; bot_add_ct; bot_add_ct; bot_add_ct; bot_add_ct; bot_add_t; bot_add_t; bot_add_t; bot_add_t; bot_add_t - Recommended baseline config (override per section as noted):
Goal: Confirm the plugin loads without errors and warmup begins.
- Start CS2 server with the plugin installed.
- Console shows no
[ERROR]or[CRITICAL]lines during load. -
DetailedLogginglines appear if enabled (LoadWarmupConfig,Starting warmup). -
warmup.cfgexecutes (confirm withmp_warmuptimebeing unlimited viamp_warmuptimein console). -
staging_overrides.cfgexecutes whenTestMode: true;production_overrides.cfgexecutes whenTestMode: false. - Plugin state =
Warmup(check via log or API if available). - Periodic ready-status announcements start after
ChatAnnouncementTimers.PlayersReadyStatusseconds. - Command reminder announcements start after
ChatAnnouncementTimers.CommandRemindersseconds. - If
ShowReadyStatusInCenterHtml: true— center HTML overlay appears and updates each second.
Goal: Verify the ready system, player joining, and auto-balance.
- Player types
!ready(or alias!r) → chat confirms they are ready. Scoreboard prefix updates ifShowReadyStatusInScoreboard: true. - Same player types
!readyagain → error "already ready" (no duplicate in list). - Player types
!unready(or aliases!u,!ur) → chat confirms unready. Scoreboard prefix removed. - Player types
!unreadywhen already unready → error "already unready". - CenterHTML overlay (if enabled) updates within 1 second to reflect new count.
With RequireAllConnectedPlayersToBeReady: false:
- With
MinimumReadyPlayers: 4, ready exactly 4 players → voting / next phase triggers immediately. - With 3 ready players, count stays at 3/4 — no phase transition.
- Admin command
!forceready(!fr) marks all connected players ready and triggers transition. - Admin command
!forceunready(!fur) unmarks everyone.
With RequireAllConnectedPlayersToBeReady: true:
- Even with minimum count met, transition does not happen until every connected player is ready.
- A new player joining resets the gate (they must also ready up).
- Player joins → automatically placed in spectator first (after 2-second delay).
- Then assigned to the team with fewer players (CT or T, alternating).
- Player is respawned on assignment.
- If
MoveOverflowPlayersToSpec: trueand both teams haveMinimumReadyPlayers / 2players, additional joiners stay in spectator. - Joining player can
!readyand be counted.
- With 2 CT and 2 T players, next joiner alternates to whichever team the previous auto-join did NOT go to (CT → T → CT …).
-
!maps(!maplist) prints the voteable map pool. -
!maplist_all(!allmaps,!maps_all) prints all configured maps regardless ofCanBeVoted.
Goal: Confirm !captain sets captains before team picking starts.
- Admin
!captain PlayerName t→ chat confirms "PlayerName set as T captain".captainTfield populated. - Admin
!captain PlayerName ct→ confirms "PlayerName set as CT captain".captainCtfield populated. - Setting captain for a player not on the server returns an error (invalid player).
- Captains set this way survive through the MapChosen → TeamPicking transition (they are inserted into picked lists on phase start).
Goal: Verify the map vote menu, vote registration, revote, and winner selection.
- Phase transition shows
announcement.state_changed.map_votingchat message. - Each connected non-bot player receives the map voting menu.
- Menu contains only maps with
CanBeVoted: truethat are not excluded byDisallowVotePreviousMaps. - Map order in menu is randomised on each vote start.
- Bots do not receive the menu (they are skipped).
- Player clicks a map → chat shows "[Player] voted for [Map] [1 votes]".
- Second player votes for the same map → "[Map] [2 votes]".
- Player uses
!revote(alias!rv) → previous vote removed, menu reopened. - After revote, player picks a different map → vote transferred correctly.
- Player attempts
!revoteoutside MapVoting state → error "invalid state".
- Vote timer expires (
DefaultVoteTimeSeconds) → map with most votes announced. - All players close their menu on announcement.
- Map load begins (state transitions to
MapLoading). - "Map loading" announcement fires every 15 seconds until map loads.
- Tie scenario: When two maps share the highest vote count, one is selected (random or first-found is acceptable — just confirm no crash).
- Zero votes: Nobody votes → a random eligible map is selected, no crash.
- Play two matches ending on
de_mirageandde_dust2(withDisallowVotePreviousMaps: 2). - Third vote: menu does not include
de_mirageorde_dust2. - Fourth vote:
de_miragereappears (oldest entry rolls off the history list). - With
DisallowVotePreviousMaps: 0→ all maps always available;playedMapscleared to prevent out-of-range errors.
Goal: Verify the second ready phase after the map loads.
- After map load, state =
MapChosen. Warmup config executes again. - Ready list is empty (previous warmup ready list cleared on reset).
- Players must
!readyagain to start team picking. -
MinimumReadyPlayersandRequireAllConnectedPlayersToBeReadyrules apply identically to Warmup. - CaptainSelectionDelaySeconds countdown fires: "Selecting captains in X seconds" messages appear.
- After delay, captains are announced (randomly from ready list unless pre-set or volunteers exist).
- If only
AllowVolunteerCaptains: truecaptains exist, they are used. Otherwise, random selection.
Goal: Validate the pick menu flow, alternation, and edge cases.
Config: SkipTeamPicking: false, DisableCaptains: false
-
teampick.cfgexecutes. - Game pauses.
- Players are moved to spectator or their designated team side (
MovePlayersToDesignatedTeamsPrePick). - Team names updated to captain names (e.g.,
team_Alice,team_Bob). - One captain receives the pick menu first (random CT or T to start).
- Captain selects a player → player added to that captain's picked list, menu reopens for opponent captain.
- Picks alternate CT ↔ T after each selection.
- A captain cannot pick the opposing captain (they are already in the other picked list).
- When all non-captain players are distributed, Knife Round starts automatically.
- If
MoveOverflowPlayersToSpec: trueand team is full (MinimumReadyPlayers / 2per side), extra players go to spectator.
- CT captain disconnects → a replacement captain is selected from remaining picked CT players and picking restarts.
- T captain disconnects → same for T side.
- Both captains disconnect simultaneously → logs errors, attempts reset if no players remain for captain.
- Player in the unpicked pool disconnects → removed from
pickedCtPlayers/pickedTPlayers, remaining picks continue normally.
Goal: Confirm knife-only config, winner detection, and side-selection prompt.
-
knife_round.cfgexecutes (knife only, no C4). -
playingCtPlayersandplayingTPlayerspopulated frompickedCtPlayers/pickedTPlayers. - Pre-match announcement timers stopped.
- Scoreboard "ready" clan-tags removed (if
ShowReadyStatusInScoreboard: true). - Any open pick menus for captains are closed.
- If
KickPlayersNotInMatch: true→ spectating non-participants are kicked.
- Confirm C4 is not given to T side (check
mp_give_player_c4 0). - Players can only use knives; rifles/pistols not spawned.
- Round ends by team elimination.
- Winning team's captain receives the Stay / Switch menu.
- All players see "CT/T team won the knife round" announcement.
- All players see "Waiting for [captain] to pick a side" announcement.
- Bot captain: automatically selects "Switch" (hardcoded fallback).
- Captain clicks Stay →
!stay(!st) confirmed, match starts with current sides. - Captain clicks Switch →
!switch(!swap) confirmed, teams swap sides, match starts. - Captain disconnects during side selection →
StayStartingSidesfires automatically (no hang).
- Winning team all receive Stay / Switch menu.
- "Team vote started" announcement shown to all.
- Players vote; majority wins (tied vote resolved by first-to-pass logic).
- 30-second timer auto-resolves if not all players vote.
- Each player's vote is recorded via
sideVotesdict; duplicate vote attempt ignored.
Goal: Validate in-match behaviour, halftime, and end-of-match reset.
-
match_start.cfgexecutes. -
announcement.state_changed.matchmessage shown to all. - All playing players moved to designated CT / T teams.
- Pre-match announcement timers stopped.
- Scoreboard clan tags cleared.
- Teammate colours assigned (no duplicates within a team).
- Current map added to
playedMapshistory. - If
KickPlayersNotInMatch: true→ spectating non-participants kicked.
- At halftime announcement,
isMovingPlayersToTeamsset to true. - On first round start after halftime,
playingCtPlayers↔playingTPlayersswap. - After swap,
isMovingPlayersToTeamsset back to false. - Team names update correctly after swap (check scoreboard).
- Match ends normally (one team wins 13 rounds,
EventCsWinPanelMatchfires). - Win panel shown for ~10 seconds.
- Plugin resets to Warmup after 10-second delay.
- All variable lists cleared (ready players, picked players, captains, votes, etc.).
- Announcement timers restart.
With FaceitLikeDamageControl: true:
- Player deals 50 damage to a teammate → dealer receives 50 damage reflected back.
- Teammate HP is not reduced.
With FaceitLikeDamageControl: false:
- Standard friendly fire rules from
match_start.cfgapply (no reflection).
Goal: Verify timeout votes, queueing, and timer accuracy.
With team size > 2:
- Player types
!timeout(!pause) during Match → vote menu opened for all teammates except caller. - Caller auto-votes Yes.
- Bots auto-vote Yes.
- Vote progress shown in chat: "X yes, Y no out of Z".
- All players vote Yes → timeout starts immediately (vote timer cancelled).
- One player votes No → vote fails ("timeout vote failed" message), no pause.
- Vote timer expires (
DefaultVoteTimeSeconds) without all votes → vote fails.
With team size ≤ 2:
-
!timeoutauto-passes without showing a menu.
- On pass: game pauses, "CT/T timeout started" announcement shown to all.
- Remaining timeouts shown to the calling team: "X/Y timeouts remaining".
- Countdown broadcasts fire during timeout.
- After
TimeoutDurationSeconds, timeout ends: "Timeout ended" message, game resumes. - State reverts from
Timeout→Match.
With Timeouts: 3:
- Use all 3 timeouts on one team → fourth
!timeoutattempt shows "0/3 remaining" error, vote not started. - Other team's timeout counter is independent.
- CT timeout active; T team calls
!timeout→ T timeout queued: "T timeout queued" message. - CT timeout ends → if in freeze time, T timeout starts immediately; otherwise marked pending for next freeze time.
- "T timeout pending" announcement shown.
- Round starts → pending timeout fires.
- Both teams queue simultaneously (queue is FIFO, handles duplicates).
- During Warmup,
!timeout→ error "invalid state for command".
Goal: Verify surrender vote mechanics and state transition.
With team size > 2:
- Player types
!surrender(!gg) during Match → surrender menu opened for teammates. - Caller auto-votes Yes (1 yes from the start).
- Bots auto-vote Yes.
- Vote progress: "X yes, Y no out of Z" shown to team.
- All Yes →
Surrenderstate entered immediately, opposing team wins. - Any No → vote fails and announced, match continues.
- Vote timer expires (
DefaultVoteTimeSeconds) → vote processed as-is (majority Yes passes, otherwise fails).
With team size ≤ 2:
-
!surrenderauto-passes without menu.
- Chat announces which team surrendered.
- Plugin transitions to Warmup after the standard post-match delay.
- During Warmup / MapVoting / PickingTeam → error "invalid state".
Goal: Verify the vote kick mechanics inside an active match.
- During Match,
!votekick PlayerName(!vk PlayerName) → chat announces "vote started against PlayerName". - All eligible teammates (excluding caller and target) receive Yes/No menu.
- Caller auto-votes Yes (1 yes from the start).
- Bots auto-vote Yes.
- CenterHTML progress overlay appears immediately and updates after each vote.
- All eligible voters click Yes → target is kicked from server.
- Chat to team: "PlayerName was kicked by vote".
- Vote timer cancelled.
- Vote state cleaned up (no stale
isVoteKickInProgress*flag).
- One voter clicks No → vote cancelled immediately (no waiting for timer).
- Chat: "vote to kick PlayerName failed".
- All open Yes/No menus closed for the team.
- Target is not kicked.
- Nobody else votes; wait
VoteKickTimeseconds → vote fails. - Chat: "vote to kick PlayerName failed".
- Target not kicked, state cleaned up.
-
!votekickagainst self → error "cannot kick yourself". -
!votekickduring Warmup / MapVoting / PickingTeam / KnifeRound → error "match only". -
!votekickwhile another vote for that team is already in progress → error "vote already in progress". -
!votekicktargeting a player on the opposite team → error (caller's team scope check). - Spectator or bot calling
!votekick→ rejected by player validity check.
- Caller is the only teammate besides the target → vote auto-passes immediately (no menu shown), target kicked.
- Start a vote on CT side; simultaneously start a vote on T side.
- Both run independently, CenterHTML for each team shows only their own progress.
- Resolving one vote (pass or fail) does not affect the other.
- Set
VoteKick.Enabled: false, reload/restart. -
!votekick→ command not registered (error or "unknown command"). -
!vkalias also unavailable.
Goal: Verify graceful handling of disconnects in every phase.
- Ready player disconnects → removed from
readyPlayers, ready count decrements. - Count falls below threshold → phase does not regress (no automatic un-start).
- Player rejoins → treated as new joiner, must
!readyagain.
- Non-captain player disconnects → removed from
pickedCtPlayers/pickedTPlayersif they were picked; picking continues. - CT captain disconnects →
captainCt = null,StartTeamPickingPhase()restarts immediately with new random captain. - T captain disconnects → same for T side.
- Non-captain playing player disconnects → removed from
playingCtPlayers/playingTPlayers, match continues. - CT captain disconnects →
captainCtreassigned to next available CT player fromplayingCtPlayers. - T captain disconnects → same for T side.
- Winning captain (knife winner) disconnects →
StayStartingSidesauto-fires, match proceeds with current sides (no hang).
- Player disconnects → removed from
playingCtPlayers/playingTPlayers. - If
PunishPlayerLeaves: trueandSensitivity ≥ 0→ player added to punishment queue (see Section 16). - Match continues normally with fewer players.
- Player disconnects and reconnects within 1 second →
recentlyDisconnectedPlayersdeduplication prevents double-handling. - No duplicate removal from team lists.
Goal: Confirm jointeam interception works correctly in each state.
- Player opens team selection (F3/F4 or console
jointeam 2/jointeam 3) →HandlePlayerChangeTeamfires. - Player is auto-balanced to the smaller team.
- Player is respawned immediately after assignment.
- Manually trying
jointeam 9(invalid) → blocked, logged as error.
- A non-picked spectating player tries
jointeam 2→ intercepted, blocked or redirected based on current state logic. - Captain trying to change sides → blocked (captain must remain on their assigned side).
-
PreventNotPickedPlayersFromJoiningOngoingMatch: false(default) → any player can join any open team slot normally. -
PreventNotPickedPlayersFromJoiningOngoingMatch: true→ player not inplayingCtPlayersorplayingTPlayersor picked lists is immediately kicked with "not picked" reason. - A legitimate playing player who reconnects and is in the playing list is not kicked.
- On
StartMatch(), all non-playing spectators are kicked immediately. - On
StartKnifeRound(), same kick logic applies. - Legitimate playing players are not kicked.
Goal: Validate all admin-only commands work correctly.
-
!mix_reset(!reset) — resets plugin to Warmup from any state. All lists cleared. Warmup CFG reloaded. -
!mix_start(!start) — force-starts the match from any state (jumps toStartMatch()). Confirm no crash if called from Warmup. -
!forceready(!fr) — adds all connected non-bot players to ready list, triggersCheckReadyPlayersToStart. -
!forceunready(!fur) — removes all players from ready list. -
!captain PlayerName ct— sets CT captain. Valid name → success. Invalid name → error. -
!captain PlayerName t— sets T captain. Valid name → success. Invalid name → error. -
!map mapname(!changemap) — changes to specified map regardless of current state. -
!maps(!maplist) — prints voteable map list to admin. -
!maplist_all(!allmaps,!maps_all) — prints all configured maps to admin. - Non-admin player attempts any admin command → denied by permission check (
managemix). - Admin commands work from console (server/RCON) as well as in-game chat.
Config: AllowVolunteerCaptains: true
- During Warmup or MapChosen, player types
!volunteer_captain ct(!volcap ct,!selfcapt ct) → "you volunteered as CT captain" message. - Player types
!volunteer_captain t→ "you volunteered as T captain" message. - When team picking starts, volunteer captains take priority over random selection.
- If only one volunteer exists, that slot is filled from volunteers; the other is chosen randomly.
- Two players volunteer for the same side → the first volunteer is used, second is ignored or superseded (verify consistent behaviour).
-
!volunteer_captainwith no argument → error "specify t or ct". -
!volunteer_captainoutside Warmup / MapChosen → check whether error or silently ignored.
With AllowVolunteerCaptains: false:
-
!volunteer_captain→ command not registered.
Config: PunishPlayerLeaves: true
Sensitivity 0 (Match / Timeout only):
- Player leaves during Match → added to punishment queue.
- Player leaves during Timeout → added to punishment queue.
- Player leaves during KnifeRound → not punished.
- Player leaves during PickingTeam → not punished.
Sensitivity 1 (+ KnifeRound / PickingStartingSide):
- Player leaves during KnifeRound → added to punishment queue.
- Player leaves during PickingStartingSide → added to punishment queue.
- Player leaves during PickingTeam → not punished.
Sensitivity 2 (+ PickingTeam):
- Player leaves during PickingTeam → added to punishment queue.
- All states from lower sensitivities also trigger punishment.
- After
WaitBeforePunishmentSeconds(default 300), the configuredServerCommandfires with{steamId},{duration},{reason}substitutions. - Player reconnects within the grace period → removed from punishment queue, punishment not issued.
-
PlayerLeavePunishment.BanDurationMinutessubstituted into{duration}. -
PlayerLeavePunishment.BanReasonsubstituted into{reason}.
With PunishPlayerLeaves: false:
- Player leaves during any state →
PunishOnLeavelogs "punishment disabled", no command issued.
true (default):
- Periodic chat messages list ready and not-ready players.
- Interval matches
ChatAnnouncementTimers.PlayersReadyStatus.
false:
- No periodic ready-status chat messages.
true (default):
- Ready players have a "[R]" or configured prefix in their clan tag.
- Unready players have a "[NR]" or configured prefix.
- Tags cleared at Knife Round start and Match start.
false:
- No clan tag modification at any point.
true (default):
- Center HTML overlay visible to all players during Warmup / MapChosen.
- Updates every 1 second.
false:
- No center HTML overlay.
true:
- Player marks ready → their own center HTML display disappears (others still see it).
false (default):
- Center HTML visible to all regardless of ready status.
- Change prefix in config (e.g.,
"[ [green]TestServer [default]]") → all plugin chat messages use new prefix. - Empty string → messages appear without prefix.
-
ChatAnnouncementTimers.PlayersReadyStatus: 10→ ready-status chat fires every 10 seconds. -
ChatAnnouncementTimers.CommandReminders: 30→ command reminders fire every 30 seconds. -
ChatAnnouncementTimers.CaptainsAnnouncements: 15→ captain announcements during MapChosen fire every 15 seconds. - After Knife Round starts, all three pre-match timers are stopped (
StopPreMatchAnnouncementTimers).
- After enough players ready in Warmup, state goes directly to
MapChosen(no voting menu). - Server stays on the current map.
- MapChosen ready phase starts normally.
-
playedMapshistory still updated when match begins.
- After MapChosen ready phase, captains are still selected (random/volunteer).
- No pick menu shown; all players on CT/T at map start remain on those sides.
-
MoveOverflowPlayersToSpecstill applies (excess players in spectator). - Knife round starts immediately after "team picking" phase.
- No captain selection at any point.
- Team names remain
COUNTER-TERRORISTS/TERRORISTS. -
SkipTeamPickingPhaseassigns players based on current team membership. - Side selection after knife round uses team vote instead of captain menu.
- All players on winning knife-round team receive Stay/Switch menu.
- Majority determines side; tie resolved by auto-Stay (or first-to-reach logic — confirm no hang).
- Warmup → immediately to MapChosen → immediately to Knife Round → Match.
- No menus shown at all. No crash.
- Warmup ready → MapChosen ready → auto-assign teams → Knife Round → team vote for sides → Match.
- Map with
CanBeVoted: falsedoes not appear in the voting menu. -
!mapsdoes not list it.!maplist_alldoes list it. - Admin
!map de_excluded_mapcan still change to it.
- Map appears in vote menu with its
DisplayName. - On selection,
host_workshop_map <WorkshopId>is executed (check console).
- Set all maps to
CanBeVoted: false→StartMapVotingPhaselogs error, state resets toReset, plugin resets to Warmup.
-
staging_overrides.cfgexecuted (verify via console — should configure bot counts etc.). -
PluginStatereported asStagingvia API or log.
-
production_overrides.cfgexecuted. -
PluginStatereported asProduction.
- Console is verbose: every state transition, player action, and list change is logged.
- Logs include method names, player names, and counts.
- Console shows only warnings and errors. No verbose info lines.
Config: DiscordInviteWebhooks populated with at least one valid webhook URL.
- Player types
!invite(!inv) → Discord webhook fires, invite message sent to configured channel. - Webhook URL is invalid or unreachable → plugin logs error, does not crash. Player sees appropriate message.
-
lastDiscordInviteSentAtcooldown: sending!invitetwice quickly → second message may be rate-limited (verify no duplicate webhook spam).
Goal: Confirm no state can get stuck or enter an invalid transition.
-
!mix_resetcalled during MapVoting → timers cancelled, menus closed, Warmup starts cleanly. -
!mix_resetcalled during PickingTeam (mid-pick) → captain menus closed, lists cleared, Warmup starts. -
!mix_resetcalled during active Timeout → timeout timer cancelled, game unpaused, Warmup starts. -
!mix_resetcalled during active surrender vote → vote timer cancelled, match state cleared, Warmup starts. -
!mix_resetcalled during active vote kick → vote kick state cleaned up for both teams, Warmup starts. -
!mix_startcalled during MapVoting → jumps directly toStartMatch()(teams may be empty — log warning expected, no crash). - Rapid
!readyspam from many players simultaneously → no duplicate entries inreadyPlayers. - Map change triggered externally (non-plugin
mapcommand) mid-match → allStopOnMapChangetokens fire, timers stopped, plugin starts fresh on new map.
Goal: Confirm all aliases work and permissions are enforced.
| Command | Aliases to test |
|---|---|
!ready |
!r |
!unready |
!u, !ur
|
!revote |
!rv |
!timeout |
!pause |
!surrender |
!gg |
!invite |
!inv |
!stay |
!st |
!switch |
!swap |
!volunteer_captain |
!volcap, !selfcapt
|
!votekick |
!vk |
- Each alias produces the same result as the primary command.
- Player without
managemixpermission cannot use admin aliases.
| Command | Aliases to test |
|---|---|
!mix_reset |
!reset |
!mix_start |
!start |
!forceready |
!fr |
!forceunready |
!fur |
!captain |
!cap, !capt
|
!map |
!changemap |
!maps |
!maplist |
!maplist_all |
!allmaps, !maps_all
|
- Each alias works for an admin.
- Each command is blocked for a non-admin with an appropriate denial message.
- Change an alias in
config.jsonc(e.g.,"ready": { "Aliases": ["go"] }), reload config. - New alias
!goworks. Old alias!rno longer works (if replaced).
Goal: Confirm all keys render correctly in both supported languages.
- Set server to
en— confirm all chat, menu, and center HTML messages appear in English. - Set server to
pt-BR— confirm all messages appear in Portuguese (Brazil). - No raw key strings (e.g.,
"command.ready") appear in chat — all keys resolve to translated strings. - Keys that include arguments (player name, count) substitute correctly (e.g., "[Alice] is ready").
- New votekick keys present in both files:
command.votekick.started,command.votekick.passed.ct,command.votekick.passed.t,command.votekick.failed,menu.votekick,info.kick_reason.votekicked.
Goal: Complete one full match from startup to post-match reset, using default config, verifying every phase transition in sequence.
- 1. Startup — Plugin loads, Warmup begins,
warmup.cfgexecutes. - 2. Warmup — 4+ players ready. State transitions to MapVoting.
- 3. MapVoting — Players vote. Timer expires or all vote. Winner announced. Map loads.
- 4. MapChosen — Players ready again. Captains selected after delay.
- 5. PickingTeam — Captains alternate picks until teams are full. State transitions to KnifeRound.
- 6. KnifeRound —
knife_round.cfgactive. Round played to completion. - 7. PickingStartingSide — Winner captain receives menu. Selects Stay or Switch.
- 8. Match —
match_start.cfgactive. MR12 match plays. Timeout and surrender available. - 9. Match End — Win panel shown. After 10 seconds, plugin auto-resets.
- 10. Warmup (again) — All state clean. Announcement timers restarted. No stale data.
// Add 10 bots quickly
bot_add_ct; bot_add_ct; bot_add_ct; bot_add_ct; bot_add_ct
bot_add_t; bot_add_t; bot_add_t; bot_add_t; bot_add_t
// Check current map
host_map
// Verify warmup config loaded
mp_warmuptime
// Verify knife round config loaded
mp_give_player_c4
// Force a round end (for testing transitions)
mp_restartgame 1
// Switch to a specific map manually
map de_mirage
{ "TestMode": true, "DetailedLogging": true, "MinimumReadyPlayers": 4, "RequireAllConnectedPlayersToBeReady": false, "SkipMapVoting": false, "SkipTeamPicking": false, "DisableCaptains": false, "AllowVolunteerCaptains": false, "FaceitLikeDamageControl": true, "MoveOverflowPlayersToSpec": true, "Timeouts": 3, "TimeoutDurationSeconds": 15, "DefaultVoteTimeSeconds": 15, "PunishPlayerLeaves": false, "PreventNotPickedPlayersFromJoiningOngoingMatch": false, "KickPlayersNotInMatch": false }