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

Version 1.10.0 is out on Github Releases

:sparkles: Improvements

  • Added HideCommandRemindersDuringPhases config variable which allows to configure which command reminders to stop at which match states.

    Example:

    "HideCommandRemindersDuringPhases": {
        "ready": ["PickingTeam", "KnifeRound", "Match", "Timeout"],
        "rtv":   ["PickingTeam", "KnifeRound", "Match", "Timeout"]
    }
    

:wrench: Bug Fixes

  • Fixed a case where when a player joined spectator team, their assigned team by CS2 engine would remain T/CT
  • Fixed a case where during warmup state, every new player join would trigger warmup config to be loaded

Full Changelog: v1.9.2…v1.10.0

Version 1.11.0 is out on Github Releases

:sparkles: Improvements

:rocket: You can now create Custom HUD plugins to handle MixScrims match flow :rocket:

Legacy CenterHTML menus and announcements are still supported, so creating a Custom HUD plugin to manage MixScrims match flow is 100% optional!

New external control API

  • Other plugins can now observe the whole match lifecycle through events: state changes, ready-ups, captain assignment, team picks, map voting, knife round, timeouts, surrender votes, vote kicks and match end.
  • Added snapshot reads for everything above, so a plugin that loads or reloads mid-match can catch up instantly instead of waiting for the next event.
  • Added driver methods so an external plugin can cast votes, make picks, volunteer captains and choose the starting side on a player’s behalf.
  • Added built-in UI suppression toggles (menus and center-screen text), so another plugin can replace MixScrims’ in-game presentation with its own without duplicate popups.
  • Two new config options to enable that suppression from the config file: SuppressBuiltInMenus, SuppressBuiltInCenterHtml.

:wrench: Bug fixes

  • Surrender now actually ends the match. Previously a passing surrender vote just paused the game and quietly reset the plugin. It now ends the match through CS2’s native surrender flow with the proper end-of-match panel, and waits for that panel before resetting.
  • Votes resolve as soon as the result is decided. Timeout and surrender votes no longer hold the whole team hostage until the timer expires or every last player clicks — once a majority is reached (or is no longer possible), the vote closes immediately. The vote progress message now shows the votes actually required.
  • Duplicate votes are blocked. A player can no longer answer the same vote twice.
  • Fixed double timeouts. A timeout request could be served and then queued a second time on the next round start.
  • Fixed team counting. Team fullness and limit checks were reading player pawns, which gave wrong numbers for dead/spectating players. They now read player controllers.
  • Removed forced game restarts from phase configs. These were causing crashes on team-limit edge cases and were wiping entities spawned by other plugins mid-warmup. Phase transitions are now driven directly by the plugin.
  • Fixed phases silently not starting. The warmup timer wasn’t always cleared before the knife round and team-pick phases, so their transitions were being ignored by the game.

Full Changelog: v1.10.0…v1.11.0

Version 1.11.1 is out on Github Releases

:wrench: Bug fixes

  • Fixed a rare edge-case where server would crash if captain chose !stay / !switch right at the moment when after knife round all players would be moved to the spawn and match pause initiated.
    • The fix is to extend round after it ended to +30s, this would allow captain to make their pick safely and if they dodn’t pick by that time, MixScrims counts that as a !stay and match begins

Full Changelog: v1.11.0…v1.11.1

MixScrims | v1.11.5

Download Latest

Scoreboard tag fixes. Worth updating if you use ready tags or captains.

  • [READY] / [NOT READY] tags stay visible now — VIP, guild and rank tags from
    other plugins were overwriting them within seconds of being set.
  • Players sitting on the team-select screen now get a [NOT READY] tag.
  • Ready tags keep updating after a map vote, not just during warmup.
  • [Captain] tags no longer linger into a live match.

Full Changelog: v1.11.4…v1.11.5

MixScrims | v1.11.6

Download Latest

Must update to this version in order to avoid random crashes.

  • Fixed a server crash on team changes — reconnects, spectator moves and the
    halftime side swap could all trigger it. The plugin was reading player names
    out of game memory that had already been torn down.
  • Servers running with DetailedLogging enabled were the most exposed, but one
    path could crash with it off too.

Full Changelog: v1.11.5…v1.11.6

MixScrims | v1.11.7

Must update to this version to avoid cases where vote cannot pass because of recently disconnected players.

  • Votes no longer hang when a player leaves mid-vote. Surrender, timeout and vote
    kick re-count who is still on the team and close as soon as the rest have decided
    it — a unanimous surrender used to sit open until the timer ran out, then announce
    itself as failed.
  • A vote kick ends immediately when its target disconnects.
  • The starting-side vote closes once the remaining winners have answered, and votes
    left behind by players who already left no longer count toward the result.
  • Leaving during map voting now withdraws your vote; the next player to connect used
    to inherit it.
  • The team pick menu is rebuilt when a player it lists disconnects, so captains can
    no longer click a name that is already gone. If nobody is left to pick, the knife
    round starts instead of stalling.
  • Two players with the same name can no longer be picked as the same person, which
    left the other unpickable for the rest of the draft.
  • Surrender vote progress now shows the correct total in replacement menus — it read
    100% one vote before the team had agreed.

Full Changelog: v1.11.6…v1.11.7