MixScrims - OG way to play mix/pugs/scrims

Plugin Name

MixScrims

Author

Shmitz

GitHub Repository

Description

A SwiftlyS2 plugin for PUGS-style CS2 matches managed entirely in-game

Core Features

  • Faceit-like damage control

  • Player leave punishments

  • Timeout and Surrender commands

  • Automated Match Flow:

    • Warmup - Players join and ready up

    • Map Voting - Democratic map selection

    • Captain Selection - Random or manual captain assignment

    • Team Picking - Captains alternate picking players

    • Knife Round - Determine starting sides

    • Competitive Match - Full CS2 competitive rules

  • Extensive API for full plugin control with external plugins

There are tons of features, full list is in the MixScrims Wiki

Installation

MixScrims Wiki - Installation

1 Like

For anyone waiting for new features and bug fixes

I’ve gotten better at this framework by creating a few personal plugins with Shared API and other more advanced features.
Because of this I now feel confident enough and have enough freed-up time to continue fixing remaining bugs (so glad there are only a few) and implementing most requested features.

Expect next update in 1 week :saluting_face:

  • max 2 weeks if something goes sideways :sweat_smile:

Version 1.2.0 is out on Github Releases

What’s New

:globe_showing_europe_africa: Translations

  • Added Portuguese (Brazil) translations by @crashzk
  • Updated translation files and indexes

:sparkles: New Features

  • SharedAPI Implementation - New plugin API for external integrations
  • FACEIT-like damage control - Friendly fire does not inflict teammates when shooting or slicing with a knife
  • Ready Status in Scoreboard - See which players are ready directly in the scoreboard
  • Center HTML Ready Display - Real-time ready player count displayed in center screen
  • Surrender Vote - Players can now vote to surrender during matches
  • Skip Map Voting - Option to bypass map selection
  • Force Unready Command - Admins can force players back to unready state
  • Require All Players Ready - Optional setting to require all connected players to ready up
  • Disable Captain System - Option to disable the captain selection system in config

:wrench: Improvements

  • Restructured configuration for better organization
  • Improved edge-case handling
  • Enhanced stability and bug fixes

:memo: Documentation

  • Updated README to reflect latest changes

:busts_in_silhouette: New Contributors

Full Changelog: v1.1.0…v1.2.0

Version 1.3.0 is out on Github Releases

What’s New

:sparkles: New Features

  • Customizable Server Prefix - Set your server prefix in config to be applied across all translations
  • Player Leave Punishment - Automatic punishment for players disconnecting during matches with 3 sensitivity levels
  • Announcement Timer Controls - Adjust timing for ready status, captains, and command reminder messages
  • Comprehensive Plugin API - 40 methods providing full match control via external plugins (start/stop matches, manage players, control timeouts/surrenders, modify teams, force state transitions, etc.)

:wrench: Improvements

  • Fixed Ready Status Displays - Scoreboard and center HTML overlays now update immediately instead of on delays
  • Enhanced player lifecycle tracking with punishment queue system
  • Improved stability and edge-case handling

Full Changelog: v1.2.0…v1.3.0

Version 1.3.1 is out on Github Releases

:bug: Bug fixes

  • Ready status was continued to be displayed after match started
  • CenterHTML ready players display was disabled by default
  • Picked players were kicked after teams were picked
  • After knife round transferring players from T to CT did not work because of a typo

Full Changelog: v1.3.0…v1.3.1

Version 1.4.0 is out on Github Releases

What’s New

