Changelog
Based on MatchZy by Shobhit Pathak, adapted for CS2 game-server hosting: remote log HTTP API, G5API compatibility, auto changelevel, advanced stats (HLTV 2.0 rating / KAST / clutch / opening duels), a coach system, a pause overhaul, and in-game admin and match-setup menus.
1.0.25
November 13, 2026Summary- New
matchzy_auto_recover(default on) withmatchzy_auto_recover_max_age(default 180 minutes): a loaded match is kept inMatchZyDataBackup/active_match.jsonuntil the series ends or the match is cancelled. A match interrupted by a crash, a restart or a plugin reload used to be gone from memory, so the server had no rosters, team names or match id andmatchzy_kick_when_no_match_loadedkicked every player. Ten seconds after the server is ready with no match loaded, MatchZy now restores the newest round backup of that match (or loads its match config again when no round was backed up yet) and sendsmatch_recovered. - With
matchzy_kick_when_no_match_loaded, a player on the roster of the interrupted match is let in while no match is loaded, and admins are told in chat. - New
.recover/matchzy_recover/css_recover: restores the interrupted match without a file name (its newest backup), or a given round number or file. - New
matchzy_raw_backup_restore(defaultredirect): Valve'smp_backup_restore_load_fileonly brought the score back, not the rosters, team names or pause state, and MatchZy did not know about it. It now runs MatchZy's restore of the.jsonwith the same name (.txtand.jsonnames both work). When only the.txtexists, the.jsonis rebuilt from another backup of the same match, or from the loaded or interrupted match, with each team's side worked out for that round from the halftime parity; admins are asked to check the sides.blockrefuses the command,allowruns it as before. matchzy_loadbackuptakes the.txtname of Valve's command, a name without extension, a path,latestor a round number. The.txtname used to be looked up as is and reported as "does not exist"..restorereturned without a word when no match was live;.restore,.restorelastand.restorecurrentnow list the newest backups on disk and the command to load one.- A round restored from warmup (crash recovery, or
.restoretyped twice) could get stuck with every player dead and the timer at 0:00. The ready phase forcesm_bGameRestartandmp_ignore_round_win_conditions 1for its fake warmup, and leaving it only reset the convars, so the engine kept treating a restart as in progress and never ended the round. Both are now cleared when the ready phase ends and before and after every restore, and a technical pause box is closed before the restore loads. - New
matchzy_round_watchdog(default on): a live round with one side all dead, or the timer past 0:00 with no bomb planted, gets the round-win overrides cleared after 3 seconds and is ended after 8 seconds. The state is logged as[RoundWatchdog]. - Players kicked at connect see the reason in the disconnect dialog (not whitelisted, no match loaded, not in the match, series over). The server log has a
[ConnectGate]line with the loaded match id and roster sizes, panels get aplayer_kickedevent, and every disconnect is logged with the engine's reason ([Disconnect]).
1.0.24
November 10, 2026Summary.breakrestoreanswers that the signature is missing when a CS2 update madeCCSGameRules_PostCleanUpstale. Before, the command failed without a reply.- New events for panels:
knife_round_started,knife_round_ended(with the winner),halftime_started,side_swap(with team1's new side) andovertime_started(with the overtime number).matchzy_test_eventsends atest_eventto the remote log URL(s) to check that a panel can be reached. - New
matchzy_backup_keep_days(default0, off): deletes round backup files older than that many days at plugin load and at series end. Nothing removed them before, so the disk filled up on servers that run for months. The running match's backups are kept. - A few seconds after going live, MatchZy lifts an engine pause it did not start (for example from the map load or a cfg). Before, the match sat paused and
.unpausedid nothing. - In-game menus (
.matchadmin,.matchsetup,.nades,.strats) no longer flicker. The ready panel, the classic ready text, the technical pause box, the practice.timerand the spawn-marker text wrote over the menu in the middle of the screen; they now wait while a player has a menu open. The.timertext also no longer covers the.startroundcountdown. - New admin tickets.
.admin [message](also.calladmin) writes to the match's ticket: one open thread per match that every player's messages go into, and every player in the match sees the messages and the admins' answers, so both teams see what was agreed..report [message]opens a private thread that only the reporter and the admins see. Admins on the server get the messages in chat, and every message is anadmin_calledevent (thread_id,kind,new_thread, server and player) so a panel or ticket system can open a ticket and add to it. The panel answers withmatchzy_admin_reply <thread_id> <message>and closes withmatchzy_admin_closeover RCON (eventsadmin_replyandadmin_thread_closed); a match's tickets also close when the match ends. Turned on with the newmatchzy_admin_call_enabled(defaultfalse),matchzy_admin_call_cooldown(seconds between messages, default5) andmatchzy_admin_ticket_timeout(default30minutes). - New events for panels:
player_ready,player_unready,team_ready,all_players_ready,unpause_requestedanddemo_recording_start. The field names match the ones tournament panels such as auto-tournament already read. - A tactical timeout (
.tac, or.pausewithmatchzy_pause_command_for_tactical) is now sent as a pause event:game_pausedwithpause_typetactical, the team andmax_duration(mp_team_timeout_time) when it is called, andgame_unpausedwhen it ends (legacy format:match_paused/match_unpaused). Before, a panel or scorebot did not see tactical timeouts at all. - A regular pause (
.pause) and a tactical timeout (.tac) now show an on-screen box like the technical pause (matchzy_pause_hud)..pause: the team and player who paused, whether it waits for freeze time, and which teams have typed.unpause..tac: the team and player, the time left of the timeout and the timeouts left. Before, players only saw CS2's own pause text. While the box is shown (matchzy_pause_hud 2), CS2's red "The match is set to pause during freeze time" box is hidden, since the box says the same; with0or1, or an admin.forcepause, it stays. matchzy_ready_hint_stylenow defaults to1: the HTML ready-up panel instead of the classic center text. New installs get it in config.cfg; existing servers keep the value in their config.cfg and change it there to switch.- The ready panel labels each side's count (
Ready (min. 4): CT 2 T 1) and the short-handed line now says how many players have joined (3 joined (min. 4): 1 missing). Before, both showed a bare2/4, which read as if a team could only have 4 players. In a loaded match the total next to the progress bar (5 / 8) is gone for the same reason, and the classic center text (matchzy_ready_hint_style 0) shows the same per-side line instead ofWaiting for players [Ready: 5/8]. The short-handed line (panel, center text and chat) also stays hidden for 30 seconds after a player joins the side, so it no longer warns about missing players while they are still loading in. - A technical pause (
.tech) now shows a box in the middle of every player's screen for as long as it lasts: the team and player who called it, whether it is waiting for freeze time, the time until it ends on its own (or until either team can unpause withmatchzy_tech_pause_mode 1), the technical pauses the team has left and which teams have typed.unpause. Newmatchzy_pause_hud(default2):1shows a single line of center text instead (the textmatchzy_tech_pause_mode 1showed before, now also for mode 0),0turns it off. - Loading a match (
matchzy_loadmatch,matchzy_loadmatch_url,.matchsetup) while practice mode or a dry run is running now ends it like.exitprac, and the match loads normally. Before, the server stayed in practice through the match warmup (practice commands such as.botand.godstill worked), and practice settings that the match cfgs do not reset (for example free default grenades) stayed on into the knife round and the live match. A failed load during practice also turns the practice settings off before going back to warmup. - A player who joins while practice mode is already running (for example started automatically at map start after switching from another mode) now gets the short practice command list in chat. Before, it was only printed to the players on the server when practice started.
- Players are put on their roster side during warmup again after a map change (series map, the veto's map). CS2 gives a reconnecting player back their old team while they are still connecting, before MatchZy's team lock sees them, so warmups could run with both teams mixed. MatchZy now checks each player's side right after they finish connecting and moves them if needed.
- Players who were on the wrong side in warmup and were moved to their roster side when the match started no longer sit out the knife round (or the first live round) dead. MatchZy now puts everyone on their roster side before the knife/live restart, respawns a player it moves during the ready phase (also with the HTML ready panel, which turns the native warmup off) or the first freeze time, and respawns any roster player who is still dead when that freeze time starts.
- Team names show on the correct sides after a round restore (
.restore,matchzy_loadbackup). The engine ties the first team name to the team that started the map as CT, but MatchZy always gave it team1's name, so the names were swapped on the scoreboard when team1 started as T or the restored round was in the other half. The halftime name swap after the restore follows the restored round too. - A registered player who coaches with
.coach(in a match config without acoacheslist) no longer counts as a missing player in the ready-up. Before, a 5-player roster with one coaching still needed 5 players on the side, so a 4v4 never started even when both teams were ready. - Spectators and coaches are no longer part of the ready-up.
.ready,.unreadyand pinging from them are ignored with a chat line, a pug withmatchzy_minimum_ready_requiredno longer counts their ready, and the not-ready lists (center text after.ready, chat reminder withmatchzy_ready_hint_style 2) no longer name them. - The
readystate of each team in the get5 status (get5_status, read by panels) now follows the same rule that starts the match (roster size,min_players_to_ready,matchzy_ready_per_team,.forceready). Before, it was only true when every player on the side was ready, so a panel could show a team as not ready while the server counted it as ready, or the other way round. - A match config without
players_per_teamnow takes the team size from theplayersrosters: the larger roster of the two teams (coaches not counted), at most the game mode's default (5 in competitive). Two rosters of 4 play as 4v4. Before, it was always 5, so a 4v4 match only started withcss_forcestart, andmatchzy_ready_max_missingwas measured against 5. The[LOADMATCH]log line now showsPlayersPerTeam. - New
matchzy_demo_live_only(defaultfalse): only live maps (match, scrim, hill) are recorded. MatchZy setstv_autorecord 0and stops any GOTV recording outside a live map, so practice mode and an idle server no longer fill the disk with demos. CS2'stv_autorecordrecords every map from the moment it loads, which wrote large demos of servers left idle for hours. MatchZy's own match demos are not affected. - A team can type
.readywhile a player is still missing, and the match now starts by itself once that player has fully connected and is on the side. Before, the start was only checked on.ready, a ping or.forceready, so the match stayed in warmup after the last player joined until someone typed.readyagain. .readycheckin a loaded match now shows per team what the match is waiting for: players on the side and ready players against what the team needs, the registered players who are missing by name (marked when they sit on Spectator), and who on the side has not typed.ready. A ready team gets one line. Before, it only showed totals, which did not say why a match with everyone ready did not start. It also answers in the server console / RCON now.- A team waiting for a registered player now sees who is missing by name. The ready panel and the classic center text show up to 2 names (
4 joined (min. 5): missing alpha5), and the chat message after.readynames all of them, marked when they sit on Spectator. Only the player's own team is shown. Without a roster ("players": "any") it keeps the count. - Loading a match now warns about a config that is valid but will probably not start as meant: a player listed for both teams, a team player also listed under
spectators, a roster with more players thanplayers_per_team, teams that need a different number of players, andmin_players_to_readythat is ignored (withmatchzy_ready_per_team) or lets a short team start. Each is a[LOADMATCH] WARNINGline in the server console, and admins on the server get a chat line with the count. The match still loads. - New
matchzy_demo_keep_days(default0, off): deletes.demfiles inmatchzy_demo_patholder than that many days, at plugin load and at series end. The demo being recorded and demos still uploading are kept. Nothing removed old demos before, so servers that keep them locally ran out of disk. - New
matchzy_validate_match <file|url> [header] [value](server console / RCON): checks a match config without loading it, also while a match runs. It says whether the config would load (or why not), shows the teams, team size, maps and ready-up it gives, and prints the load warnings. A panel can test what it sends before a tournament.
1.0.23
November 5, 2026Summary- A player who left a live match and came back in the same round got back the money they had at the start of that round. CS2 keeps an in-memory round backup for reconnecting players (
mp_backup_round_auto) and restores their cash from it, so money spent that round was refunded while the bought weapons stayed on the ground for teammates (players reported 4000 turning into 6000). MatchZy now remembers the money a player leaves with and sets it back to that if they return in the same round with more. A reconnect in a later round, and money earned after coming back, are not touched. Each correction is logged.
1.0.22
November 5, 2026Summary- Round backups are found again on servers where a hosting egg,
server.cfgor another plugin changedmp_backup_round_file_pattern(for example tobackups/%prefix%_round%round%.txt). CS2 then wrote the round files to a folder MatchZy does not read, so the backups had no round data and.restorefailed. MatchZy now sets the pattern back to%prefix%_round%round%.txtwhen a match goes live and logs the old value. - On Metamod servers the round backup files no longer stay in
csgo/addons/metamod/. CS2 writes them to the first game search path, which Metamod'sgameinfo.giline makescsgo/addons/metamod/, and it no longer accepts a full path tocsgo/. MatchZy now moves each round file tocsgo/about two seconds after the round starts, once CS2 has finished writing it (also files left there by older versions). Restores load them fromcsgo/as before. Ifcsgo/is not writable, the files stay where they are and a warning is logged once. - Round backup files are now also looked for in
csgo/backups/, for servers whosegameinfo.giadds that folder as a game search path (some Pelican/Pterodactyl eggs). CS2 writes the round files to the first such folder, so MatchZy found no round data there and.restorefailed. Servers without it still usecsgo/orcsgo/addons/metamod/. - The startup line and
css_matchzy_versionnow also say that this is the fork by mrc4tt and not the original MatchZy by WD-, with where to get support (github.com/mrc4tt/MatchZy), so a log or console output tells this fork (1.0.x) apart from the original MatchZy (0.9.x). TheMatchZy version: xline is unchanged.
1.0.21
November 2, 2026Summary- MySqlConnector updated from 2.4.0 to 2.6.2 for GHSA-473q-m89c-ghf8. MatchZy connects with the default TLS mode, in which the older version sent the MySQL password before verifying the server certificate, so a man-in-the-middle between the game server and a remote MySQL server could read it. SQLite is not affected.
noclipin the console now only works in practice mode. MatchZy takes over thenoclipcommand to apply it server-side, and that handler ran before the engine'ssv_cheatscheck without checking for practice, so any alive player could noclip during warmup, the knife round, scrims and live matches. Dry run counts as outside practice.- With
matchzy_ready_hint_style 1or2, a player who joined a team during warmup while the round was running stayed in the observer view until the round ended. The join respawn checked for a player pawn, which someone who just joined from the team menu or Spectator does not have yet, so it never ran. Joiners now spawn as soon as their team is set, and withmatchzy_warmup_instant_respawn truealso in the native warmup. - New
matchzy_warmup_instant_respawn(defaultfalse): a warmup where the dead respawn at once at their team spawn with 2 seconds of spawn protection, no bomb, no friendly fire, buying all warmup and full money on every respawn. It is set afterwarmup.cfg, so servers with an olderwarmup.cfgcopy do not have to edit it. Friendly fire, buy time and respawn cash return to their previous values when the warmup ends. - With
matchzy_ready_hint_style 1or2, a warmup that restarted while the ready phase was already running (match loaded during warmup, veto finished, map reload) ranwarmup.cfgagain, which turned the ready phase's respawn and no-round-end rules off. Rounds then ended when one side was eliminated and the dead only came back with the next round. The rules are now put back after the cfg. - New
matchzy_ready_max_missing(default-1= off): the fewest players a team can ready up with in a loaded match,players_per_teamminus this. It applies to every way of readying up (a smaller roster,min_players_to_readyin the match config, join mode,matchzy_ready_per_team,.forceready). Before,matchzy_forceready_max_missingonly limited.forceready, so a panel sendingmin_players_to_ready 1or a 3-player roster still let a short team start with plain.ready. - Ready reminders in a loaded match no longer read as "everyone must type .ready" when fewer are enough: players on a side that is already ready are left out of the waiting list, the chat reminder (
matchzy_ready_hint_style 2) says how many each side needs, and the classic center hint counts ready players against what the start needs instead of everyone on the server. - A server started without
-allow_round_backup_filesnow warns admins in chat when a match is loaded and when it goes live, not only in the log. CS2 saves no round backups without it, so the missing option used to show up only when a.restorefailed with every round already lost. - Warmup, knife round, scrim and all live cfgs now set
mp_drop_knife_enable 0, andwarmup.cfg/knife.cfgalso setmp_defuser_allocation 0. A knife-drop or free-defuser value fromserver.cfgor another plugin used to carry into these modes. Servers with their own cfg copies get the new values automatically unless their cfg sets them. matchzy_spawn_markers_enabled_defaultis nowtrue: the.showspawnsmarkers are drawn as soon as practice starts, so players can walk into a spawn box (or aim at it) and press E to teleport there without knowing the command..hidespawnshides them; set it tofalsefor the old behaviour.- New
.smoketimerspawn smoke timer in practice (on by default,.smoketimerturns it off for you): after a spawn teleport (E on a spawn marker,.spawn,.ctspawn,.tspawn) a clock starts on your first move, jump or shot. A smoke you throw then reports how many seconds after that start it was thrown and when it popped, with its flight time, so a spawn smoke can be checked against the round start. - Chat messages are now also translated to German (
de), Spanish (es), French (fr), Norwegian (nb), Polish (pl), Russian (ru) and Swedish (sv). Each player sees their own language (!lang <code>); messages without a translation stay in English. - A pause still pending when the last map of a series ended (for example an auto-pause after a player left during the final round) stayed queued through the end-of-match intermission and the reset. It is now cleared when the map ends, as it already was between the maps of a series.
1.0.20
October 24, 2026Summary- Fixed a match loaded with
matchzy_loadmatch/matchzy_loadmatch_urlduring a running.startpug reusing the pug's match id when the match config has nomatchid. Its stats, events, demo name and round backups went to the pug's match. The loaded match now gets its own id; amatchidin the match config is still used as before. .showspawns: pressing E on a spawn marker now picks the marker you aim at more precisely. The aim tolerance is a fixed distance around the marker instead of an angle, so a far marker next to the one you aim at is no longer picked, and the aim is taken from your real eye height (also while crouched).
1.0.19
October 24, 2026Summary- Fixed GOTV demos not being recorded on Windows servers. The current CS2 build rejects the drive-less
/csserver/game/csgo/demos/...path thattv_recordwas given ("is a current-drive-root path", "couldn't open file ... for writing"), so every attempt failed. On Windows the demo path is now relative tocsgo/, and MatchZy finds the file incsgo/orcsgo/addons/metamod/for the recording check and the upload. Linux servers are unchanged.
1.0.18
October 24, 2026Summary- New
matchzy_ready_enabled(defaulttrue). Set it tofalseand players can no longer ready up:.ready,.r,.unready,.forceready,.readycheck, ready by ping and join ready mode are turned off, and only an admin starts the match with.start/.forcestart. This also applies before the map veto and to pugs. The ready time limit does not run, the[READY]/[UNREADY]clan tags are hidden, and the ready hint says the server is waiting for an admin. - New
matchzy_hide_failed_connect_messages(defaultfalse). Set it totrueto hide the chat line when a player leaves before they were fully connected, such as "failed to connect" or a cancelled join. Leave messages of players who were in the game are still shown.
1.0.17
October 24, 2026Summarymatchzy_remote_log_url ""now clears the remote log URL and stops sending events. Before, the empty value was ignored and the server kept sending every later match's events to the old webhook until the plugin was reloaded. The same works formatchzy_remote_log_header_key,matchzy_remote_log_header_value,matchzy_remote_log_auth_key,matchzy_remote_log_auth_valueand theget5_names. An empty value in a match config'scvarsis still ignored.- Running a remote log setting without a value (
matchzy_remote_log_url) prints what it is set to. Header and auth values are shown masked. An invalid URL is now logged instead of ignored without a message. matchzy_loadmatch_url/get5_loadmatch_urltries the download up to 3 times when it times out, hits a network error or gets HTTP 5xx, 408 or 429, with 2 and 4 seconds between attempts and 20 seconds per attempt. Other errors such as 404 or invalid JSON still fail at once.
1.0.16
October 24, 2026Summary- The hostname set by
matchzy_hostname_formatno longer stays on the server after a series. The hostname from before the match is saved and put back together with the match config'scvarswhen the series ends or the match is stopped (unlessmatchzy_reset_cvars_on_series_endis false). Round backups keep it, so it is also put back after a.restoreor a server restart. - Demo uploads no longer fail for team names with letters outside ASCII (for example
Ærø). The demo file name now converts them (ætoae,étoe) or drops them; before, the upload request was refused because the file name is sent in theMatchZy-FileName/Get5-FileNameheaders. - A
.pauseor.forcepauseduring the knife round (or.forcepauseduring side selection) now starts in the first live round. The engine only pauses at the next freeze time, so the pause used to hang over side selection, where.unpausedoes not work. - Series: when a match config or override cfg sets
mp_match_restart_delaybelow 18, the change to the next map now happens 3 seconds before the game's own restart. Before, the fixed 15 second change could come too late and the game loaded another map. - Added
.ffire nadesand"friendly_fire": "grenades"in the match config: only HE and molotov/incendiary damage teammates, bullets, knife and zeus do not..ffire on/.ffire offand"friendly_fire": true/falseset friendly fire directly;.ffirewithout an argument still toggles it.
1.0.15
October 23, 2026Summary- Ready panel in a loaded match: the per-side count no longer goes above what the side needs. With
"min_players_to_ready": 1and three ready players on CT, the panel showedCT 3/1; it now showsCT 1/1. A side that is ready through.forcereadyshows as full.
1.0.14
October 23, 2026Summarymin_players_to_readyin a match config now sets how many players of each team must type.ready, when it is lower thanplayers_per_team(or the team's roster size). With"min_players_to_ready": 1, one ready player on CT and one on T start the match, and the ready panel shows 2 instead of 10. Before, the value only applied to.forcereadyand every player on both teams had to ready up. Leave it out (or set it toplayers_per_team) to keep the full ready-up.
1.0.13
October 23, 2026Summary- When
live.cfgorlive_wingman.cfgis missing on disk and MatchZy falls back to its built-in live settings, the match config'scvarsare now applied before the game restart. Before, the restart ran first, so settings it reads (such as the number of tactical timeouts frommp_team_timeout_max) kept the built-in value. live_wingman.cfgandlive_rush.cfgnow set the tactical timeouts: 1 timeout of 60 seconds per team and 1 more in each overtime (mp_team_timeout_max 1,mp_team_timeout_time 60,mp_team_timeout_ot_max 1,mp_team_timeout_ot_add_each 1,mp_team_timeout_ot_add_once 1). Before, wingman and rush kept the values from whatever mode ran before (for example 4 x 30 seconds after a 5v5 match). Existing servers get these settings without changing their cfg files.live_wingman.cfg: overtime has 6 rounds (mp_overtime_maxrounds 6, was 4), a team playing short-handed gets no extra money (cash_team_bonus_shorthanded 0, was 1000), and team voice is recorded in the CSTV demo (tv_relayvoice 1).dryrun.cfgandsleep.cfg:cash_team_bonus_shorthanded 0(was 1000), the same aslive.cfg.- Removed
sv_damage_print_enablefrom the built-in settings used when a cfg file is missing. CS2 does not have this convar.
1.0.12
October 21, 2026Summary- Fixed missing or shared spawn points after an observer joined before the players. With a loaded match (
get5_loadmatch_url,matchzy_loadmatch), someone not on a team roster could use the team menu's auto-select (or wait for the menu to time out) and land on a team, take a spawn, and only then be moved to Spectator. The spawn stayed blocked by their body, so at round start a player spawned on top of another or not at all. Auto-select is now refused for anyone who is not on a team roster, and anyone who goes from a team to Spectator before the match is live has their body moved off the spawn. This also covers players who pick Spectator in a.matchor.scrimwarmup.
1.0.11
October 17, 2026Summary- A match config with
game_moderush,1v1orwingmannow always goes live with that mode's cfg (live_rush.cfg,live_1v1.cfg,live_wingman.cfg). The cfg was picked from the server's currentgame_mode, so a match whose game mode had not been applied yet went live withlive.cfg. - A match config with
"wingman": trueand"players_per_team": 1and nogame_modeis played as 1v1 (live_1v1.cfg) instead of wingman.
1.0.10
October 17, 2026Summarylive_1v1.cfgnow uses the wingman format: 16 rounds (MR8, first to 9), $8000 max money, 1:30 rounds, 40 second bomb timer, overtime MR2 with $8000. Existing servers keep their currentlive_1v1.cfg; delete it to get the new defaults, or set the values inlive_1v1_override.cfg.- New admin commands
.1v1,.wingman(.2v2) and.5v5(.competitive), also ascss_1v1,css_wingman,css_5v5: switch the server's game mode and reload the map, or change to the map given (.wingman de_inferno)..1v1runs in the wingman game mode and goes live withlive_1v1.cfg. Needs@css/map, only before a match has started. - In a pug,
matchzy_minimum_ready_requiredandmatchzy_ready_per_teamnow follow the game mode: at most 2 ready players for 1v1, 4 for wingman and 6 for rush (1, 2 and 3 per team). A lower value set by the admin still applies, and 5v5 is unchanged. - Round backups work again on the CS2 update of October 15, 2026. CS2 now rejects a round backup path that is absolute ("Rejecting round backup file path"), so no round backup files were written and every restore failed with nothing to load. MatchZy now sets a plain file name and finds the files in
csgo/orcsgo/addons/metamod/. The-allow_round_backup_fileslaunch option is still required. - New practice commands on the bot at your aim:
.kevlarand.armortoggle its kevlar or kevlar + helmet,.botgun <weapon>changes its weapon (both kept when the bot respawns),.dismissremoves it and.runboostputs you on it while it runs with your movement keys..dismissallremoves all bots. - New practice strategy recorder:
.stratrecrecords every living player on your team at once after a 3 second countdown,.strat [name] [me <role>]plays it back with one bot per role (all start together),.strat stopends it..savestrat,.liststratand.delstratkeep strategies per map instrats/<map>.json. - Strategies can be built one slot at a time:
.createstrat <name>, then.stratslot <name> <1-5>records that slot while bots play the slots already recorded..playgroup <name>plays a strategy,.stratsopens a menu for it all. .rec(new alias.record) freezes you for a 3 second countdown before recording. In practice.playreplays your recording (outside practice it is still.uncoach).- New practice command
.stoprecord: stops your.recor.stratrecrecording. A double right click or Shift + E while recording does the same. .shownadesmarkers now include a glowing grenade model (in the lineup's color) that shows through walls, so saved lineups can be found across the map..shownades <filter>shows onlysmoke,flash,he,molly,decoy,mine,globalor lineups whose name or description contains the text;.shownades allclears it.- New practice command
.expire: smokes and molotovs do not run out until you type it again. - New practice command
.coloredsmokes: turns colored smokes on or off without editingmatchzy_smoke_color_enabled. - New practice command
.xray: every player and bot glows through walls. - New alias
.observeme(css_observeme) for.fas. .dryruntakes an optional freeze time from 0 to 60 seconds (.dryrun 15); the default stays 6. In a dryrun.rr(and!rr) restarts the round,.rr 15restarts it with a 15 second freeze time.- New alias
.repair(css_repair) for.nobreak/.breakrestore. - A coach's scoreboard line stays at 0 for the whole match: it is cleared when a player becomes coach, after their end-of-freezetime death, after round MVPs and at round end and start.
- A coach is moved to its team's side after halftime on every map. Before, this only happened on maps with a coach viewing-spawn file.
- 1v1 matches (
"game_mode": "1v1") now run in the wingman game mode (game_mode 2) instead of competitive.
1.0.9
October 16, 2026Summary- New "Restore Round..." in
.maunder Match Control: pick the round to restore from a list (round, score, how long ago) instead of typing!restore <round>. With no live match, for example after a server crash, it lists the newest backups on disk, like.backup, and restores the whole match from the one you pick. Every pick asks for confirmation. - The knife round can now be turned on or off from the server console or the game panel console with
css_knife,css_rk,css_kr,css_kniferoundorcss_roundknife. Each call toggles it. Before, these commands did nothing outside the game. - New
game_modekey in match configs:competitive,wingman,rushor1v1. MatchZy switches the server to the rightgame_modebefore the map loads (rush isgame_type 0/game_mode 6, 1v1 runs in the competitive game mode)."wingman": truestill works. - Rush (3v3) matches go live with the new
live_rush.cfg, based on Valve's rush rules: 15 rounds, no halftime, 40 second rounds, $10000 max money. A match config whose maps are all rush maps (rush_001and otherrush_maps,aim_rush) is played as rush without settinggame_mode. A pug on a server ingame_mode 6or on a rush map also useslive_rush.cfg. - 1v1 matches go live with the new
live_1v1.cfg, with common 1on1 ladder rules: 24 rounds (MR12), $16000 max money, 10 second freeze time, 1:55 rounds, no short-handed bonus. - Without
players_per_teamin the match config, the team size now follows the mode: 1 for 1v1, 2 for wingman, 3 for rush, 5 for competitive. Before, wingman matches defaulted to 5. .matchsetupasks for the game mode after the series. Rush offers only the rush maps frommatchzymaps.cfg(orrush_001when there are none); the other modes leave rush maps out.- New override files
live_rush_override.cfgandlive_1v1_override.cfgwork like the other_overridefiles. - Fixed the CSTV bot being kicked when a match, scrim or hill went live while bots were still on the server (for example bots added with
bot_add). The mode cfg'sbot_quota 0removed the CSTV bot together with the other bots, and no demo was recorded. MatchZy now kicks the bots itself before the cfg runs. - With
tv_enable 1, MatchZy now checks that the CSTV bot is actually on the server before it sendstv_record. If the bot is missing, MatchZy restarts GOTV (tv_enable 0thentv_enable 1, needstv_enable_dynamic 1) and records a few seconds later. If the bot is still missing, notv_recordis sent and the chat says the match is not being recorded. - If the CSTV bot is kicked during a match, the demo so far is kept and a new demo starts once GOTV is back. Both files are uploaded at the end of the map.
- New
matchzy_series_end_shutdown_seconds(default 0, off): closes the server (quit) this many seconds after a series ends, also after a forfeit,.ggorget5_endmatch. It first sendsserver_shutdownwith reasonseries_endto the server's remote log URL and to the match's own, and waits for demo and backup uploads. A match loaded within the delay cancels the shutdown. Before, a forfeit put the server back in warmup and the players could ready up and play a match that sent no events. - With
matchzy_kick_when_no_match_loadedon, players still on the server when a series ends (also after a forfeit) are now kicked once the match is reset, unless the panel has loaded a new match by then. Admins stay. As in Get5, a match ended withget5_endmatchdoes not kick anyone. Before, only new connects were kicked, so the players left over could ready up and play a game no panel received. - Fixed a possible server crash on the map change between maps of a series. The server's cfgs can restore
bot_quotaon every level load, so the engine added bots while the players were still reconnecting; on a full server the next bot crashed it. MatchZy now putsbot_quota 0incsgo/cfg/gamemode_competitive_server.cfgandgamemode_competitive2v2_server.cfg(the file is created when missing, the line is added when the file has nobot_quota; a different value set by you is kept and logged as a warning). - Fixed the coach kill at the end of freezetime firing on the next map when the map changed during freezetime.
- Fixed no player stats being recorded in a game started without a loaded match while
matchzy_kick_when_no_match_loadedwas on. Every player on the server was dropped from the player list because there was no roster to find them on (log:playerData is empty during a live round). - New
matchzy_forfeit_join_grace_seconds(default 60): when the ready time of a loaded match runs out while a registered player of the team that is not ready has just joined, the forfeit waits up to this long so the player can pick a side and ready up. Each player gets it once per ready phase. Before, a player who connected 30 seconds before the deadline lost the series for their team while still choosing a side. - The ready time reminders now name the registered players a team is still missing, for example
Herning: 4/5 players on the server. Missing: Mio0p.A team that typed.readywhile short-handed used to think it was ready. .tech,.pauseand.tacin the ready phase of a loaded match now answer that pauses only work once the match is live, with the ready time left. They used to do nothing, and the ready time kept running.- The delivery of
series_start,going_live,map_result,series_end,demo_upload_endedandserver_shutdownis now logged with the match id and HTTP status, also when it succeeds or when no remote log URL is set, so a missing result can be traced in the server log. - Fixed no demos and no round backups being written on Windows servers. MatchZy passed
tv_recordandmp_backup_round_filea full path with a drive letter, which the engine rejects (record D:/...: invalid path). On Windows the path is now sent without the drive letter (/Steam/.../csgo/...), so demos and backups still land incsgo/and not incsgo/addons/metamod/. Linux servers keep the full path. - Fixed the bomb sometimes dropping outside the map when a Terrorist coach was given it. The coach is killed at the end of freezetime to spectate, and the death dropped the bomb at the coach viewing spot. The bomb is now moved to a Terrorist player before the coach is killed.
- Fixed the bomb lost outside the map when a coach picked it up: a teammate dropped it during freezetime, the coach stood on it, and the freezetime kill dropped it at the coach viewing spot. A bomb a coach gets at spawn or picks up is passed straight to a random Terrorist player, while the coach is still alive, and a bomb a coach drops for any other reason (for example dying before freezetime ends, with the bomb falling out of the map) is given to a live Terrorist player. The round-start hand-off also retries for 3 seconds when no Terrorist player has spawned yet. In a match with a coach, a coach still holding the bomb is checked twice a second and the bomb passed to a random Terrorist player, and a dropped bomb that a Terrorist player stands on for 1.5 seconds without picking it up (visible but not collectable) is replaced by a new bomb in that player's hands.
- On load, MatchZy now removes settings it no longer has (for example
matchzy_random_spawns) from an existingconfig.cfg. These lines printed "Unknown command" every time the file was run. Only the active setting line is removed: comments and commented-out settings stay, and settings MatchZy still uses are not changed. .showspawnsnow draws a box on the floor at each spawn with the spawn number above it, instead of a vertical beam. The box follows the floor (from the map's nav mesh) instead of the spawn point, which often sits a few units above the ground. The number is the one.spawn,.ctspawnand.tspawntake. The marker you aim at turns green and the center of the screen shows which spawn it is, so you can see what USE (E) will teleport you to before you press it. Aiming at the box or the number both work, and so does standing inside a box: USE then puts you exactly on that spawn, facing the spawn direction. To put a spawn on a key, bind the console command instead of a chat line:bind F1 "css_spawn 1".- New
.botshootin practice: bots shoot back. They stay on their spot, turn to the nearest enemy they can see and fire after.botreactiontime(0-1000 ms, default 500). Active smokes block their view. Bots lose their grenades while it is on. - New
.startroundin practice: clears thrown utility, respawns dead players and bots, puts every player on a different random spawn of their side, puts the bots back on their spot with full health and freezes everyone for 5 seconds with a countdown. - New
.botrespawn(bots respawn after dying, on by default) and.botlifereg(bots heal back to 100 HP, off by default) in practice. - New
.liferegon(your own health regeneration) and.allliferegon <true|false>(everyone) in practice. Regeneration is on by default, as before; turn it off to be able to die against.botshootbots. - New bot spawn pools in practice:
.botspawn <name>adds your spot to a pool,.placebot <number> <name>replaces the bots with bots on random spots of the pool,.placenewbotadds them to the current bots,.listbotspawnand.delbotspawnmanage the pools..showbotspawnshows the spots as green boxes; stand in one and press USE (E) to delete it. Pools are saved per map inbotspawns.json. - New
.kicklastbot,.botjigglerange <units>and.botjigglerandom(only a random half of the bots jiggle) in practice. - New
.slp,.tlpand.dlpin practice: save, teleport to and delete your saved location. After a death you respawn at your saved location. - New
matchzy_spawn_markers_enabled_default(default false): shows the.showspawnsmarkers automatically when practice starts. - Fixed a server stutter of about 130 ms when MatchZy is reloaded (
css_plugins reload) with players on the server.config.cfgnow runs once the commands it calls are ready instead of right away. - The server console no longer prints the startup lines about the round_start warm-up, the grenade functions, and the
css_mapcommand being left to CS2-SimpleAdmin. - Dryrun rounds now use the map's normal competitive spawns, the same as a match round. Dryrun used to move players to random spawn points every round, including spawn points a match never uses (for example 10 instead of 5 on Dust2 T), and some players were not moved, which could leave two players on the same spawn.
- Fixed
.nobotin practice starting an endless loop where a new bot joined every few seconds and was kicked again ("Kicking bot ... due to erroneous spawning"). - Fixed
.throwand.rethrow(.rt) sending a grenade thrown while running or jumping to a different spot than the original throw. The rethrow now starts from the grenade's exact release point. - The
.tachint printed when a match, scrim or hill goes live now shows the server's real tactical timeout settings (mp_team_timeout_maxxmp_team_timeout_time) instead of a fixed "4 x 30 seconds". Scrim and hill, which use 3 x 31 seconds, showed the wrong numbers. Withmp_team_timeout_max 0the hint says tactical pauses are off. .tacnow tells the chat how many tactical timeouts the team has left..helpbefore a match goes live now lists the player commands (.ready,.unready,.coach <side>,.tac,.tech). The admin commands (.start,.knife,.scrim/.playout,.endmatch,.matchin scrim mode) are only shown to admins; players used to see them without being able to use them. In a live match.helpshows how many tactical timeouts your team has left.- The chat hints on joining a team in warmup follow the same rule: players get
.readyand.help, admins also get one line with the current mode and the commands to change it (in Match Mode.scrim,.knifewith the knife round setting,.prac; in Scrim Mode.match,.prac). Before, every player was told to type.scrim, a scrim server suggested switching to Scrim, and the.prac/.knifehints went to every admin on the server each time someone joined. - The CSTV demo now starts on the first round after the going-live restart, about a second after LIVE. Before, it usually started 8 seconds after LIVE, in the middle of the first freeze time.
- The chat now says "CSTV is recording this match." about 3 seconds after the recording starts (was "CSTV Recording..." after 6 seconds). When a map ends, the chat says the recording is finished, with the demo file name, and whether it will be uploaded. The same message is shown when the recording stops early:
.endmatch, a reset, or a map change or reload during a match. The CSTV messages are now translated (English, Danish, Albanian). .clearand.cleanupin practice now also remove blood and bullet holes from the map for every player.- Loading MatchZy while a map is running (
css_plugins load MatchZy, as hosting panels do when switching modes) now registers the players who are already on the server. Before, the ready-up counted 0/0 and the match never started until players reconnected.server_readyis now also sent after such a load. - Unloading MatchZy (
css_plugins unload) cleans up after itself: warmup bots, the bot team and spawn/grenade markers are removed; after practice, cheats, buddha, infinite ammo, frozen bots, buy-anywhere, money, warmup, round time and team-damage settings are reset, so the next mode doesn't inherit them. - Unloading during the ready phase (
matchzy_ready_hint_style1 or 2) no longer leaves the next mode in a paused warmup with 60-minute rounds. - Unloading no longer freezes the server for up to 3 seconds while
server_shutdownis sent. .arcdraws at most 32 beam segments per grenade arc and keeps at most 256 arc beams on the map (oldest removed first), instead of one beam per tick of flight for every throw. Each beam is drawn by every client..shownadesmarkers are only sent to the players who turned them on (each player toggles them for themselves), and the lineup labels only within 1500 units. Before, one player's.shownadesput a beam and a world-text label per lineup on every player's screen.- During the ready phase with
matchzy_ready_hint_style1, the frozen 1:00 round timer is re-pinned about twice a second instead of on every tick, so clients no longer get a game rules update 64 times a second. player_disconnectis no longer sent for a player kicked on connect for not being in the match (or not on the whitelist), who never got aplayer_connect, nor for a player who leaves before Steam has authenticated them (it was sent with steamid0).- New practice commands
.recand.replay:.recrecords your movement and the grenades you throw (up to 60 seconds,.recagain stops),.replay [t|ct]lets a practice bot walk the last recording and throw the same grenades at the same moment, on the team you recorded on, or the one given..replay stopstops it. The bot is removed when the replay ends or is stopped. .replaybots now crouch where you crouched, and draw the grenade shortly before each throw and switch back to their gun afterwards. The throw animation itself is not played.- New
.replay looprepeats the path until.replay stop. It can be combined with the team:.replay ct loop. - New
.saverec <name>,.loadrec <name>,.listrecand.delrec <name>in practice: keep recorded paths (with their grenades) per map, inpathrecordings/<map>.jsonin the MatchZy config folder..loadrecmakes the path your current one for.replay. - New
.showrecin practice: draws your current path on the map (white, blue where you crouched), with a green post at the start, a red one at the end and a post in the grenade color at every throw spot. Only you see it;.showrecagain hides it. - Fixed round backups not being written on servers where the game folder is reached through a different path than the one the engine runs from (for example a Docker host path): CS2 printed "Rejecting round backup file path" and wrote no round file, so
.restorehad nothing to load. The backup prefix and the demo path now use the game folder of the running server binary, and MatchZy reads the round files and demos back from that same folder. - A live match with only a coach as human player (bots playing) no longer logs "[UpdatePlayerStats] Nothing to write" and a "no player stats collected" warning every round. Coaches get no stats row and bots are only recorded with
matchzy_stats_include_bots, so nothing is logged for that case, and the empty database write is skipped. Real problems (empty or invalid player data) are logged once per map. - CS2 now only writes and loads round backups when the server is started with
-allow_round_backup_files(without it: "Round backup files are disabled" and every restore fails). MatchZy logs a warning when the launch option is missing, and.restore/ the restore menu say so in chat instead of pausing the match and then failing. - Removed the
[round_start perf]log line. - Practice now turns off cash awards (
mp_playercashawards 0,mp_teamcashawards 0). A practice bot that was kicked or died on its own printed "+$300 for neutralizing an enemy" and "compensation for the suicide of" to the other team. The match, scrim and other mode cfgs turn them back on. - A
.replaybot that is dead when the replay starts is now waited for (up to 3 seconds, for.botrespawn) instead of ending the replay at once. round_endandmap_resultnow fillscore_ctandscore_tonteam1/team2with the rounds each team won on each side of the map. Both were always 0. The team objects also gainside(the side the team is on) andstarting_side(the side it started the map on),ctortas in Get5. Round backups keep the side scores, so they are right again after a restore.
1.0.8
October 6, 2026Summary- Killing a coach at the end of freeze time (or moving a coach back to their team) no longer gives money to the other team. A suicide in CS2 pays a random enemy the kill reward, and the coach removal counted as one.
1.0.7
October 5, 2026Summarymatchzy_ready_per_teamin a loaded match now also waits for the team's registered players: a team is ready once N of its players typed.readyand all players in its roster (at mostplayers_per_team) are on the server. Before, one.readywithmatchzy_ready_per_team 1started the match while teammates were still missing. A team can still start without a missing player with.forceready. Pugs without a match config are unchanged.- A team waiting for registered players is told in chat and on the ready panel how many are missing (for example
Team 3/4: 1 missing), in every ready mode. The hint no longer suggests.forceready, which stays available but optional.
1.0.6
October 5, 2026Summary- With
matchzy_kick_when_no_match_loadedon, a joining player no longer sees the mode hints (.scrim,.prac,.knife) in warmup, also before a match is loaded. Such a server only plays loaded matches. - Shorter console output on load: one line with the MatchZy version, config folder, map count and admin count, and one with the database type, instead of a line per step. Warnings and errors are logged as before.
- When CS2MenuManager is not installed, the console now says that the in-game menus (
.matchadmin,.matchsetup, ...) are off, instead of[Menu] warmup skipped: FileNotFoundException.
1.0.5
October 5, 2026Summary- The ready panel and the center ready text now say the short-handed team is still waiting for its missing players, or can use
.forcereadyto start without them, instead of only telling them to type.forceready. If the missing player joins,.readyis enough as usual.
1.0.4
October 5, 2026Summary- Each mode now starts from MatchZy's built-in default for that mode, then runs your mode cfg and its
<mode>_override.cfgas before. Settings your cfg leaves out (for example in an olderlive.cfg) no longer keep the value from the previous mode. Before,mp_weapons_allow_typecount 0inwarmup_override.cfgcarried into alive.cfgwithout that line, and nobody could buy in the match. Values set in your cfgs and overrides still win. Applies to warmup, knife, live, live_wingman, scrim, hill, dryrun and sleep; not to practice mode. Server-level settings (sv_hibernate_when_empty,tv_relayvoice,sv_lan,sv_pure,sv_steamgroup_exclusive,sv_kick_ban_duration,sv_competitive_minspec,mp_logdetail) are not filled in, so your server.cfg values stay. If you left a setting out of a mode cfg on purpose to keep an earlier value, set it in that mode's override. - The match config
cvarsare now applied after every mode cfg, also in warmup and the knife round, so they always win over the mode cfg and its override. Before, warmup.cfg and knife.cfg could overwrite them until the match went live. player_connectis now also sent for players who join while a match load is changing the map.- 4v5 in loaded matches: a team whose roster in the match config lists fewer players than
players_per_teamnow readies up with that many. A team registered with 4 players is ready once those 4 have typed.ready, without.forceready; a team of 5 still needs all 5. Coaches listed as players do not count; open ("any") and bot rosters are unchanged. - New
matchzy_forceready_max_missing(default1):.forcereadyneeds at leastplayers_per_teamminus this many players, so by default a team may be at most one player short (4 in a 5v5).min_players_to_readyin the match config can only make it stricter; before, a match config withmin_players_to_ready 1(common in panels) let a single player force-start the match.-1keeps the old rule (onlymin_players_to_ready). - A team that is waiting for a registered player who has not joined, but has enough players for
.forceready, is told in chat and on the ready panel how many are missing and that.forcereadystarts without them. - The ready panel (
matchzy_ready_hint_style 1) in a loaded match now counts towards what the teams need (for example7 / 9in a 4v5) and shows ready / needed per side, instead of usingmatchzy_minimum_ready_required. - With
matchzy_team_clantag_enabledturned off during a live match, team tags are removed at each player's next spawn.
1.0.3
October 4, 2026Summary- A short-handed team (for example 4 players in a 5v5 match) can start with
.forcereadyagain when the match config has nomin_players_to_ready. MatchZy usedmatchzy_minimum_ready_required(default 10, a pug's total over both teams) as the per-team minimum, so.forcereadyasked for 10 players. The default is now 1, as in Get5. Amin_players_to_readyin the match config works as before. - Join ready mode (
matchzy_ready_mode 1) withoutmin_players_to_readyin the match config waits forplayers_per_teamplayers per team.
1.0.2
October 4, 2026Summary- Workshop servers no longer crash at match end. A server started with
+host_workshop_map <id>and/or+host_workshop_collection <id>and no+map <name>is detected as a workshop server. A plainchangelevel <name>for a workshop map looked formaps/<name>.vpk, failed to mount it with players connected, and crashed the server (~CServerChangelevelState with non empty m_Clients). - Every map change MatchZy makes (map rotation,
.map, match load, veto, backup restore, map reload) now useshost_workshop_map <id>for workshop maps,ds_workshop_changelevel <name>for collection maps andchangelevelonly for maps in the server'smaps/folder. The boot map is linked to its+host_workshop_mapid. - A console
changelevel/mapfor a workshop map from the engine or another plugin is replaced with the workshop command, or blocked when the map cannot be loaded. - With auto changelevel disabled, a workshop server sets
mp_match_end_restart 1at series end so the engine restarts the map instead of changing level by name. - Match config, veto, backup and map rotation entries in workshop form (
workshop/<id>,<id>) now count as the current map when that workshop map is loaded, so no needless map change. .maptakes an unknown collection map only asws:<name>; workshop ids must be digits only.- A backup for a workshop map whose id is not known is refused instead of leaving a restore pending for the wrong map.
1.0.1
October 4, 2026Summary- New
matchzy_team_clantag_enabled(defaultfalse): while the match is live, players get their team'stagfrom the match config (team1.tag/team2.tag) as their scoreboard clan tag. Coaches keep their coach tag. The tag is reapplied on spawn and team change. - New optional
tagfield forteam1/team2in the match config. - No
[READY]/[UNREADY]clan tags in join ready mode (matchzy_ready_mode 1), where nobody types.readyand every player showed[UNREADY]for the whole warmup.
1.0.0
October 3, 2026Summary- New
player_connectevent: sent when a player joins a loaded match (and again after each map change) with the player and their IP address without the port. Players kicked for not being in the match are not sent. - New
player_sayevent: sent for every chat line (sayandsay_team, chat commands included) while a match is loaded, with the message as typed.round_numberis-1while the match is not live. A command that ends the match, such as.stopmatch, is still sent to that match's URL. {TEAM1}and{TEAM2}inmatchzy_hostname_formatandmatchzy_match_start_messagenow keep the spaces in team names (Team Nameinstead ofTeam_Name). Demo file names still use_.- Coaches are no longer listed among the players who are not ready (they never counted towards the ready-up).
0.8.99
October 3, 2026Summary- New
.friendlyfire(also.ffire, and.ffoutside practice mode): admins turn friendly fire on or off for the coming match, scrim or hill before it starts, like.knifefor the knife round. It is applied on top of live.cfg / scrim.cfg / hill.cfg and the match config on every map of the series, and cleared when the match is reset. In practice mode.ffis still fast-forward.
0.8.98
October 3, 2026Summary- New
matchzy_empty_shutdown_seconds(default0, off): closes the server withquitonce it has had no players for that many seconds. Bots and CSTV do not count, players reconnecting during a map change do, and the count also runs from server start, so a server nobody joins is closed too. Before quitting, MatchZy sends theserver_shutdownevent withreasonemptyandempty_seconds, and it waits while a demo or round backup upload is still running. Can be set per match in the match config'scvars.
0.8.97
October 3, 2026Summary- New setting names
matchzy_max_tech_pausesandmatchzy_tech_pause_time: they setmatchzy_max_tech_pauses_allowed/matchzy_tech_pause_durationand switch to Get5 pause rules, likeget5_max_tech_pauses/get5_tech_pause_time.get5_allow_technical_pausesetsmatchzy_enable_tech_pause. All three also work in a match config'scvarsblock.
0.8.96
October 3, 2026Summary- Ready-up time limit, Get5 style:
get5_time_to_start/matchzy_time_to_startsetmatchzy_forfeit_ready_timeout, and the newmatchzy_forfeit_veto_ready_timeout(get5_time_to_start_veto) sets a separate limit for the ready-up before the map veto (default-1, same as the map). - New
.addreadytime <seconds>(alsomatchzy_add_ready_time/get5_add_ready_time) gives the teams more time to ready up, at most the full time. - When neither team is ready in time the series now ends in a tie (
series_endwith no winner), as in Get5, instead of being cancelled. - The ready-up time limit reminders follow Get5: every minute, every 30 seconds in the last five minutes, and at 10 seconds. The clock does not run while a round restore is waiting for the teams.
- New join ready mode
matchzy_ready_mode 1: in a loaded match a team is ready oncemin_players_to_readyof its players are on its side, and the match startsmatchzy_join_start_delay(default 10) seconds after everyone has joined. - New
matchzy_tech_pause_mode 1for Get5 technical pause rules: a pause counts once it takes effect in freeze time, the pausing team can cancel it before then, it never ends on its own, and once it has lastedmatchzy_tech_pause_durationseconds either team can.unpause. A countdown is shown in the center of the screen.get5_max_tech_pausesandget5_tech_pause_timeset the limits and switch to this mode. The default (0) keeps the current behavior. - Technical pauses used are saved in round backups. Restoring a backup of another map or match (for example after a server crash) brings back its counts; restoring a round of the current map keeps the pauses already used.
- The default config.cfg is reorganized into sections with shorter, corrected descriptions, and now also lists
matchzy_prac_disable_magazine_drop,matchzy_grenadelibrary_labels,matchzy_grenadelibrary_label_scaleandmatchzy_botjiggle_range. Setting names and defaults are unchanged, and existing config.cfg files are not rewritten (compare withdefaults/config.cfg). matchzy_chat_prefixwith an empty value now falls back to the green[MatchZy]prefix, the same as the config.cfg default.- Fixed a possible server crash after a map change when
.shownadesmarkers,.showspawnsmarkers or.landmarkerbeams were active (the plugin kept using the previous map's entities). - Delayed rethrows (
.delaywith.rt/.throw) no longer fire after practice has ended or the map has changed. - Leaving practice now turns off all-talk,
buddhaand impact markers, which carried over into a dry run or warmup. dryrun.cfg also setssv_full_alltalk 0. - A practice bot kicked by the console or another plugin no longer keeps a bot slot reserved (the server kept adding and kicking a replacement bot).
- After a map veto that changes map, the match can no longer start on the old map before the map change (possible with join ready mode or a quick
.ready). - A surrender vote (
css_gg) from one team no longer stops the other team's vote from expiring. - Auto-pause: a long
matchzy_autopause_resume_delayno longer schedules several resumes, and the match is not resumed when a player dropped again during the delay. css_unpausefrom the server console now unpauses the match..matchsetupno longer replaces a match another admin or a panel loaded while the wizard was open.- A match start that was stopped while the database was still being set up no longer goes ahead later, and its database row is closed.
- Removing a retired setting from config.cfg no longer removes a commented-out setting right above it.
- Player names ending in a backslash no longer break the forced player names file.
- MySQL passwords containing
;work. - In the Get5 event format,
game_unpausedis sent when the pause after a round restore ends on its own,player_disconnectandround_startare never dropped while the receiver is unreachable, andfreezetime_endcounts and lists bots. - The built-in warmup settings (used when warmup.cfg is missing) now match warmup.cfg (free armor, CSTV voice relay).
- Albanian practice messages and a Danish coach message that were still in English are translated.
.loadbotposwithout a name spawns every saved bot again, one after the other (only one bot appeared).- The
.nadesmenu also lists the shared lineups added with.libadd, marked (G). .autopausetakes effect immediately: turning it on during a live map starts the check, turning it off ends an auto-pause in progress.- scrim.cfg, hill.cfg and knife.cfg now set
sv_deadtalk 1like live.cfg, so dead players can talk to their living teammates in scrims too. Existing cfg files are not rewritten.
0.8.95
October 3, 2026Summary- Live events now use Get5's event format by default (new
matchzy_events_format, defaultget5).player_death,bomb_planted,bomb_defused,bomb_explodedandgrenade_thrownmatch Get5's schema (nestedplayer/attacker/assistandweaponobjects,round_time, Get5 field names), pauses are sent asgame_paused/game_unpaused, and MatchZy's own live events (player_kill,player_hurt,player_blinded,grenade_detonated,bomb_pickup,bomb_dropped,freezetime_end) use the same objects. If your receiver reads the old flat fields (killer_name,victim_steamid, ...), setmatchzy_events_format legacyto keep the old format. - Get5 format:
player_disconnectsends a Get5playerobject, and the newbackup_loadedevent (round_number,filename) is sent when a round backup is restored, followed by that round'sround_start. The pause after a restore is sent asgame_pausedwithpause_typebackup,.pauseis reported astechnical,weapon.idis SourceMod's weapon ID as Get5 sends it (G5API stores it), andround_end'sround_numberis the rounds played when the round started, as in Get5. - Loading a match clears ready flags and force-ready from before the load and unpauses the game, as in Get5 (on the same map they used to carry over).
round_endnow reportsround_time(milliseconds since freeze time ended) instead of always 0.- New optional per-mode override files:
warmup_override.cfg,knife_override.cfg,live_override.cfg,live_wingman_override.cfg,scrim_override.cfg,hill_override.cfg,prac_override.cfg,dryrun_override.cfgandsleep_override.cfgincfg/MatchZy/. Each runs right after its mode cfg, so a server can change a few settings without editing the mode cfg itself. MatchZy never ships, creates or changes these files, so they survive every update. Settings from a loaded match config still apply on top. - The default warmup.cfg is back to normal CS2 warmup values:
mp_respawn_immunitytime 0,mp_weapons_allow_typecount -1(no purchase limit) andammo_grenade_limit_flashbang 2. Existing warmup.cfg files are not rewritten. If you installed 0.8.94 fresh and want the normal values, compare your warmup.cfg withcfg/MatchZy/defaults/warmup.cfg. To keep the 0.8.94 values (5 s spawn protection, no flashbangs), put them inwarmup_override.cfg. - Added
mikzy_versionandcss_mikzy_versionas aliases formatchzy_version. - Coach scoreboard tags (
[TEAM COACH]) now show up and stay: they were sent without a network update, replaced by[UNREADY]within a second during warmup, and removed when the match went live. - Practice commands (
.spawn,.bot,.break,.saveposand the rest) now reply "Practice mode is not active!" outside practice instead of doing nothing. - Less work on the game thread: the ready panel and the scoreboard ready tags only update when something changed, the
.shownadesmarker check only runs while markers are shown,whitelist.cfgis only re-read when the file changes, and the hostname is only set again when it differs. .forcereadynow works withmatchzy_ready_per_team: a force-readied side counts as ready even with fewer than N players, so a short-handed team can start the match and is no longer at risk of the forfeit timer..readycheckwithmatchzy_ready_per_teamcounts at most N ready players per side, so it no longer reports "waiting for 0" while one side still has nobody ready.matchzy_ready_hint_style 2withmatchzy_ready_per_team: the chat reminder only lists players on sides that are not ready yet, and shows the per-team minimum instead ofmatchzy_minimum_ready_required.- dryrun.cfg now sets
mp_weapons_allow_typecount 5, so a dry run started from warmup no longer keeps the warmup purchase limit. - prac.cfg now sets
mp_respawn_immunitytime 0, so practice started from warmup no longer gives 5 seconds of spawn protection (grenade damage on freshly spawned players and bots works again). Existing cfg files are not rewritten: add the line to your own dryrun.cfg and prac.cfg, or compare withcfg/MatchZy/defaults/. - When a live, scrim or hill cfg file is missing, the built-in fallback settings now show the round timer again (
sv_hide_roundtime_until_seconds 0). - The
map_changeevent is no longer sent at server start for the boot map (it had an emptymap_nameand arrived beforeserver_ready). - The first
.rt/.throwafter a server start no longer stalls the server while the rethrow code is compiled.
0.8.94
October 2, 2026Summarymatchzy_minimum_ready_requireddefaults to 10 again (was 2). Existing config.cfg files keep their value.- The reference copies of the default cfgs and
database.json.examplemoved fromaddons/counterstrikesharp/plugins/MatchZy/defaults/tocfg/MatchZy/defaults/(in the folder your server uses,matchzyorMatchZy). MatchZy rewrites them on every load, with a README.txt that explains how to use them. They are never executed. The oldplugins/MatchZy/defaults/folder can be deleted. - New convar
matchzy_ready_per_team(default 0, off): a team is ready once that many of its players have typed.ready, and the match starts when both teams are ready.1means one player from CT and one from T. Works for pugs and loaded matches; in a loaded match it replaces the rule that every player must ready up. - warmup.cfg:
mp_respawn_immunitytime 5,mp_weapons_allow_typecount 0andammo_grenade_limit_flashbang 0(no flashbangs in warmup) andsv_hide_roundtime_until_seconds 1, which hides the top timer during warmup. The live configs set it back to 0. matchzy_ready_hint_style 2now removes the native "Warmup" label in the middle of the screen, the same way style 1 does (the ready phase runs as a warmup that never ends, with respawns), without showing the HTML panel. The chat reminder is unchanged. live_wingman.cfg, scrim.cfg and hill.cfg now setmp_weapons_allow_typecount 5and scrim.cfg / hill.cfg setmp_respawn_immunitytime 0, so the warmup values never carry into a live game. Existing cfg files are not rewritten.- Practice: the grenade rethrow functions are resolved when practice starts, so the first
.rt/.throwof each grenade type no longer stalls the server. A rethrow that takes unusually long is logged. - Shorter server-frame stall when config.cfg is executed at plugin load: its
matchzy_*/get5_*command handlers are prepared in the background first. - No more
[ResetMatch - FATAL] [ERROR]: Global Variables not initialized yetat server start (the map-end reset now waits until the server has loaded a map), and the repeated[AutoStart] skippedlog lines are gone.
0.8.93
October 1, 2026Summary- New remote log events
server_ready(plugins loaded andconfig.cfgapplied),map_change(before a map change, with the target map when a map command requested it) andserver_shutdown(quit,_restart, fatal error or plugin unload). They are sent with or without a loaded match. - Fixed a server crash in practice when switching from
.specback to.tor.ct: the Linux signature for the engine team-join handler matched the wrong function since CS2 build 14182 and is updated ingamedata/matchzy.json. - Security: a match config's
cvarsblock (and a backup that carries it) can now only set real convars and MatchZy/Get5 settings. Action commands such asmatchzy_loadmatch_url,matchzy_loadbackupandget5_endmatch, andmatchzy_everyone_is_admin, are ignored and logged.matchzy_demo_pathandmatchzy_demo_name_formatmust be relative paths without... - Security: team names, tags and flags loaded from a round backup are cleaned the same way as match config team names.
- Match configs with
1/0forskip_veto,clinch_seriesorwingmanare accepted (they were refused as "should be a boolean"). get5_endmatch/.forceendafter a series has ended now replies that the series is over, instead of sending a secondseries_endand overwriting the winner in the database. Ending a series between two maps no longer writes a result for the next, unplayed map.- Bots are kicked one by one by user id instead of with
bot_kick(warmup bots, bot teams, map changes, the warmup fallback config), so the CSTV bot is never kicked with them. - A round restore that is refused because the backup has no usable round data no longer changes the running match first (match id, teams, sides, timeouts). A queued restore that is refused when the match goes live now starts the match normally instead of leaving the server in warmup.
- Chat commands that take an argument (
.map,.ban,.pick,.spawn,.sp,.team1,.back, ...) only run when the command word matches exactly, so.mapxno longer runs.mapand.spec xno longer runs.spawn. - A series is clinched once the trailing team can no longer catch up, so drawn maps are counted (a BO5 at 2-0 with two draws no longer plays a fifth map).
get5_endmatch team1|team2/.forceend team1|team2during a live map now sendsmap_resultfor that map (won by the named team) beforeseries_end.- Veto: a captain who changes team is replaced by a teammate (the veto hung waiting for them), and a captain who left during the veto countdown is replaced instead of aborting the veto.
- Match config
cvarsthat set an on/off or number MatchZy setting such asmatchzy_enable_tech_pauseormatchzy_tech_pause_durationnow take effect (they were rejected as "can't be converted") and are restored at series end. - Changed convars are restored as
1/0instead ofTrue/Falseand with a.decimal separator on every server locale. 64-bit float convars are read correctly. - Match load URLs are logged and shown without their query string or credentials.
- The series score is still written to the database when the map row update fails.
- Practice:
.savenadeand.importnadesave positions with a.decimal separator on every server locale; lineups saved with,still load. A lineup with an invalid position is refused with a message instead of an error..importnadeno longer turns1,5into15. - Practice:
.last,.loadposand.loadnadeno longer move dead players or spectators. - Practice:
.fasno longer adds a death to the players it moves to spectator. - Practice: ending practice during
.ffresets the timescale and unfreezes players right away. - Team names with spaces are shown in full on the scoreboard (
mp_teamname_1/mp_teamname_2are now quoted). - Demo and round backup paths are always quoted, so they also work on Windows servers.
tv_record_immediate 1is only sent when the server has that convar. - SQLite databases use WAL mode, so overlapping writes at the end of a map wait less for the file lock. Back up
matchzy.dbtogether with its-waland-shmfiles. - A restore requested during warmup now only says that it is queued (it used to print "Backup file loaded successfully" first).
- Practice: if a grenade signature in
gamedata/matchzy.jsonresolves to an empty address,.rethrow/.throwindexuse the entity fallback instead of failing with "Invalid function pointer". - Practice: the server log says why a thrown grenade was not recorded.
- The release zip no longer contains anything under
cfg/, so extracting an update never overwrites yourcfg/MatchZy/files and no longer creates a secondcfg/MatchZy/folder on servers that usecfg/matchzy/. MatchZy writes any missing cfg on load. Reference copies of the current defaults are inaddons/counterstrikesharp/plugins/MatchZy/defaults/. - The default cfgs written on a fresh install are now the same files the release zip used to ship. The plugin's built-in copies had drifted from them (for example
mp_match_end_changelevel,mp_round_restart_delay,mp_win_panel_display_time). Existing cfg files are not changed. admins.json: every listed SteamID64 is a full MatchZy admin again. The value is free text (for example the player's name) and is no longer read as admin flags; use CounterStrikeSharp's own admin system for limited admins.- A remote log URL or header set in a match config's
cvarsnow only applies to that match. The next match goes back to the server's ownmatchzy_remote_log_urlsettings instead of keeping the previous match's URL.series_endandmatch_cancelledstill go to the URL of the match they belong to. - Events are sent with a 60 second timeout instead of 10 seconds, and a failed send names the event and host in the log.
- Loading a match config with a
matchidthat was already used reopens that match in the database: the match row's end time and winner are cleared when its first map starts, and a replayed map's result is cleared when it starts again. - Stability: dropped grenades cleared after a practice
.t/.ctswitch, and the pawn of a player who leaves practice, are now removed with the engine's Kill input instead of being freed directly (the "WriteEnterPVS: GetEntServerClass failed" crash class). - Stability: moving a player to spectator (
.spec,.fas, players outside a loaded match) waits until the player is actually dead before changing team, also for a player who cannot take damage. Changing team on a living player can crash the server. - Stability: the veto no longer moves spectators onto a team with a plain team switch (which left them stuck observing), and a spectator joining a team is never respawned when the server's team-join signature is missing.
- Stability:
.coachtestno longer strips weapons inside the chat command handler. - A match that failed to start (an error during the knife or go-live setup) no longer blocks every later ready-up until a map change.
- A matchid allocated after the match was stopped or replaced is discarded instead of being given to the next match.
- Live events read their target URL and match id when the event happens, not later on a background thread, so an event sent while a match resets is no longer lost or sent to the wrong place.
.unpause(both teams) or an admin unpause now ends an auto-pause even when a team is still short: the match plays on, and only a further drop in players pauses it again. Before, the match paused again within 10 seconds.- A round restore that has to set the round up again (a restore queued in warmup, or after a crash) now records a demo, and a scrim or hill game is restored as a scrim or hill game instead of a match.
- A restore that needs another map no longer loses the match when it was started with
.matchinstead of a match config. - A map change from outside MatchZy in the middle of a loaded match now sends
match_cancelledwith reasonmap_changedand closes the match in the database. - A force-ready only lasts for the ready phase it was given in (it carried over to the next map and after the veto).
- Forfeits,
.ffwwalkovers and.ggsurrenders now stop and upload the demo, sendmap_resultfor the map in progress beforeseries_end, and write the real map score (a score of 16 was written before, wrong for MR12). All of them give the winner the series. - A second end-of-map event can no longer count the same map twice in the series score.
get5_statuscan reportpending_restore.- The stats export JSON names no winner for a drawn map (it named team2).
- Performance: coach matches no longer scan the whole entity list once per player at every round start (the spawn points are cached per map),
.autoclearscans once per grenade instead of six times, bomb defuse and explode events reuse the site found at the plant, the whitelist file is only read when the whitelist is on, and chat from spectators during match setup no longer rebuilds the player list. - Practice:
.lnand the nades menu load the lineup you picked. A shared lineup in the menu,.ln #N, or a name with a typo used to load your own closest-named lineup instead; a name that matches nothing now says so. - Practice:
.delbotposonly deletes a saved bot position with exactly that name (a typo deleted another one)..loadbotposno longer loads an unrelated position for a typo. - Practice:
.exitdryonly works during a dryrun (in practice it restarted the game). Starting.dryfrom practice turns off the practice markers, impacts and grenade preview first, and leaving practice stops.botjiggle. - Practice: a delayed rethrow no longer fails when the player left during the delay.
- Practice:
.lnalways replies, also when savednades.json cannot be read. - Help texts:
.ffskips 10 seconds,.crouchbotadds a crouching bot,.importnadehas no.inchat alias, and non-admins are no longer pointed to.mhelp. - The technical pause "not enabled" message showed a raw translation key.
- The admin and match setup menu titles no longer contain the chat prefix's colour codes.
- New
matchzy_ready_hint_style 2: no center text during the ready phase. Instead, like upstream MatchZy, the chat lists the players who are not ready everymatchzy_chat_messages_timer_delayseconds (in each player's language). Styles 0 and 1 are unchanged. .coachonly works in warmup and during freeze time. Becoming a coach in the middle of a live round left the team a player short for the rest of the round.- Practice:
.rs,.grtand.fasare admin commands now (they affect every player on the server). - Live events are sent through one queue in the order they happened, so a receiver no longer gets
round_endaftermap_resultormatch_unpausedbeforematch_paused.series_endno longer waits a fixed half second. When the receiver keeps failing, the high-volume live events (kills, damage, grenades, ...) are dropped for 30 seconds at a time so they cannot hold up match events; live events give up after 10 seconds, match events after 60. - Advanced stats (rating, KAST, opening duels, trades, clutches) are stored in each round backup and put back on a round restore, so the rounds that are replayed are no longer counted twice.
- An auto-pause that both teams agreed to play through stays lifted after halftime (the agreed player counts followed the side, not the team).
.t/.ctwhile still in the team menu asks the player to pick a team first instead of forcing the join.- A queued restore from a
.matchgame is dropped when the server switches to practice or sleep. - Translations: about 250 chat messages that were English-only (coach, practice, pauses, backups, forfeits,
.gg,.ffw, admin replies and more) are now in the language files, with Danish and Albanian translations. Messages sent to one player use that player's language instead of the server's. The ready-phase center hint (classic style) and the "not ready" list are shown in each player's own language too. Practice toggles such as.god,.impactsand.trajnow say On/Off instead of True/False.
0.8.92
October 1, 2026Summary- Fixed round backup files (
matchzy_<matchid>_<map>_roundNN.txt) being written tocsgo/addons/metamod/instead ofcsgo/on Metamod servers since the September 22 CS2 update. Backups were saved without round data, so.stopand.restorehad nothing to load.
0.8.91
September 29, 2026Summary- New
matchzy_coach_listed_only(default false): in a match loaded from a match config, only the SteamIDs in a team's"coaches"list may coach that team, and a team without a list has no coach. Usematchzy_coach_enabled falseto turn coaching off completely. - The coaching docs now list who can coach in each case (no match loaded, match config with and without a
coacheslist, admins, coaching disabled) with a full match config example.
0.8.90
September 29, 2026Summary- Fixed a server crash about one second after a player connected to a server with a loaded match (0.8.88 and 0.8.89). The automatic team placement on connect forced the engine's team join on a player who was still in the team menu. Players now pick a team from the menu again, as before 0.8.88; the roster lock still only lets them join their own team, and a player who ends up on the wrong side, is off the roster or is a substitute on a full side is still moved.
- New
matchzy_loaded_match_hide_mode_hints(default true): in a match loaded from a match config (JSON file, URL or.matchsetup), a joining player only sees "Please type .ready to ready up!". The mode hints (.scrim, .prac, .knife) and the admin help line are not shown, since they do not apply to a loaded match. Set it to false to show them as before.
0.8.89
September 29, 2026Summary- Tactical timeouts in overtime: live.cfg now sets
mp_team_timeout_ot_add_once 1,mp_team_timeout_ot_add_each 0andmp_team_timeout_ot_max 5, so each team gets one extra tactical timeout (.tac) when the match goes to overtime. The old live.cfg had nomp_team_timeout_ot_add_once, so a team that had used its timeouts in regulation had none in overtime.mp_team_timeout_maxis now 4 (was 3). These are only defaults: both config.cfg and live.cfg can be edited to your needs. Set the timeouts incfg/MatchZy/live.cfg(it runs when the match goes live, so the same lines in config.cfg would be overridden), or per match in the match config'scvarsblock. Note that live.cfg is part of the release zip, so extracting an update over the server replaces it; keep a copy of your edits (config.cfg is never replaced). - New
matchzy_overtime_pauses_per_team(default 1, 0 = no limit): how many times each team may use.pausein each overtime period. Admin pauses are not counted; regulation is unchanged. Chat announces the overtime allowance when overtime starts. Change it to your needs in config.cfg. .pauseno longer requires tech pauses to be enabled. It was refused whenevermatchzy_enable_tech_pausewas false.
0.8.88
September 29, 2026Summary- Fixed a knife round being played although the match config sets the side (
"map_sides": ["team1_ct"]and similar). Every player who connected during warmup switched the knife round back on. The same reset also undid.scrim/.hill(no knife) and an admin's.knife off, andmatchzy_knife_enabled_default falsewas lost after the first match reset. In a loaded matchmap_sidesnow always decides. - Players in a loaded match are put on their team automatically when they connect (no team menu), listed spectators on Spectator, and anyone not in the match on Spectator. Players already on the server when a match is loaded are moved to their team as well. A player the game auto-assigned to the wrong team, or who came from Spectator, is moved back too; before, only a player with a live body was corrected, so someone could end up on (and coach) the other team.
players_per_teamis enforced when players join: substitutes listed in a roster wait on Spectator while their side is full. Side swaps (halftime, knife switch) are not affected.- After a veto that keeps the current map, and after every map change of a loaded match, players are moved to the sides of that map.
.coachwithout acoacheslist now requires the player to be on that team's roster. A player not in the match (for example an admin exempt from the kick) could coach either team.get5_endmatch/.forceend/!forceendnow follow Get5: without an argument they cancel the match (in any state, including warmup and veto), withteam1orteam2that team wins the series. They used to do nothing outside a live map and, mid-map, score the map for the team ahead and move a series on.- A stopped or cancelled match sends
match_cancelledand closes its database row also when it is stopped before going live (warmup, veto, knife, between maps). - A database outage at ready-up no longer replaces the match id with -1 (which silenced every event for the map).
- The veto no longer hangs when a captain leaves: a teammate takes over, or the veto is aborted when the team is empty.
skip_vetonow defaults to false like Get5: a map pool larger thannum_mapsis vetoed unless"skip_veto": trueis set. A pool of exactlynum_mapsmaps is played in order as before. The Get5 keysside_type(standard, always_knife, never_knife, random) andveto_first(team1, team2, random) are now read.skip_veto,clinch_seriesandwingmanaccept 1/0 as well as true/false.- Match config
cvarsare applied before the live restart, so round 1 already uses them, andmp_overtime_enable/mp_match_can_clinchfrom the match config are no longer overwritten by the live.cfg values. matchzy_remote_backup_url(get5_remote_backup_url) now uploads every round backup (with the Get5 headers). The setting was read but never used.- Surrender (
!gg) needs votes from the players on the team (all but one), not frommin_players_to_ready: withmin_players_to_ready 1one player could surrender. It is not available in a multi-map series (it would end the whole series), coaches cannot vote, and votes reset at halftime and on a new match. series_endis sent aftermap_resulthas been delivered.map_pickedandside_pickeduse a 0-basedmap_numberlike the other events.get5_statusreports side asct/tand ready state and connected players per team.- Pause and unpause messages name the right team after halftime.
- The previous match's veto no longer decides who starts the next veto.
- Security: entries in the match config
cvarsblock must be a real convar or amatchzy_/get5_setting with a plain value; anything else (e.g.quit, or a value with a quote or;) is ignored and logged.rcon_passwordcannot be set from a match config. Map names from a match config, veto, backup or.mapmay only contain letters, digits and_ - . / :. Match config loads that fail (invalid JSON,num_mapsbelow 1, a team without a name, a non-numericmatchid) are refused and reset cleanly. The load URL's auth header value, the match config body and presigned demo upload URLs are no longer written to the log. - MatchZy's own
admins.jsonnow honors flags in its value: a value such as"@css/chat"grants only the commands that accept that flag. An empty value or text without flags (for example the player's name) keeps full admin, as before. - MatchZy settings set in a match config's
cvarsblock (for examplematchzy_kick_when_no_match_loaded,matchzy_knife_enabled_default, demo and backup upload settings) are restored at series end like the other cvars; they used to stay on the server. The remote log settings are kept soseries_endstill reaches the match's URL. A stopped or cancelled match now restores itscvarstoo. - New
matchzy_forfeit_ready_timeout(default 0 = off): in a loaded match, a team that is not ready this many seconds after the ready phase of a map began forfeits the series; if neither team is ready the match is cancelled (match_cancelledwith reasonno_show). Reminders are printed at 5, 2 and 1 minute(s) and 30 seconds. - New
matchzy_forfeit_leave_timeout(default 0 = off): in a loaded match, a team with no players left on its side for this many seconds during a live map forfeits the series. - New
matchzy_veto_step_timeout(default 0 = off): seconds a veto captain has for each ban, pick or side choice before it is made at random (a random map, or CT for a side). - New
knife_wonevent (Get5 format:team,side,swapped) when the knife winner has chosen a side. - The
1kstat (rounds with exactly one kill) is filled in the stats events. .importnaderefuses codes with invalid numbers, and imported lineups load as smokes instead of failing..matchsetup: a stale menu of an admin whose wizard was taken over can no longer change or cancel the new admin's setup.- Fixed
.t/.ctfrom spectator in practice falling back to the old behavior (player left dead with a team-menu hint). The gamedata key had been renamed toCBasePlayerController_HandleCommand_JoinTeamingamedata/matchzy.jsonwhile the plugin still looked upCCSPlayerController_HandleCommandJoinTeam. Both names are now accepted. - Match configs that list team
"players"as an array of SteamID64s are accepted again (as strings or as plain numbers). The load check only allowed the object form. Adding a player to an array roster withmatchzy_addplayernow stores the SteamID instead of the name, andmatchzy_removeplayerremoves from array rosters and spectators too. matchzy_remote_log_urland its header settings set in config.cfg are kept when a match config is loaded. Before, loading a match dropped them, so no events were sent for that match unless the URL was repeated in the match config'scvarsblock.- The default for
matchzy_minimum_ready_requiredin a newly generated config.cfg is now 2 (was 10), matching the plugin default. The default formatchzy_chat_messages_timer_delayis now 21 seconds in the plugin as well (was 13). Existing config.cfg files keep their values. - On/off settings such as
matchzy_whitelist_enabled_default,matchzy_knife_enabled_defaultandmatchzy_allow_pausenow accept1and0as well astrueandfalse. Before,1could not switch a disabled setting on. matchzy_admin_chat_prefixwith an empty value now resets the admin prefix. It reset the normal chat prefix instead..versionin chat now replies. It printed nothing..skipveto/.sv,.rmap,.surrender,.configs,.kniferound,.autopauseand.listbackupsnow work with the dot prefix, as.mhelplists them. Before, only the!form worked..mhelpalso shows the real team name commands (.team1/.team2),.rrestoreinstead of.rr, and lists.forceendseparately.- Fixed a loaded match being wiped by its own map change. The map change to map 2 of a series, and to the map picked in the veto, reset the whole match (series score, rosters, veto result), so the next map came up as an empty server. A cross-map round restore was lost the same way. A map change in the middle of a live map still resets the match; a map change during warmup of a loaded match keeps the match and changes back to the match's map.
- Fixed warmup never ending after a map veto. The match-start guard stayed set after the veto, so the second ready-up was ignored.
- A forfeit or surrender reports its winner in
series_endeven when the series score is level. - Fixed every finished series being announced as a tie ("X and Y have tied the match") with
series_endwinner "none". A drawn scrim or pug no longer announces "Draw has won the match". map_resultandseries_endreport the correct winning side, and a draw as side "0" / team "none". Before, the side was "2" whenever team2 won and a draw was reported as a team2 win.round_endwinner.teamis now the team that won the round. It was the team ahead on score.- A drawn map in a series no longer breaks the series (the next map lookup ran past the end of the map list).
- matchzy_stats_matches gets its winner and end time when the series ends, not after every map. Surrender (
css_gg) stores the map's round score in matchzy_stats_maps instead of the series score. - The last round's player stats are written to the database before the map's CSV export.
- Stats events now fill
kast,trade_kills,first_kills_t/ct,first_deaths_t/ct,flash_assists,friendlies_flashed,team_kills,suicides,knife_kills,bomb_plants,bomb_defusesand1v3-1v5(human players). They were always 0. - A suicide no longer counts as a kill for KAST, and team kills no longer count as opening or trade kills.
- Coaches are left out of player stats, the CSV, the stats JSON, the damage report,
player_death/freezetime_endevents and alive counts. Their end-of-freezetime death used to be the first death of every round, which took the opening duel stats away from the players. freezetime_endreportshas_helmetandhas_defusercorrectly. They were always false.player_death,bomb_planted,bomb_defusedandfreezetime_endare sent for live rounds only, not during the knife round or side selection.- New
player_killevent for every kill in a live round: killer, victim, assister (and whether it was a flash assist), weapon, headshot, wallbang, no-scope, through smoke, blind, distance, team kill, opening kill, trade kill, the killer's HP, and the killer's kills this round and this map.player_deathis still sent as before and also covers suicides and world deaths. - New
player_disconnectevent (user id, SteamID, name, team, reason) while a match is loaded. - Disconnect cleanup (ready check, player list, coach list, practice data) no longer requires the leaving player to still have a valid, connected pawn, so it also runs for spectators and players already marked as disconnecting.
- Auto-pause now triggers when a player leaves a full match. It required 10 connected players, which is exactly what a disconnect takes away. Only players on T/CT count (not spectators or coaches), so a smaller match is never auto-paused.
- A manual or admin pause is no longer auto-resumed because of an earlier auto-pause.
matchzy_max_tech_pauses_allowedandmatchzy_tech_pause_durationare now enforced: each team gets its tech pauses per map, and a tech pause ends on its own when the time runs out (-1 = no limit). Unpausing earlier, or a later regular or admin pause, cancels that countdown.matchzy_allow_unpause falsenow disables.unpause. The setting existed but was never checked.matchzy_allow_pause,matchzy_allow_unpause,matchzy_stop_command_no_damageandmatchzy_asay_console_enabledare added to config.cfg (appended to existing files with their current defaults)..stopworks in round 1 of scrim and hill (it looked for a backup file name that was never written).- A round restore during the last round of a half no longer skips the halftime side swap, which mixed up team scores and stats for the rest of the map.
.match,.scrimand.hillno longer change knife/playout settings when a match is already running. Typed during the knife round they could leave the match stuck..match/.scrim/.hillcould reset a loaded match after the server had been in sleep mode once.- A match start no longer continues if the match was reset while its database row was being created.
- A failed demo recording is no longer reported as the match demo, and the part recorded before a stall is still uploaded when the restart fails. A restarted recording no longer overwrites an earlier demo with the same name (the new file gets
_part2, ...), and all parts of a map's demo are uploaded. Demo uploads stream the file instead of loading it into memory. - The advanced stats JSON counts rounds from the scoreboard, so a replayed round no longer lowers ADR and rating.
- The coach no longer causes a possible crash when the bomb is moved from the coach to a player, or when a coach on the wrong team is moved back.
.matchsetupis no longer locked for everyone when the admin using it closed the menu or left. The lock is released when its owner is gone or after 3 minutes without use..rrand the admin menu's "Restart Round" restore the current round in a match (.rrstill restarts the round in practice). They did nothing outside practice..forceendand!forceendnow do the same thing (end the match through the normal match-end path, likeget5_endmatch).- Practice:
.fftwice in a row no longer leaves players frozen, and the server no longer stays at 5x speed when practice ends during a fast forward. - Practice:
.timerstops when practice mode ends instead of running into the match. - Practice:
.backno longer teleports spectators or dead players. - Practice:
.hidespawns/.showspawnsno longer remove bot position, coach spot or grenade markers. - Practice: a damaged
botpositions.jsonor grenade library file is backed up and never overwritten by a later save. - Practice: fixed a possible server crash when a crouching bot was kicked right after spawning.
- Practice:
.delay 0clears a grenade delay, and.delaywith no throw history no longer errors. - Practice: best/worst spawn commands no longer error on maps where spawns had not been collected yet.
- Practice: stray bots are kicked by id, so a practice bot with the same name is never kicked by mistake.
- Added a documentation site at https://matchzy.miksen.me.
0.8.87
September 28, 2026Summary- New optional
"coaches"list per team in the match config (object keyed by SteamID64 or an array, like"players"). Listed coaches can join their team, are not kicked bymatchzy_kick_when_no_match_loaded, and become its coach automatically. When a team has a list, only those SteamIDs can.coachit. See the README. - Coaches no longer count toward
players_per_teamin the ready check and no longer need to.ready.
0.8.86
September 28, 2026Summary- New
matchzy_coach_enabled(default true): set it to false to turn off.coach/css_coach. Players who are already coaching stay coaches until.uncoachor the match resets. .coachnow only lets you coach the team you are on..coach ctwhile on T (or from spectator) is refused, so a player can no longer register as the other team's coach.- New live remote log events:
grenade_thrown,grenade_detonated(smoke, flash, HE, molotov with position),player_blinded(who flashed whom, duration, team flash),bomb_pickup,bomb_droppedandbomb_exploded. Sent while the match is live and a remote log URL is set, likeplayer_hurt. bomb_plantedandbomb_defusednow report the correct site. Previouslysitewas almost always "B".
0.8.85
September 27, 2026Summary- New
matchzy_stats_include_bots(default false): bots on CT/T get player stats in the database, CSV and stats events. Bots have no SteamID, so each is recorded under a stable id of 90000000000000000 plus a hash of its name (one row per bot per map). Bots are still not tracked as match players, so the ready system, veto and pauses are unchanged. - Players vs bots matches: a team with
"players": "any"takes any human not on another roster, and a team with"bots": true(optional"bot_difficulty"0-3) is filled with bots up toplayers_per_teamand kept on its side through warmup, live, halftime, overtime and round restores. A bot match needs a fixed map list (the load is refused if it would veto), draws knife sides at random, and the bot side always counts as ready/unpaused and is ignored by autopause. Bot stats are recorded automatically;.warmupbotsis disabled in these matches. See the README. - A live round with only bots now logs that plainly (and names the convar) instead of the roster warning "Every connected player resolved to CsTeam.None".
- Removed
matchzy_coach_debugand its coach/spawn debug log lines. Coaches are now always killed at the end of freezetime. - Removed the
[rethrow perf]timing line that slow practice rethrows printed to the server console. - Practice: a normal throw now stores the grenade's launch velocity reliably, so
.rethrow/.rtno longer spawns nothing after a throw was recorded with zero velocity.
0.8.83
September 16, 2026Summary- Prepare managed rethrow entry points during background load warm-up to reduce first-use JIT work. Flash timings now separate entity creation from DispatchSpawn, and replayed projectiles receive the recorded item index on the managed creation path too.
- Reduced repeated native player reads during round damage initialization, death tracking, and practice marker visibility checks. Added slow arc-render timings and released HTTP response resources after remote event delivery.
- Practice rethrows resolve only the requested grenade factory instead of initializing all four on first use. Slow rethrows log signature-resolution, spawn, and setup timings to help diagnose gameplay stalls.
- Round backups now serialize match and team configuration on a background worker using independent snapshots, reducing game-thread work while retaining the existing restore format.
- Warm selected round-start methods and JSON serializer metadata in the background when the plugin loads, reducing first-use initialization work. Live testing is still required to determine whether this reduces the observed round-start stalls.
- Round start no longer walks the full entity list to set the scoreboard team names, no longer re-reads live.cfg on rounds 1 and 2 (the file is cached and re-read only when it changes on disk), and encodes the scoreboard part of the round backup off the game thread.
- Round start now logs a "[round_start perf]" line whenever its game-thread work exceeds 5 ms, naming the stages that went over.
0.8.82
September 15, 2026Summary- Practice bot commands (.bot, .tbot, .ctbot, .crouchbot, .boost, .crouchboost) now correctly refuse to run on servers started with -nobots. The check read the command line through the .NET runtime, which inside CounterStrikeSharp does not return the server's real launch options, so the flag was never seen. With bots disabled the engine still creates a controller and pawn for each bot_add but gives it no player model, which is why .bot appeared to place an invisible bot that could still be shot and damaged. The flag is now read from the engine's own command line.
- .warmupbots now refuses to run on a server started with -nobots as well, instead of setting a bot quota the engine answers with invisible bot shells.
- .nobot used a different, broken -nobots check (it looked for a value on a flag that carries none), so it never matched either. It now uses the same check as the rest of the bot commands.
- The "bots are disabled" notice is now sent only to the player who ran the command, in that player's language, instead of being broadcast to everyone in the server's default language.
- Launch options are now read from the engine command line for every check that uses them, so -nohltv (used to skip CSTV and demo recording) is detected on servers where it previously went unnoticed.
- Fixed .map being ignored after a map change. The duplicate-command guard stored a timestamp from the previous map, and because server time restarts on every map load the next .map looked like a repeat and was dropped until the server had been running long enough. Changing map twice in a row works again.
0.8.80
September 4, 2026Summary- Fixed the plugin starting warmup on top of a practice session when it was loaded from a mode-switch script. A script such as
css_plugins load "MatchZy"; matchzy_autostart_mode 2; css_pracran css_prac correctly, but the plugin's own config.cfg exec (queued at load) landed after the script's lines and reset matchzy_autostart_mode to 1, so the delayed autostart then exec'd warmup.cfg over prac.cfg. The explicit mode commands now consume that map's autostart, so the delayed autostart no longer overrides a mode an admin already chose. - css_prac, css_match, css_scrim, css_exitprac and css_sleep now also write the chosen mode to matchzy_autostart_mode (2, 1, 1, 1, 0), so the mode survives a map change. Before, a map change always fell back to the value in config.cfg, which sent a practice server back to warmup when a mode-switch script reloaded the map to apply game_alias. css_dryrun is unchanged (no autostart mode maps to dryrun).
- Practice started by autostart on a fresh map (matchzy_autostart_mode 2, or the mode-switch flow above) now becomes a real practice round as soon as the first player connects. prac.cfg ran before anyone was in, so its mp_warmup_end did nothing and the engine started its own warmup on the first connect: the player sat through the server's mp_warmuptime countdown before practice settings (60 min round) took effect. The warmup is now ended right away. The built-in fallback practice (no prac.cfg) keeps its paused warmup and pins mp_warmuptime to 9999 so a short inherited value does not run a countdown.
- Bullet impacts (sv_showimpacts) are now on for every player when practice starts or a player joins practice; .impacts turns them off per player. Before, each client was sent sv_showimpacts 0 on connect and at practice start, so nobody saw impacts until .impacts, and coming from another mode (deathmatch) the client kept that mode's 0. The .impacts toggle also assumed the wrong starting state, so it could take two presses.
0.8.79
September 2, 2026Summary- .mhelp now shows each admin the commands they can actually run. The chat summary is built from the same permission checks the commands use, grouped by category, so an admin with only the map/practice flag (SourceMod "g") sees .match, .scrim, .prac, .map and the like, while .start, .endmatch, .restore and other match-control commands are left out. The console copy lists every admin command with a check mark or a blank box and, for each command the player cannot use, the permission it needs (for example "needs: @css/config"), followed by a short flag legend.
- .mhelp is no longer restricted to admins holding @css/config. Any player who passes at least one admin command's permission check can open it; before, a map/practice-only admin was told they were not an admin and got no guide at all.
- The admin command list is now a single table in the plugin (Util/AdminCommandCatalog.cs) that records, per command, the exact permission key and flags its handler checks. Per-player command_overrides from admins.json are honored by the guide the same way the commands honor them. New admin commands must be added to this table to appear in .mhelp.
0.8.78
September 1, 2026Summary- The .map command and match-config map changes now accept workshop maps by name with a "ws:" prefix (for example "ws:cs_alpine"), changed via ds_workshop_changelevel. The map must be part of the workshop collection the server hosts. Workshop ids keep working as before, and can also be given as "ws/<id>".
- Match-config maplists, the veto flow and the next map in a series now accept the "workshop/<id>" and "workshop/<id>/<name>" map formats (the same formats the map-rotation file documents). Previously these formats only worked in the map rotation; a match config using them logged "Map not valid, cannot change" and the match never changed map.
0.8.77
August 25, 2026Summary- MatchZy now also runs on stock upstream CounterStrikeSharp (roflmuffin), not only the forked build. On stock servers, css_scrim / css_match and demo recording no longer fail with a TypeLoadException: the CSTV enabled check reads the process command line instead of the fork-only CommandLine helper, and the coach auto-placement and grenade library label positioning detect the fork's Trace API at runtime and fall back cleanly when it is absent (coach uses a simple hover spot, labels keep their saved position).
- gamedata/matchzy.json now includes the CCSPlayer_WeaponServices_SelectItem vtable offset, so putting a restored grenade or weapon in hand (.last / .back / .ln) also works on stock CounterStrikeSharp, whose core gamedata does not carry that key.
0.8.76
August 17, 2026Summary- Practice .bot no longer refuses to spawn a bot when CSTV is disabled. The full-server guard that protects the CSTV bot from being displaced now only applies while a CSTV client is actually connected; with tv_enable 0 (common on listen servers, which can also report a wrong max player count) bots spawn normally again.
0.8.75
August 15, 2026Summary- matchzy_kick_when_no_match_loaded works again. The kick was lost in an earlier fork revision, so the convar let anyone join: with it enabled, players who are not on the loaded match's roster (or anyone at all when no match is loaded) are now kicked on connect. Admins are exempt so they can join to manage the server.
- The css_whitelist player whitelist is enforced again: with whitelisting enabled, players whose SteamID is not in whitelist.cfg are kicked on connect. The check existed but was never called, so it did nothing.
- Fixed a server crash when a player who was not part of a set-up match joined a team or spectate: the plugin tried to move them to team "None" and respawn them there, which can take the server down.
0.8.74
August 11, 2026Summary- Demo recording is now verified by the file actually growing on disk, not only by the file existing. GOTV's demo writer buffers tv_delay seconds of frames in memory before anything past the header reaches disk, so the check waits out the configured GOTV delay plus a margin before it treats a static file as a dead recording. A dead recording is stopped and started again into a new file, up to three attempts.
- The demo file is watched for the whole match, not only at the start. The file size is sampled once a minute; a recording whose file stops growing for several minutes in a row (scaled to the GOTV delay) is restarted into a new demo file. The restart is silent in chat and only reported in the server log.
- A failed demo start runs tv_stoprecord before retrying, so a recording the engine considers open but stalled cannot make every retry fail with "already recording".
- The plugin now sets tv_enable_dynamic 0 when a demo recording starts and when practice mode is set up. Dynamic CSTV (a +tv_enable_dynamic 1 launch option used by some hosts) removes the CSTV bot whenever nobody is spectating, which looks like the bot being kicked and can stall a running recording.
- Practice bot commands (.bot and friends) no longer add a bot when the server has no free slot. bot_add on a full server takes the CSTV bot's slot, kicking CSTV and killing GOTV and the demo recording. The player gets a chat message that the server is full instead.
- Bots are now kicked one by one by name instead of with a bare bot_kick (practice start and end, dryrun start, match reset, and the warmup and practice cfg templates). The bare bot_kick could also take out the CSTV bot, which killed GOTV and the demo recording.
- Molotov and incendiary detonation times in practice are now tracked per projectile instead of per player, so throwing two mollies in a row prints a correct time for each. The molotov/incendiary label now comes from the grenade itself instead of the thrower's team, which mislabeled picked-up nades.
- Added matchzy_auto_team_names_enabled. Set to 0 to stop MatchZy from renaming scoreboard teams in scrim mode (the automatic team_<playername> naming at knife/match start), keeping the game's own team names. Team names from a Get5/JSON match config are always applied regardless. Setting matchzy_ct_name or matchzy_t_name to "" never disabled the renaming, it only switched to the player-based naming; the config.cfg comments now say so.
0.8.73
August 6, 2026Summary- Fixed GOTV/CSTV demos not being recorded on .match, .scrim and .hill. The cfg for each of those modes is followed by mp_restartgame, and that restart kills a recording started before it. The demo was started on the round change that the cfg itself causes, which happens just before the restart, so the recording was thrown away a second later and no .dem was ever written. The plugin now waits for the restart to finish before starting the demo.
- The plugin now checks a few seconds after starting a demo that the file really exists on disk, and starts it again if it does not (up to three attempts). A dropped recording used to go unnoticed until the end of the map, when the demo turned out to be missing.
- GOTV recording now also works on servers that enable GOTV from a config file. Only the tv_enable launch option was checked, so a server that set tv_enable 1 in autoexec.cfg, server.cfg or a hosting provider's own CSTV config recorded nothing and said nothing about it.
- Fixed no demo being recorded for the rest of the session after a map change made by another plugin. A map change done through CS2-SimpleAdmin, an RTV plugin or the changelevel command did not go through MatchZy, so the plugin still believed a recording was running and refused to start a new one on every following match.
- The "CSTV Recording..." message in chat is now only shown once the demo file has actually been created, and it is shown once per match. Previously it was printed at go-live whenever tv_enable was 1, which said the match was being recorded even when the recording had already been dropped. If no demo could be started, the server now says that in chat instead of staying silent.
- Demos are now written continuously (tv_record_immediate) instead of being held in memory, so a demo of a match that ends in a server crash is no longer lost.
- Demo recording now reports itself in the server log: when it starts, when it is confirmed on disk, when it is retried, when it stops, and the reason when it is not started at all.
- A match that is stopped before it finishes now gets an end time written to the database. Stopping a match with .stopmatch, !endmatch, !forceend, !restart, !surrender or the Stop Match button in the admin menu left end_time empty in matchzy_stats_maps and matchzy_stats_matches, so the match stayed in the database looking like it was still running. The round score at the moment of the stop is stored as well.
- A stopped match is recognisable by having an end time but no winner. The winner column is left empty on purpose, since a match that plays out always stores a team name or "Draw" there. Rows that already have an end time are never overwritten.
- This also covers a match stopped during the knife round or side selection, which had already been given a database row at ready-up.
- config.cfg is no longer part of the release zip. Unpacking an update over an existing server could overwrite an edited config.cfg and wipe the settings on it. Servers without a config.cfg still get a complete one written on the next plugin load, and servers that have one keep it: new cvars from an update are appended to it as before.
- The release zip now contains database.json.example next to the config files, listing the MySQL fields. The real database.json is still never shipped, since overwriting it on an update would replace the server's MySQL login with the SQLite default and quietly stop stats from reaching the database.
- scrim.cfg written by the plugin now includes sv_pure, sv_pure_kick_clients and sv_pure_trace, matching the scrim.cfg that ships in the release zip.
- Fixed player stats not being saved on MySQL when the match config carries its own matchid. The plugin wrote the map row without first creating the match row it points at, which MySQL rejects, and every later write for that match was then skipped with "Invalid matchId: -1" in the log. The match row is now created up front. SQLite was unaffected, so this only showed on servers using MySQL.
- Loading a match config with a matchid that was already used no longer breaks stats for that match. The map row is updated instead of inserted a second time.
- A match that supplies its own matchid now gets its database row at load time rather than at go-live, so stopping it during warmup or veto still records an end time.
- Fixed database writes being lost when several of them happened at once. Round-end player stats, map-end data and series-end data share the end of the last round, and they were all sent over one shared database connection, which cannot handle simultaneous use. Each operation now uses its own connection.
- Fixed team assignment on maps set to knife in the match config. Sides were not initialised for those maps, so the plugin reused the side assignment left over from the previous match. Depending on what that was, teams were placed on the wrong sides, or no player was recognised as part of the match at all and everyone could join whichever team they wanted.
- Restoring a round backup no longer breaks side tracking for the rest of the session. The restore replaced the team objects the plugin tracks sides by, which could leave every player unassigned from that point on. Coach assignments now also survive a restore.
- Match configs that list team players as an array of Steam IDs are now accepted everywhere. Previously only the object form was recognised, and an array made the plugin treat the match as having no team lists, which disabled team locking.
- A player row the database rejects no longer takes the rest of the team down with it. One bad row used to abort the write for every remaining player in that round; each player is now written on its own and the skipped one is named in the log.
- The server log now says so when a round produces no player stats at all, instead of leaving an empty player stats table as the only clue. It also reports when only part of a team was written.
- Fixed .restore doing nothing while restoring the same round from the server console worked. The round snapshot is taken at round start, the same moment the server writes its own round file, so the copy stored inside the snapshot could be cut off half way. Restoring then wrote that cut-off copy over the server's intact round file, and the load failed without an error. A cut-off copy is now detected and the server's own file is used instead.
- A round snapshot no longer stores a half written copy of the server's round file. It is left empty instead and filled in a moment later, which already happened when the file was missing entirely but not when it was still being written.
- Round backups are checked for completeness before being offered to the server. An incomplete file is reported as such rather than being loaded and silently ignored.
- Fixed player stats never being written on a database created by an earlier MatchZy version. The four multi kill columns were named enemies5k, enemies4k, enemies3k and enemies2k here but enemy5ks, enemy4ks, enemy3ks and enemy2ks everywhere else, and an existing table is never altered by the plugin, so every player row was rejected by the database. The match and map tables were unaffected, which is why matches kept being recorded while the player table stayed empty. The upstream names are now used, and a table created by an affected version is renamed automatically on the next plugin load.
- server_ip in the match table again includes the port, as it did before. Rows written since then hold the address without it.
- Fixed a possible server crash when a player leaves in the same moment they are moved to their assigned team during match setup or veto. The team move is applied one frame later and the player was not re-checked in between.
- !loadbackup now says when it cannot read a file name from what was typed, instead of reporting that a backup with an empty name does not exist. Every use of the command is also written to the server log with the file name it received, since its replies otherwise only reach the player who typed it.
- Loading a backup during warmup now states that the backup is queued and will be restored once the match goes live. It previously reported that the backup had loaded successfully even though nothing had been restored yet, which is why running the command a second time appeared to be required: the second run forces the restore immediately. Both options are now named in the message.
- The round icons above the scoreboard are now cleared when switching game mode. Rounds played in dryrun stayed on screen after .prac, .exitdry, .scrim or .hill, so practice or warmup started with a row of icons from a game that was already over. Entering and restarting a dryrun clears them as well, so a dryrun always starts from an empty row.
- Practice mode keeps the row of round icons empty. Practice rounds still end and used to add an icon each time, filling the top of the scoreboard over a long session. Dryrun is unaffected and still builds up its round icons normally until .exitdry.
0.8.72
August 5, 2026Summary- Added matchzy_restore_auto_unpause. When enabled, the match unpauses on its own after a round restore instead of waiting for both teams to type .unpause. Default: false (unchanged behavior).
- Added matchzy_restore_unpause_delay, the countdown in seconds used by the automatic unpause. Default: 5.
- Fixed the match staying paused with no way to unpause when matchzy_pause_after_restore was disabled. The game already pauses itself on a backup load (mp_backup_restore_load_autopause), and MatchZy did not know about it, so .unpause did nothing.
- Restoring a backup that holds no round data no longer reports a successful restore and pauses the match. The admin now gets a message that nothing was restored. If the server still has the round file the game itself wrote for that round, the restore now uses it instead of refusing.
- Round backups no longer end up without round data. The backup was written at round start, at which point the game had not always finished writing its own round file yet, so the round data was missing and that round could not be restored later. The backup is now completed once the game is done.
- A round restore is now announced only once the server has actually loaded it. If the load does not take effect, the restore is reported as failed in chat and the reason is written to the server console, instead of announcing a successful restore and pausing a match that never moved.
- The round backup file is now rewritten from the stored backup every time before it is loaded. A leftover file from an earlier match with the same match id and round number was being loaded instead, which could make a restore do nothing.
- Restoring the current round with !restorecurrent, !restartround, !rr or !rrestore no longer asks for a "yes" confirmation. The command is admin-only and !restore never asked for one.
- Fixed .restorecurrent and .rrestore replying "invalid value for restore command" when typed with anything after the command name.
- The pause after a round restore is now applied after the backup has actually been loaded, instead of before it.
- A round restore now also rolls the scoreboard back: the round history above the scoreboard is cut to the restored round, and player kills, deaths, assists, damage, score and MVPs are set back to what they were in that round. Added matchzy_restore_scoreboard_stats to turn it off. Older backup files only get the round history rolled back, since they carry no player snapshot.
- The chat commands .backup, .backups, .backupmenu, .restorelast, .rl, .restorecurrent and .rrestore now work. Only the !backup and /backup forms were reaching the plugin.
- The round history above the scoreboard is now cleared when a match is ended and the server returns to warmup, instead of keeping the win icons of the finished match next to a 0-0 score.
- Fixed MatchZy writing config files into a second cfg folder on servers that have both csgo/cfg/matchzy and csgo/cfg/MatchZy. One folder is now picked consistently (an exact lowercase "matchzy" first), and the folder in use is printed in the server log at startup. If both folders exist, a warning names the one being used so the unused folder can be deleted.
- database.json is now read from the same cfg folder as the rest of the config files instead of a hardcoded lowercase path.
- Fixed MatchZy commands running twice on servers that list "." as a chat trigger in CounterStrikeSharp's configs/core.json (for example "PublicChatTrigger": [ "!", "." ]). CounterStrikeSharp already turns ".map" into the css_map console command, and MatchZy handled the same chat line a second time, so the command was carried out twice and every reply was printed twice (".map junkname" answered "Invalid map name!" twice). MatchZy now detects the trigger at startup and leaves those commands to CounterStrikeSharp. Chat commands that have no console command of their own, such as .rdy and .knife, are unaffected. Servers using the default "!" and "/" triggers see no change.
- Added matchzy_dot_trigger_dedupe to turn the above off (default: true). It only has an effect on servers that use "." as a chat trigger.
0.8.71
August 1, 2026Summary- Recorded demos are now uploaded once the map ends, if matchzy_demo_upload_url is set. The fork previously stopped the recording without ever uploading it.
- Added matchzy_demo_upload_s3 (alias get5_demo_upload_s3). When enabled, the demo is sent with an HTTP PUT and the raw .dem file as the body, for S3-compatible storage that uses presigned upload URLs. Sign the URL with Content-Type application/octet-stream. Default: false.
- Added matchzy_demo_upload_header_key and matchzy_demo_upload_header_value (aliases get5_demo_upload_header_key / get5_demo_upload_header_value) to send a custom authentication header with the upload.
- Large demo uploads no longer fail part way through. The upload now has its own timeout instead of sharing the 10 second one used for event publishing.
- Added the demo_upload_ended event, sent to the remote log URL after each upload with the demo filename and whether it succeeded.
- An invalid matchzy_demo_upload_url is now reported in the server log instead of being ignored silently.
- matchzy_demo_upload_url and the two upload header settings are deliberately not written to config.cfg, because a presigned URL and an authentication token are credentials and config.cfg is world readable. Set them from a private cfg. config.cfg documents the syntax in a comment.
0.8.70
July 31, 2026Summary- Fixed match end data being written to the database twice at series end (duplicate "[SetMatchEndData] Match X end data set successfully" log lines). The second write could also overwrite the final map's per-map score with the series score.
0.8.69
July 30, 2026Summary- Fixed
.t/.ctwhile spectating in practice: previously the player was either kicked (client drop with NETWORK_DISCONNECT_LOOPDEACTIVATE) or joined the team permanently dead. The switch now calls the engine's own HandleCommand_JoinTeam (immediate mode), which runs the complete join flow and spawns the player. Requires the updated gamedata/matchzy.json (new key: CCSPlayerController_HandleCommandJoinTeam); without it the switch falls back to the old behavior plus a team-menu hint. - Fixed a practice side-switch sometimes swallowing the player's next real death on the scoreboard: the no-death flag was set even when no switch suicide fired (e.g. switching while dead or spectating) and lingered until the next death.
0.8.68
July 29, 2026Summary- Fixed
.botjigglemaking a freshly spawned.botinvisible: the jiggle anchored the new bot at the map spawn point it briefly appeared on and yanked it back there every tick, so it never showed up at the lineup. Jiggle now strafes each bot around its assigned practice spot; bots not spawned via practice commands are no longer jiggled at all. .botnow pre-pins bot_quota to the expected count (current bots + 1) right before bot_add, so the engine's quota logic has no headroom to spawn the second bot of a pair in the first place. If the engine pair-spawns anyway, the extra is still detected and kicked as before.- Fixed
.bot/.tbot/.ctbotsometimes spawning nothing (console: "kicking wrong-team pair bot"): when bot_add pair-spawned one bot per team, the wrong-team bot could be seen first and the requested one arrived a tick later, after the claim pass had already given up and kicked everything. The claim now prefers the requested team over the whole set and retries briefly before failing, so the right bot is kept and only the pair extra is kicked. .backups(css_backupmenu) now works when no match is live: it lists the 5 newest backup files on disk (match id, round, score, map, age) with a ready-to-use restore command for each. Useful after a server crash - reconnect, run.backups, restore the round the match crashed on.- Added
css_loadbackupas an alias ofmatchzy_loadbackup/get5_loadbackup, so a backup file can be restored from chat with!loadbackup <file>(admin only). Previously the command was only usable from the server console.
0.8.67
July 28, 2026Summary- Removed
matchzy_random_spawnsand the 0.8.65 coach auto-scatter entirely. Live match/scrim rounds always use the map's competitive spawns; a coach never changes player spawn behavior (the coach sits at their own viewing spot and does not take a competitive spawn point). Dryrun mode keeps its random spawns. If your existing config.cfg contains a matchzy_random_spawns line, it can be deleted (a leftover line only causes a harmless unknown-command console note). - Fixed a coach still displacing one player off the standard competitive spawns (e.g. Ancient CT: one player left in the back corner instead of the line of 5). The reseat treated every enabled spawn as valid, so the displaced player was never pulled back; it now only accepts the map's lowest-priority (competitive) spawn set and moves the displaced player onto the spawn the coach freed up. Also fixed a player standing exactly on a competitive spawn being re-teleported every round (a neighbouring player could claim that spawn first; spawn claiming is now nearest-first).
- Added
bot_quota 0to live.cfg, scrim.cfg, hill.cfg, knife.cfg and warmup.cfg. The CS2 default is 10, so on servers whose base config never zeroes it the engine could quietly add or refill bots during warmup and matches. - Added
mp_randomspawn 0to scrim.cfg, hill.cfg and knife.cfg (live.cfg already had it). The cvar is sticky, so a mode or plugin that had set it to 1 earlier could leave scrim/hill/knife rounds with randomized engine spawns. - The coach-displaced player is now corrected in the spawn frame itself (before the client renders), instead of a visible teleport during freezetime - players no longer notice anything when a coach is on. Nobody is ever moved to Spectator (no ghosting window), and the timer-based reseat stays as a safety net.
- The coach's freezetime death no longer shows up in the kill feed (the old suppression only matched self-attributed suicides; the forced kill reports the world as attacker and slipped through).
- The coach no longer steals one of the five competitive teammate colors: the coach is set colorless and the five real players on each side always hold the five distinct colors (the ex-coach gets a color back on .uncoach).
- Fixed the coach not dying at all on current CS2 builds: the coach body is made untouchable at placement, and the engine now drops the forced suicide when the pawn takes no damage - damage is re-enabled for the kill itself. Also moved the kill to the end of freezetime (about 1 second before live) so the coach is alive at the viewing spot for the whole tactical talk, without an idle body entering the live round or a long black death-cam during freezetime.
- The coach is never moved through the Spectator team anymore (ghosting risk): the freezetime-end fallback for a still-alive coach now kills the coach instead of bouncing them Spectator-and-back, and the coach team fixup switches directly between sides.
0.8.66
July 27, 2026Summary- Fixed GOTV/CSTV demos not recording on
.scrimand.hill(worked on.match). scrim.cfg / hill.cfg runmp_restartgame, whose restart clobbered thetv_recordthat was started on a fixed 2s timer; the demo now starts on the first live round after the restart settles (with a fallback), so it records reliably. - Fixed
matchzy_random_spawns(and the coach auto-shuffle) leaving players on the same spawns every round: the shuffle ran at round start before players finished respawning, so the teleport did nothing. It now runs a moment later, so spawns actually vary. Added debug lines (undermatchzy_coach_debug) showing the spawn pool size and how many players were moved.
0.8.65
July 27, 2026Summary- Added
matchzy_random_spawns(default false): randomizes player spawns each live round across all enabled map spawns instead of the fixed competitive set, so maps no longer always reuse the same spots (e.g. Dust2 T now uses all 10 spawns, not the same 5). For casual/scrim variety only; leave off for ranked matches. While on, the coach spawn-reseat is skipped. (Note: a side can only vary up to the number of spawn entities the map defines - Dust2 CT has only 5, so it cannot vary.) - Random spawns now also turn on automatically while a coach is present (no need to set the convar), since a coach on a side is exactly when spawns look "always the same". Coaches are excluded from the shuffle (they stay at their viewing spot). Reverts to normal once the last coach leaves.
- Fixed the coach being killed ~1 second AFTER the round went live (visible/idle body into the round) instead of during freezetime. The kill is now scheduled at a small fixed delay early in freezetime, so the coach body is reliably gone before the round starts, regardless of the
mp_freezetimevalue (previously it readmp_freezetime- a float cvar - as an int, mistiming the kill). - Fixed
.watchme/.fas(and.spec) failing to move players to Spectator and spammingCCSPlayerPawnBase::SwitchTeam( 1 ) - invalid team index.:SwitchTeamonly accepts T/CT, so the Spectator move now usesChangeTeamon the already-dead pawn. - Removed log warning spam
Field CCSPlayerController:m_szClanName is not networked, but SetStateChanged was called on it(and the same forCCSGameRules:m_fNextUpdateTeamClanNamesTime) from the ready clan-tag refresh. Both fields are not networked, so the calls were no-ops; scoreboard tag updates are unaffected.
0.8.64
July 24, 2026Summary- Fixed a rare server crash when using
.ct/.t/.specto switch to the side you are already on. It ran a redundant suicide plus team-switch to your current team (the engine'sChangeBasePlayerTeamAndPendingTeamwith the requested team equal to the current one occasionally crashed). It is now a no-op, only respawning you if you were dead on T/CT. .cbot/.crouchbot/.duckbotnow boost you on top of the crouched bot (spawn above it), matching.crouchboost.- Fixed
.crouchboost/.cboostskipping the player-validity and bot-limit checks that.boostalready ran. - Fixed
.loadbotposplacing a bot tilted or under the map when the saved spot was recorded while looking up or down: the bot is now always placed upright, facing the saved direction. - Reduced duplicate "kicking late untracked bot" log spam when spawning several bots in quick succession.
- Removed the experimental
.jt/.jumpthrowcommand and thematchzy_experimental_jumpthrowconvar (the server-side input injection was unreliable across CS2 builds).
0.8.63
July 24, 2026Summary- Fixed a match load being wiped when the config's first map differs from the current map. Loading via
get5_loadmatch_url/matchzy_loadmatch(or the file variants) changelevels to the match map; that changelevel ended the outgoing map and reset the just-loaded match, so the server arrived on the new map with no match (get5_statusreturnednone/ null matchid, default team names, no ready). The match is now carried across the changelevel and re-loaded on the target map, matching get5 behavior. Loading while already on the first map was unaffected and still works.
0.8.62
July 24, 2026Summary- New named bot positions (practice):
.savebotpos <name>(.sbp) saves your current spot as a named bot placement for the current map,.loadbotpos <name>(.lbp) spawns a bot at that saved spot (no name spawns every saved placement on the map),.listbotpos(.listbp) lists them,.delbotpos <name>(.dbp) removes one. Stored per map incfg/matchzy/botpositions.json. - New
.showbotpos(.showbp): toggles in-world markers (beam plus name label, CT lime / T orange) at every saved bot placement on the map; redraws itself after a map change. - New
.botjiggle: toggles all practice bots strafing side to side for dodge/aim reps. Newmatchzy_botjiggle_rangeconvar (default 30) tunes the strafe width. .cbot/.crouchbot/.duckbotnow boost you on top of the crouched bot (spawn above it), matching.crouchboost.- Practice now prints the molotov/incendiary burn time in chat when your fire detonates (via the inferno start-burn event), alongside the other utility detonation timings.
- Fixed bot placements spawning under the map or lying prone: the saved-position file now serializes correctly, and every bot spawn is placed upright (keeps its facing without the view pitch tilting the model or clipping it through the floor).
- Fixed
.crouchboost/.cboostskipping the player-validity and bot-limit checks that.boostalready ran.
0.8.61
July 20, 2026Summary- Coach viewing spots reworked across the whole map pool. By default (matchzy_coaching_mode 1) each active map now ships a hand-tuned spot behind the team; maps without one fall back to a computed spot (stands behind the team with line of sight, keeps a real stand-back distance so it is never nose-to-back with a player, refuses a lower-level spot, and uses an overhead camera above the spawn when no clean ground spot exists).
- New
matchzy_coaching_mode(default 1): 1 uses aspawns/coach/<map>.jsonspot when present (hand-tuned override) otherwise computes it, 2 always computes the coach spot behind the team and ignores the JSON files. - Coach spawn files reworked: the old fixed per-map viewing spots were removed (they were the "always the same bad spot" complaint). Placement is computed live for every map; a
spawns/coach/<map>.jsonentry is only an optional override, and.savecoachspawn t|ctwrites/replaces one (saving your exact view angle) for any map that needs hand-tuning. - New
.showcoachspawns(admin): draws the coach viewing spot for both sides in-world (blue = CT, orange = T), matchingmatchzy_coaching_mode, and survives a map change instead of going invisible-but-on. Reloads the JSON each time so hand-edits show immediately. - New
.coachtest(admin, debug): places you like a coach on your current side right now (run again to release) so a single admin can check the coach spot on any map without a match. - Coach placement is now silent (no landing sound), the coach can no longer be damaged/killed by teammates, and players already on a competitive spawn are never re-teleported (the reseat only moves a genuinely coach-displaced player, and near-duplicate spawns can't seat two players on top of each other).
- Coach spawn files are read/written under a case-resolved plugin path (prefers an existing
matchzyfolder overMatchZy), so a saved spot is found again on case-sensitive Linux. - Practice
.botfix: onebot_addcould pair-spawn a bot on the other team (and the claim was team-blind, so a CT player could get a CT bot); the wrong-team bot is now kicked and.botadds exactly one bot on the opposing team. - Fixed a server crash from
.watchme/.fas: forcing the other players to spectator used the live-player team-change path (weapon strip -> other plugins' weapon hooks re-enter on a half-destroyed weapon -> crash). It now drops weapons first and switches team the safe way, the same fix.t/.ct/.specalready had.
0.8.60
July 19, 2026Summary- Fixed the coach falling out of the map with a black screen on maps where the team spawn backs onto the map edge (Mirage T): the behind-team spot is now validated with wall and floor probes and moves closer to the spawn until it is inside the world.
- Fixed players being re-teleported every round while a coach was on, even on the coachless side: anyone standing on any valid team spawn is now left alone (maps like Mirage enable more spawn points than the team size), and near-duplicate spawn points can no longer seat two players almost on top of each other.
- New
.coachtest(admin): instantly places you like a coach on your current side and back again on the second run - lets a single admin verify coach placement on any map without bots or a match. - Coach spawn computation is hardened against the AcceleratorCSS tracer: a failure now falls back to the fixed viewing spot instead of erroring in the spawn handler.
0.8.59
July 19, 2026Summary- Practice grenade library:
.shownadestoggles in-world markers for every saved lineup on the map (yours + the shared pack),.hidenadeshides them, andcss_shownadescan be bound to a key. Markers and labels are colored by grenade type (smoke blue, flash yellow, HE red, molotov orange, decoy grey). - Grenade library labels show the type, comment and throw style, are readable from every angle (never mirrored), and no longer clip into walls next to the lineup.
- Grenade library: press E aimed at a marker to teleport to the lineup with the right grenade equipped; lineups saved on the same spot share one marker and F cycles between them (a counter like 1/2 is shown).
- Grenade library: the marker you are standing on hides for you only (no beam blocking the throw) and reappears when you walk away - no need to run
.shownadesagain. - Grenade library shared pack: admins can promote lineups with
.libadd <name>, remove with.libremove <name>and list with.liblist- visible to everyone on the server. .savenade <name> [throwtype] <comment>accepts an optional throw style (jump/run/walk/crouch) as the second word;.listnadesnumbers lineups and.ln #Nloads by number. Saving without a grenade in hand is allowed (the label shows a blank type).- New
.nadesmenu: browse the grenade library by type and click a lineup to load it (requires the CS2MenuManager plugin). - New
.warmupbots [count](admin): adds aim-warmup bots during the warmup/ready phase; they are removed automatically the moment the knife round or live match starts. - Practice
.botfixes: the engine could pair-spawn a second bot on the other team (leaving a bot on each team) and could even hand you a bot on your OWN team; both are detected and kicked, so.botadds exactly one bot on the opposing team again. - Practice colored smoke no longer reverts to grey a few seconds after blooming, and rethrown smokes (
.rt/.throw) are colored too. - Fixed
matchzy_autostart_mode 2being ignored aftercss_plugins restart MatchZy: the plugin read the convar before config.cfg had re-applied, so a practice server came back up in match mode. - Dry Run no longer ends after a single round: play as many rounds as you like (with bots or friends) until an admin runs
.exitdry, which now returns to match warmup instead of forcing practice mode (run.pracyourself if wanted). .matchand.scrimnow print a compact status line (Knife / DemoRec / Playout with colored Enabled/Disabled) plus a.helphint, and.helpduring the ready phase shows the same status block with the available commands.- Coach overhaul: the coach now spawns behind their own team automatically on every map (no per-map file), can no longer be damaged or killed by teammates, and the players' competitive spawns are left untouched (previously everyone was re-teleported each round when a coach was on, which shuffled spawns).
- Fixed scrim.cfg never applying
mp_autoteambalance 0(the setting was glued into a comment). Note: existing scrim.cfg files on disk keep the old text - delete the file to regenerate it. - Fixed the first
.ma/.nadesmenu open stalling the server for over a second (the menu library is now warmed up in the background at plugin load). .shownadesfailures now log the full error and a single bad marker no longer prevents the rest from drawing..matchsetupwizard: added a Best of 2 (BO2) series option and a "Back to Admin Menu" entry at the top of the wizard.- Removed the experimental
.predictgrenade predictor along withmatchzy_experimental_predictorand thematchzy_predict_*convars.
0.8.58
July 18, 2026Summary- Fixed dot-prefix chat commands (
.ma,.match,.stopmatch, ...) doing nothing during match setup: a spectator / unassigned admin is excluded from the internal player map while a match is being set up, which stopped the chat handler from resolving them, so only the!versions (e.g.!ma) worked. Dot commands now dispatch for those players too. - Fixed
.stopmatchand the "Stop Match" button in the.ma/css_maadmin menu not stopping a match that had been set up but was not yet live (setup / veto / warmup / knife). Stop now works in every pre-live and live state, not just once the match goes live. - Added
.matchstopas an alias for stopping/ending a match (alongside the existing.stopmatch,.endmatch,.stopgame,.endgame,.forcestop,.forceend,.end,.exitscrim).
0.8.57
July 17, 2026Summary- Fixed
.botspawning two bots at once: the redundantbot_join_teambeforebot_add_t/bot_add_ctspawned an extra bot, andbot_quota_mode normalthen refilled any kicked extra..botnow adds exactly one bot (quota is pinned to the tracked bot count). - Practice now disables the round's team-damage penalties (autokick / team-damage warn/kick / TK punish), so grenade / molotov / friendly-fire testing no longer risks a kick.
- Fixed a lingering ghost body in practice: a player who disconnects mid-practice could leave an orphaned pawn (the round is kept alive so the engine does not always reap it). The disconnecting pawn is now removed on the next frame.
- The ready-status display is controlled by a single convar,
matchzy_ready_hint_style:0= classic center text (default),1= HTML READY-UP panel with the native warmup suppressed (panel shows its ownWARMUPbadge and no native pill, at the cost of a frozen1:00round timer top-center). This folds in the oldmatchzy_ready_hide_warmup_hudtoggle (retired) and the experimentalmatchzy_ready_block_warmup_announce(removed); both are auto-removed from an existing config.cfg on update. Note: hiding the native warmup is what forces CS2 to draw the round timer, and no server value can blank it, hence the frozen1:00. - Hardened practice spawn loading (
.prac): the spawn scan is now materialized and guarded so it cannot crash the command (fixes anArrayTypeMismatchExceptionseen when running under the AcceleratorCSS Harmony tracer). - Fixed the ready phase after a live plugin reload (
css_plugins unload/load): per-player ready state and the gamerules warmup state are now restored on hot reload, so the ready hint counts connected players (with the NotReady list) and displays correctly instead of reading 0/0 or staying invisible until a round restart.
0.8.56
July 16, 2026Summary- Practice named position slots:
.savepos <name>saves a position under a name,.loadpos <name>teleports back to it,.listposlists your saved names, and.delpos <name>removes one (up to 32 per player)..savepos/.loadposwith no name keep working as the single default slot. - Practice flash test:
.flashtest(or.ft) toggles a chat readout of your own blind duration each time you get flashed, for tuning pop-flashes and self-flashes. - Practice self-flash:
.blindthrows a flashbang at your own face for pop-flash reaction reps (no teammate or client bind needed). - Practice
.wipe(or.clearnades) clears your grenade throw history (the source for.last/.back/.rt/.throwindex) without leaving and re-entering practice. - Practice
.jt(.jumpthrow) jumpthrows the grenade in your hand, gated behind the new convarmatchzy_experimental_jumpthrow(defaultfalse). Experimental: it forces the jump and release server-side, which the engine may ignore on some CS2 builds, so it ships off by default. - Practice
.cleanupclears all utility currently on the map (smokes, mollies, infernos, live projectiles). - Practice
.autocleartoggles auto-clearing utility: when on, each time a grenade detonates the older utility is removed and only the just-detonated result is kept, for fast lineup iteration. - Practice
.landmarker(.lm) toggles a marker at each grenade's detonation point so you can see exactly where it landed. - Practice
.arc(.traceline) toggles drawing the flight path of thrown grenades as an in-world trajectory line. - Practice saved grenade lineups are now capped at 500 per player, and
.mynadesshows how many you have saved. - Fixed
.rt/.throw(rethrow last grenade) silently doing nothing after a normal mouse1 throw: a freshly thrown grenade could be recorded with zero velocity (its velocity field lags a frame on current CS2 builds), which the rethrow's zero-velocity guard then dropped. The launch velocity is now recovered from the projectile's movement when the direct read comes back empty. - Added an experimental grenade landing predictor:
.predictdraws the flight arc and a landing marker for the grenade in your hand, gated behindmatchzy_experimental_predictor(defaultfalse). It forward-simulates the throw (with world-collision wall/floor bounces when built against a CounterStrikeSharp API that exposes the trace natives, otherwise a no-collision estimate), tunable live viamatchzy_predict_gravity/matchzy_predict_throwspeed/matchzy_predict_elasticity/matchzy_predict_friction, with amatchzy_predict_debugreadout of predicted-vs-actual landing distance for calibration. - Fixed a countdown timer appearing during the ready phase when the HTML ready panel (
matchzy_ready_hint_style 1) is used: hiding the native WARMUP banner also droppedmp_warmup_pausetimer, so the round timer counted down. The timer is now frozen during the ready phase, matching paused warmup. - The HTML ready panel now shows a
WARMUPbadge at the top, since the native WARMUP banner is hidden while the panel is up. - Fixed the HTML ready panel dropping lines (e.g. the NOT READY status) in languages with accented characters such as Danish and Albanian: accented text broke the center-HTML rendering, so it is now escaped to render correctly in every language.
- Practice
.delnadecan now delete multiple lineups at once:.delnade <name1> <name2> ...removes each, and.delnade allremoves every lineup you saved on the current map. It reports which were deleted and which were not found. - Fixed a rare
ArrayTypeMismatchExceptionwhen entering practice (.prac->GetSpawns) on servers running a call-history crash tracer: the spawn lists are now pre-sized so the list-grow path that tripped it is never taken. - Added
matchzy_ready_up_by_ping(defaulttrue): set itfalseto stop pinging (middle-mouse / scroll button) from toggling your ready status, for players who ready up by accident. - The ready panel (and classic ready hint) no longer shows during
.dryrun, which has no ready gate. - config.cfg now auto-removes retired convar lines on load, so an upgraded server no longer spams "Unknown command" when config.cfg execs.
- Fixed getting stuck in the spectator/observer camera for several seconds after picking a team during the ready phase (with the HTML ready panel): hiding the native warmup also disabled warmup's auto-respawn, so a fresh team-joiner was not spawned. Players are now respawned on join, with a periodic safety sweep that keeps every T/CT player spawned during the ready phase.
0.8.55
July 16, 2026Summary- Practice spawn markers are now interactive: with
.showspawnsactive, aim at a spawn marker and press USE (E) to teleport to that spawn..hidespawns(or leaving practice) disarms it. - Practice spawn markers are now lifted slightly off the floor so they stay visible over shallow water (e.g. de_ancient) instead of sinking out of sight.
- Practice
.backwith no number now steps backward through your grenade history like CS:GO practice mode: the first.backjumps to your most recent nade, each further.backgoes one older, and it stops at the oldest instead of printing a usage message..lastand.back <number>set the starting point, and the cursor resets when you throw a new nade. - Fixed practice spawn teleports (
.spawn, best/worst spawn) tilting the whole player model sideways at steep spawn angles after a recent CS2 update: they now keep the body upright (same fix already used for.last/.backnade lineups). - Build now compiles against the fork's CounterStrikeSharp API DLL at
~/CounterStrikeSharp(1.0.398) instead of the NuGet package (which tops out at 1.0.371), so the plugin matches the newer server runtime ABI. This fixes anEntryPointNotFounderror triggered on 1.0.39x runtimes.
0.8.54
July 16, 2026Summary- Fixed practice rethrow (
.throw/.rt/.throwsmokeetc.) only working for flashbangs: smoke / HE / molotov / decoy re-throws silently did nothing when their native*_Createsignature failed to resolve fromgamedata/matchzy.json. They now fall back to the managed entity API (like flash always has) so a rethrow always spawns, and log a clear warning when the signature was missing so a stale/undeployed gamedata file is diagnosable. Also added incendiary (CT molotov) rethrow support. - Fixed re-thrown grenades spinning wrong: the projectile's angular velocity (spin) was being set to its linear launch velocity on rethrow. The real spin is now captured at throw time and replayed, so a rethrown nade tumbles like the original (cosmetic; landing spot was already correct).
- Added
.grt(.globalrethrow, consolecss_grt) in practice: rethrows every player's last thrown grenade at once, for setting up full team executes in one command. - Fixed
.listnades/.loadnade/.delnade/.importnadethrowing aFileNotFoundException(server error spam) on a fresh server before any lineup was saved: the missingsavednades.jsonis now treated as empty instead of crashing the command.
0.8.53
July 15, 2026Summary- Reworked the "waiting for players" ready screen into a per-player HTML panel: title, progress bar, ready count, CT/T split, current mode (Match / Scrim / Hill / Match Setup), and each player's own READY / NOT READY status, shown in their own language. New convar
matchzy_ready_hint_style(0 = classic center text, 1 = HTML panel, default1) andmatchzy_ready_hint_blink(blink the NOT READY line to grab attention, style 1 only, defaultfalse). - The native "WARMUP" HUD banner can be hidden during the ready phase (with the HTML ready panel) so it no longer overlaps the panel. A "fake warmup" keeps the pre-match ready phase playing like warmup (round never ends, respawn on death, no round-time expiry) while the banner is hidden, and the center panel no longer flashes.
- Fixed the ready panel showing the wrong mode: switching
.scrim/.hillduring warmup now updates the panel immediately, and.hill->.matchno longer leaves the server stuck in hill mode. - Practice grenade spawns and
.breakrestorenow resolve their signatures by key from CounterStrikeSharp's gamedata instead of hardcoded byte patterns. MatchZy ships its owngamedata/matchzy.json(auto-loaded by CounterStrikeSharp, included in the release.zipataddons/counterstrikesharp/gamedata/matchzy.json), so it works on stock CounterStrikeSharp without editing the coregamedata.json. Missing/stale keys degrade gracefully instead of crashing. - Added
matchzy_ready_clantag_enabled(defaulttrue) to toggle the[READY]/[UNREADY]scoreboard clan tags shown during the ready phase. - MatchZy now auto-yields the map command when a dedicated map plugin (CS2-SimpleAdmin / CS2MapChange) is installed alongside: it registers neither
css_mapnor handles the.mapchat command, letting the other plugin own map changes. This avoids acss_mapConCommand conflict (which could block players from connecting) and a double map change (two plugins both firing a changelevel disconnected players). Map changes are also debounced, so a single.mapnever changes the map twice even on servers that add.as a chat trigger (where.maphits both the chat dispatch andcss_map).matchzy_map_console_command_enabled(defaulttrue) gates the console command; set itfalseto never registercss_map.
0.8.52
July 15, 2026Summary- Added optional
.map/css_mapadmin command for changing the map. Thecss_mapconsole command is gated bymatchzy_map_console_command_enabled(defaulttrue) so it can defer to another plugin such as CS2-SimpleAdmin without a conflict; the.mapchat command is always available. The map name is validated and resolved before the demo is stopped and bots are kicked (a typo no longer tears the server down and loses the recording), supports workshop ids viahost_workshop_map, and resolves bare names (e.g.mirage->de_mirage). - Config folder is now case-agnostic: an existing
cfg/MatchZy/orcfg/matchzy/is auto-detected and used for every MatchZy file (cfgs,savednades.json,admins.json,whitelist.cfg). Also fixes cfgs failing to exec on case-sensitive Linux when the folder wasMatchZy/but paths were hardcoded lowercase. Keep only one of the two folders. admins.jsonis now actually loaded at startup (was never called before, so it had no effect); only valid SteamID64 entries grant admin, and a reload drops removed admins.- Fixed practice smoke rethrow (
.rt/.throwsmoke) dropping the smoke dead at the spawn origin. Smoke was excluded from the velocity-apply path. - Fixed
.loadnade/.back/.lastauto-throwing the restored grenade (dead into a wall at tight lineups); the pose-clear now redeploys the nade without triggering a throw. - Fixed
.savenadestoring the position 4 units above the real stance, which made loadnade lineups release from the wrong height. - Removed the end-of-match summary panel (the center-HTML MVP / clutch / top-frag panel) and its
matchzy_match_summary_panelandmatchzy_match_summary_panel_durationconvars.
0.8.51
July 13, 2026- Grouped the source into concern folders (Core / Match / Practice / Stats / Pause / ...) with no namespace or build change.
0.8.50
July 11, 2026- Bumped CounterStrikeSharp API to 1.0.371.
- Fixed a server crash and a phantom death when switching team with
.t/.ct/.specin practice. - Kept the player model flat on
.last/.backwhen the lineup was aimed at a steep pitch. - Auto-clean the stale
publish/folder ondotnet publish.
0.8.49
July 9, 2026- Bumped for the Valve game update (build 14168).
0.8.48
July 1, 2026- Added ClanTags support and small fixes.
- Release / CI housekeeping (untrack build artifacts, fix
release.yml). - Re-arm AutoStart on the first player connect so warmup execs after an empty-map load (0.8.46).
- Iterated on the warmup-timer pause so the HUD reliably shows a plain paused "WARMUP" (
mp_warmup_pausetimer/mp_warmup_online_enabledhandling) (0.8.41–0.8.45).
0.8.40
July 1, 2026- Added the
matchzy_nade_pose_flicker_freetoggle for nade restore.
0.8.39
July 1, 2026- Clear the stuck throw-pose on all grenade restores.
0.8.38
July 1, 2026- Ship cfgs under
cfg/MatchZy/in the release artifact. - Don't create
matchzy/whenMatchZy/already exists. - Added the in-game coach spawn builder.