:bug: Bug Fixes

  • Fixed async errors when moving a player to a team (#32)
  • Timeout vote no longer prompts the vote initiator to vote (now defaults to “Yes”)
  • Surrender vote no longer prompts the vote initiator to vote (now defaults to “Yes”)
  • Added extra checks to remove ready/unready Clan tag when a match starts

:wrench: Improvements

  • Added optional config: HideReadyStatusInCenterWhenReady
    • Hides CenterHTML display of ready/not ready players when a player is already ready (#30)
  • Timeout vote countdown now displays as Center HTML and updates every second for better visibility

Full Changelog: v1.3.1…v1.4.0

Version 1.5.0 is out on Github Releases

What’s New

:sparkles: New Features

  • Fully customizable Discord Invite. Converted from simple message to an embed with removable fields. #36

image

:bug: Bug fixes

  • Ready status would continue to be displayed if team picking was skipped #37

Full Changelog: v1.4.0…v1.5.0

Version 1.6.0 is out on Github Releases

:sparkles: New Features

  • Added MovePlayersToSpecDuringTeamPicking config option (set to false to keep players on their teams during picking) (closes #40)
  • Added !votekick / !vk command — team-based unanimous vote kick, active only during Match state (closes #43)
  • Added VoteKickConfig (Enabled, VoteKickTime — default 30s)
  • Restructured commands into individual files (Commands/Admin/, Commands/Player/)

:wrench: Bug Fixes

Captain & Side Selection

  • Fixed captain comparison in !stay / !switch to use PlayerID instead of object reference
  • Added validation to prevent non-winner team from voting (error.not_winner_team)
  • Fixed OnSwitch missing player validation and wrong log message (“OnStay”)
  • Fixed SwitchStartingSides / StayStartingSides to accept nullable captain
  • Fixed ProcessTeamSideVotes not handling empty vote case correctly
  • Fixed SurrenderVoteResult and TimeoutVoteResult using re-derived team instead of stored vote team
  • Removed Timeout state from captain disconnect handling

Team Picking

  • Fixed player list filtering to use PlayerID equality
  • Fixed duplicate player check in HandlePlayerJoinTeam for CT/T during Match
  • Removed stray CloseMenuForPlayer(captain) after CT captain pick

Player Management

  • Replaced all player.Controller?.PlayerName with player.Name (20+ occurrences)
  • Fixed GetPlayerByName comparison to use player.Name

Event Handling

  • Added duplicate disconnect prevention via recentlyDisconnectedPlayers
  • Fixed HandleClientPutInServer to only auto-assign during Warmup/MapVoting/MapChosen
  • Added freshlyJoinedPlayers cleanup on disconnect

Map & Configuration

  • Fixed workshop map change — removed redundant ds_workshop_changelevel, use only host_workshop_map
  • Fixed LeavePunishment.Sensitivity missing { get; set; } accessor
  • Fixed GetRandomMap to use GetMapsToVote() so DisallowVotePreviousMaps is respected

State Management

  • Changed ResetPluginState to call StartWarmup instead of LoadSelectedMap
  • Expanded ResetVariables to clear all state (vote kick, timeout, surrender, side votes, player tracking lists, isFreezeTime, playerColors, etc.)
  • timeoutCountCt / timeoutCountT now reset to cfg.Timeouts instead of hardcoded 3

UI & Menus

  • Replaced deprecated GetCurrentMenu + CloseMenuForPlayer pattern with CloseActiveMenu
  • Fixed player radar color allocation (addresses #41)

:globe_with_meridians: Translations

  • Added error.not_winner_team (EN/PT-BR)
  • Added all command.votekick.* and menu.votekick keys (EN/PT-BR)
  • Fixed key: command.unready.not_ready → command.unready.already_unready

:package: Dependencies

  • Updated SwiftlyS2 from beta to stable

Full changelog

v1.5.4…v1.6.0

Version 1.6.1 is out on Github Releases

:sparkles: Refactoring

  • Moved maps to dedicated config file at maps.jsonc

:wrench: Bug Fixes

  • Additional fixes for radar colors being duplicated across teammates

:chart_increasing: Version

  • 1.6.0 → 1.6.1

Full changelog

v1.6.0…v1.6.1

Version 1.7.1 is out on Github Releases

:sparkles: Improvements

  • Added Lithuanian translations
  • Improved logging
  • Improved performance a bit
  • Improved safety checks and validation
  • Broadened state coverage: Auto-reset now triggers in all match states except Warmup and MapLoading
  • Excluded bots from player count: Uses !IsBot(p) filter so CS2 bot replacements don’t inflate the count
  • Deferred reset on empty server: When all humans leave, sets resetMixOnFirstJoin flag instead of immediate reset (server hibernation prevents timers from firing)
  • Map change safety: Skips auto-reset logic during MapLoading state to prevent false resets when players reconnect after map vote

:wrench: Bug Fixes

  • Another attempt at fixing 2 Teammates have the same colors
  • Fixed another team limit bypass
  • Fixed auto mix reset triggers
  • Fixed ObjectDisposedException in SwitchStartingSides when captain disconnects before the delayed team name update executes

Full changelog

v1.6.0…v1.7.1

Version 1.7.5 is out on Github Releases

:wrench: Bug Fixes

  • Fixed silent failures during map transitions that could cause unobserved async exceptions and server crashes
  • Added null guards around Core.Engine access in map loading, config execution, and team-limit overrides
  • Prevented disposed IPlayer references from desyncing playing-team lists during round resync
  • Plugin unload now properly unsubscribes lifecycle events and cancels all active timers to prevent callbacks against dead instances

:sparkles: Improvements

  • Replaced silent catch blocks and DetailedLogging-gated error paths with unconditional warnings so production issues are no longer swallowed
  • Invalid/disconnected player votes (timeout, surrender, votekick) now log a warning instead of silently dropping
  • Command alias cleanup on hot reload now reports null configuration entries instead of skipping silently

Full Changelog

v1.7.1…v1.7.5

Version 1.7.9 is out on Github Releases

:wrench: Bug Fixes

  • Fixed a critical bug which would cause endless map vote instead of picking team members
  • Fix: Do not register commands as raw (causes issues for some native-like commands (eg. map)
  • Fixed cases where if a map was changed by another plugin, it would mess up MixScrims config execution resulting in various issues, like match config being executed during Warmup.

:sparkles: Improvements

  • Hardened captain handling against stale/disposed IPlayer references that survive map changes and reconnects, preventing crashes in PrintChosenCaptains, StartTeamPickingPhase, StartKnifeRound, and the side-pick prompt.
  • Added a new EnsureCaptainsAlive() helper that clears invalid captain refs and re-picks replacements from playing/picked rosters.
  • Guarded !start so it can no longer relaunch the knife round when the match is already past pre-match phases (fixes the knife-round loop).
  • Preserve the pre-MapLoading state across map transitions so manual !map during warmup no longer auto-promotes the match to MapChosen (and skips captain selection in that case).

Full Changelog

v1.7.5…v1.7.9

Version 1.8.0 is out on Github Releases

:sparkles: Improvements

  • Implemented !rtv command (disabled by default) - Works only in warmup, so players can change warmup maps to whichever they want
  • Improved edge case handling on player disconnects
  • Implemented automatic version append to published .zip
  • Moved some listeners to new GameHooks hook for better performance

Full Changelog

v1.7.9…v1.8.0

Version 1.9.2 is out on Github Releases

:wrench: Bug Fixes

  • Fixed a case where disconnected ready player would cause ready players counter to wait for the disconnected player before allowing to start a match.
  • Improved logic handling for team limits
  • Added additional checks to prevent crashes
  • Fixed captain announcement duplicates logic
  • Fixed ready/unready counter increase/decrease edge case bugs
  • Added missing rtv translations

:sparkles: Improvements

  • Added captain clan tags in scoreboard
  • Captains are tracked via PlayerID instead of SteamID to allow playing with bots
  • When map is changed by rtv, match state will remain warmup after map change

Full Changelog

v1.8.0…v1.9.2