Skip to content

Repository files navigation

GG1MapChooser

GG1MapChooser is a CounterStrikeSharp map chooser for CS2 servers. It manages map votes, RTV, nominations, map pools, low-player map lists, admin map changes, automatic map rotation, next-map handling, and Discord reporting.

Features

  • Map Voting System - Players can vote for the next map. If no valid vote is cast, the plugin chooses a random valid map.
  • Rock The Vote (RTV) - Players can request an immediate map vote during the game.
  • Immediate RTV Option - If RTVDelayFromStart is set to 0 or below, RTV is available immediately after the match starts.
  • Map Nominations - Players can nominate maps for upcoming votes. Each player can have one active nomination.
  • Nomination Cooldown - Recently nominated maps can be temporarily blocked from being nominated again.
  • Map Pools - Maps can be grouped into named pools. The active pool is used by RTV, map votes, admin votes, and automatic map changes.
  • Pool Voting - Players can vote to start a pool vote and then choose the active pool.
  • Low-Player Pool - A separate low-player map list can be used automatically when the server population is below the configured threshold.
  • Menu Modes - Map votes, nominations, and pool votes can use wasd, chat, or both menu modes.
  • Panorama Yes/No Vote - The admin "Vote to Change Map or Not" flow can use the native CS2 Panorama vote UI.
  • Player Count Thresholds - Maps can define minimum and maximum player counts.
  • Map Display Names - Maps can have friendly names shown in menus and messages.
  • Map Weights - Random map selection can be weighted per map.
  • Extend Map Limit - The number of map extensions per map can be limited.
  • No Vote Line - Optional "No Vote" line can be added to vote menus to reduce accidental map selections.
  • WASD Vote Counters - WASD vote menus can show live vote counts next to options.
  • Admin Controls - Admins can change maps, start votes, start yes/no votes, set the next map, switch pools, and start pool votes.
  • External Controls - Server commands allow other plugins or configs to start map votes and trigger selected map changes.
  • Discord Logging - Loaded and voted maps can be reported to Discord with a configurable message template.
  • Timer Reliability Improvements - Vote and map-change timer handling has been improved to avoid blocked or mistimed votes.

Configuration Files

Map Configuration

Define maps in csgo/cfg/GGMCmaps.json. Each map entry supports:

  • ws - true for Workshop maps, false for classic maps.
  • display - Friendly display name shown in menus and chat.
  • mapid - Workshop map ID. Required for Workshop maps outside the server collection.
  • minplayers - Minimum player count required for the map. 0 disables the lower limit.
  • maxplayers - Maximum player count allowed for the map. 0 disables the upper limit.
  • weight - Random selection weight. Higher values increase the chance of being selected. 0 disables random selection. -1 uses OtherSettings.DefaultMapWeight.

Legacy Map List Format

The legacy flat format is still supported. When this format is used, the plugin treats the whole map list as one pool named default.

{
  "de_mirage": {
    "ws": false,
    "display": "Mirage",
    "mapid": "",
    "minplayers": 0,
    "maxplayers": 0,
    "weight": 1
  }
}

Pool-Based Map List Format

Maps can now be grouped into named pools. The active pool is used by normal map votes, RTV, admin map votes, and automatic random map changes.

{
  "Small Maps": {
    "gg_small_map": {
      "ws": false,
      "display": "Small Map",
      "mapid": "",
      "minplayers": 0,
      "maxplayers": 12,
      "weight": 1
    }
  },
  "Large Maps": {
    "gg_large_map": {
      "ws": false,
      "display": "Large Map",
      "mapid": "",
      "minplayers": 10,
      "maxplayers": 0,
      "weight": 1
    }
  }
}

When a pool-based map list is used, the active pool is selected in this order:

  1. The previous active pool, if it still exists.
  2. PoolVoteSettings.DefaultPool, if configured and found.
  3. The first available pool in GGMCmaps.json.

When an admin switches the active pool manually, the plugin clears pending nominations, admin-selected maps, pending next map state, and temporary vote state.

Plugin Settings

Customise plugin behaviour in csgo/addons/counterstrikesharp/configs/plugins/GG1MapChooser/GG1MapChooser.json.

The config is divided into these sections:

  • VoteSettings - map vote, nomination, menu, no-vote, extend, and Panorama yes/no vote settings.
  • RTVSettings - Rock The Vote settings.
  • PoolVoteSettings - map pool voting settings.
  • WinDrawSettings - round/win based vote timing.
  • TimeLimitSettings - time-limit based vote timing.
  • DiscordSettings - Discord webhook reporting.
  • MenuSettings - WASD menu behaviour.
  • OtherSettings - additional behaviour such as sounds, map-change delay, low-player maps, and default map weight.

VoteSettings

  • RememberPlayedMaps - Number of recently played maps excluded from upcoming votes.
  • RememberNominatedMaps - Number of recently nominated maps kept in nomination cooldown. 0 disables cooldown.
  • MapsInVote - Number of maps shown in a vote.
  • VotesToWin - Vote ratio required to win or start threshold-based actions. Example: 0.6 means 60%.
  • AllowNominate - Allows players to nominate maps.
  • NominationsMenuMode - Nomination menu mode: wasd, chat, or both. Empty values fall back to wasd.
  • EndMapVoteMenuMode - End-of-map vote menu mode: wasd, chat, or both. Empty values fall back to wasd.
  • YesNoVotePanorama - Enables native Panorama yes/no voting for the admin "Vote to Change Map or Not" flow.
  • PanoramaSFUIString - SFUI string used by the Panorama yes/no vote.
  • VotingTime - Duration in seconds for map votes.
  • ExtendMapInVote - Adds the "Extend Map" option to map votes.
  • ExtendMapTimeMinutes - Number of minutes added when "Extend Map" wins.
  • MaxExtendMapCount - Maximum number of times the current map can be extended. 0 means unlimited.
  • ChangeMapAfterVote - Changes the map after vote completion when the vote is not already configured as an immediate change.
  • SpectatorsCanVote - Allows or blocks spectator voting.
  • IncludeNoVote - Adds a "No Vote" option to vote menus.

RTVSettings

  • AllowRTV - Enables Rock The Vote.
  • RTVDelayFromStart - Initial delay in seconds before RTV is allowed. If this is 0 or below, RTV is available immediately after the match starts.
  • IntervalBetweenRTV - Cooldown in seconds after an RTV starts before another RTV can start.
  • NoRTVafterRoundsPlayed - Blocks RTV after this many rounds have been played. 0 disables this restriction.

PoolVoteSettings

  • Enable - Enables player/admin pool voting.
  • DefaultPool - Preferred active pool name when the mapcycle is loaded. If empty or not found, the first available pool is used.
  • DelayFromStart - Initial delay in seconds before pool voting is available.
  • IntervalBetweenVotes - Cooldown in seconds after a pool vote starts before another pool vote can start.
  • VotesToWin - Required player vote ratio to start a pool vote. If 0, VoteSettings.VotesToWin is used.
  • VotingTime - Time in seconds for players to choose a pool after the pool vote menu opens.
  • BlockBeforeMapVoteSeconds - In time-limit mode, blocks pool voting when the scheduled map vote is this many seconds away or closer.
  • BlockBeforeMapVoteRounds - In round-wins mode, blocks pool voting when the scheduled map vote is this many rounds away or closer.
  • MenuMode - Pool vote menu mode: wasd, chat, or both. Empty values fall back to wasd.

WinDrawSettings

  • VoteDependsOnRoundWins - Enables round/win based vote timing.
  • TriggerRoundsBeforeEnd - Number of rounds before the end of the match to start the vote.
  • TriggerRoundsBeforeEndVoteAtRoundStart - Starts the scheduled vote on round start when true, or round end when false.
  • TriggerVoteAtRoundStartSecondsFromStart - Delay in seconds from round start before starting the vote.
  • ChangeMapAfterWinDraw - Changes the map after the win/draw event if a next map has been selected.

TimeLimitSettings

  • VoteDependsOnTimeLimit - Enables time-limit based vote timing using mp_timelimit.
  • TriggerSecondsBeforeEnd - Number of seconds before the time limit ends to start the vote.
  • ChangeMapAfterTimeLimit - Changes to the selected map when the time limit expires.
  • VoteNextRoundStartAfterTrigger - Starts the vote at the next round start after the time-limit trigger.
  • VoteRoundEndAfterTrigger - Starts the vote at round end after the time-limit trigger.
  • MinutesExtendTimeLimitToRoundEnd - Temporarily extends the time limit so the delayed round-start or round-end vote can happen.

DiscordSettings

  • DiscordWebhook - Discord webhook URL used for map reports.
  • DiscordMessageMapStart - Reports map starts to Discord.
  • DiscordMessageAfterVote - Reports map vote results to Discord.
  • PictureExtension - File extension used when building map image URLs for Discord embeds.

MenuSettings

  • DisplayVotesCount - Shows vote counters next to options in WASD vote menus.
  • SoundInMenu - Enables menu navigation sounds.
  • FreezePlayerInMenu - Freezes regular players while they use WASD menus.
  • FreezeAdminInMenu - Freezes admins while they use WASD admin menus.
  • FreezeMode - Freeze method used by the menu.
  • ScrollUp, ScrollDown, Choose, Back, Exit - Button bindings for WASD menus.

OtherSettings

  • PrintPlayersChoiceInChat - Prints player choices to everyone instead of only to the player.
  • PrintNextMapForAll - Prints nextmap output to all players.
  • DelayBeforeChangeSeconds - Delay before changing the map after configured vote/end events.
  • VoteStartSound - Sound played when a map vote starts.
  • RandomMapOnStart - Changes to a random map after server start.
  • RandomMapOnStartDelay - Delay before random map change after server start.
  • LastDisconnectedChangeMap - Changes to a random map after the last player disconnects.
  • WorkshopMapProblemCheck - Detects workshop map load failures and retries/falls back to random map handling.
  • TvStopRecord - Stops TV recording before map changes.
  • DefaultMapWeight - Default random selection weight for maps with weight = -1.
  • LowPlayerMaxPlayers - Maximum real player count, including spectators, for low-player mode.
  • LowPlayerMaps - Map list used while low-player mode is active. Entries use the same format as normal map entries.

How New Features Work

Pool Voting

Players can request a pool vote with rtm, !rtm, /rtm, css_rtm, or !css_rtm. Admins can also start a pool vote from css_maps.

Pool voting has two stages:

  1. Players first vote to start a pool vote, similar to RTV.
  2. When the threshold is reached, the plugin opens a menu where players choose the pool.

A pool wins only if it is the single option with the highest vote count. If no one votes, the result is tied, or the current pool wins, the active pool stays unchanged. If a different pool wins, it becomes the active pool and pool-sensitive state is cleared.

If a map vote is due while a pool vote is in progress, the map vote is queued and starts after the pool vote finishes.

Pool voting requires at least two pools and exactly one automatic map vote mode: either time-limit based voting or round/win based voting. If both are enabled or both are disabled, pool voting is disabled to avoid ambiguous timing.

Low-Player Pool

Low-player maps are configured in OtherSettings.LowPlayerMaps. This list is separate from normal map pools and does not appear in pool votes.

Low-player mode is active when the number of real players, including spectators, is less than or equal to OtherSettings.LowPlayerMaxPlayers.

When active, normal map votes, RTV, and automatic random map changes use LowPlayerMaps. When the player count rises above the threshold, the plugin returns to the normal active pool.

Menu Modes

wasd opens only the WASD HTML menu. chat or chatmenu opens only the CounterStrikeSharp chat menu. both opens both menu types at the same time; selecting in one closes the other. Empty or unknown values fall back to wasd.

The admin "Vote to Change Map or Not" flow uses Panorama voting when VoteSettings.YesNoVotePanorama is true. In that case, EndMapVoteMenuMode does not apply to that yes/no vote.

Nomination Cooldown

When VoteSettings.RememberNominatedMaps is greater than 0, nominated maps from completed votes are added to a recent nomination cooldown list. Maps in this list cannot be nominated again and are shown as disabled entries in nomination menus.

This is a map-count based cooldown, not a time-based cooldown.

Maximum Map Extend Count

VoteSettings.MaxExtendMapCount limits how many times the current map can be extended through the Extend Map vote option. 0 means unlimited. The counter resets with the map state.

Immediate RTV

If RTVSettings.AllowRTV is true and RTVSettings.RTVDelayFromStart is 0 or below, RTV is available immediately after the match starts. After an RTV starts, RTVSettings.IntervalBetweenRTV is still used as the cooldown before another RTV can start.

Configuration Example

{
  "VoteSettings": {
    "RememberNominatedMaps": 3,
    "NominationsMenuMode": "both",
    "EndMapVoteMenuMode": "wasd",
    "YesNoVotePanorama": true,
    "PanoramaSFUIString": "#SFUI_Vote_None",
    "MaxExtendMapCount": 2
  },
  "PoolVoteSettings": {
    "Enable": true,
    "DefaultPool": "Small Maps",
    "DelayFromStart": 90,
    "IntervalBetweenVotes": 120,
    "VotesToWin": 0.6,
    "VotingTime": 20,
    "BlockBeforeMapVoteSeconds": 30,
    "BlockBeforeMapVoteRounds": 1,
    "MenuMode": "both"
  },
  "MenuSettings": {
    "DisplayVotesCount": true
  },
  "OtherSettings": {
    "LowPlayerMaxPlayers": 8,
    "LowPlayerMaps": {
      "gg_small_map": {
        "ws": false,
        "display": "Small Map",
        "mapid": "",
        "minplayers": 0,
        "maxplayers": 8,
        "weight": 1
      }
    }
  }
}

Discord Message Configuration

Define the text you want to display in csgo/addons/counterstrikesharp/configs/plugins/GG1MapChooser/NextMapMessage.json:

  • The config file is created automatically if it does not exist.
  • You can modify or localise the text, for example: content = "Next map: ".
  • To display map pictures, set the image folder URL in the message template.
  • Map images must follow the naming convention <mapname>.<PictureExtension>.

Usage

  • RTV: Players can use rtv, !rtv, or /rtv.
  • Pool Voting: Players can use rtm, !rtm, /rtm, css_rtm, or !css_rtm.
  • Nominating: Players can use nominate, !nominate <mapname>, or the yd alias.
  • Revote: Players can use revote to reopen the active vote menu and change their vote.
  • Next Map: Players can use nextmap to see the selected next map.
  • Time Left: Players can use timeleft to see time or round information, depending on the active vote mode.

Setup Examples

  • If another plugin ends the game and only needs GG1MapChooser to select the next map, use ggmc_mapvote_start.
  • If another plugin needs GG1MapChooser to select and immediately change to the winning map, use ggmc_mapvote_with_change.
  • For round/win based voting, enable WinDrawSettings.VoteDependsOnRoundWins, configure TriggerRoundsBeforeEnd, and decide whether the vote should start on round start or round end.
  • For time-limit based voting, enable TimeLimitSettings.VoteDependsOnTimeLimit and make sure TriggerSecondsBeforeEnd leaves enough time for VoteSettings.VotingTime.
  • For pool voting, use a pool-based GGMCmaps.json with at least two pools and enable PoolVoteSettings.Enable.
  • For low-player maps, fill OtherSettings.LowPlayerMaps and set OtherSettings.LowPlayerMaxPlayers to the desired threshold.

Plugin Commands

Player Commands

  • rtv - Rock The Vote.
  • rtm / css_rtm - Request a map pool vote.
  • nominate - Open nomination menu.
  • nominate <mapname> - Nominate a specific map.
  • yd - Nomination alias.
  • revote - Reopen the active vote menu.
  • nextmap - Show the selected next map.
  • timeleft - Show remaining time or round information.

Admin Commands

  • css_maps / !maps - Opens the admin map menu.
  • ggmap <partofmapname> - Quickly find and change to a map by partial name.
  • ggmap <exactmapname> - Server-side exact map change command for scripts/plugins.
  • setnextmap - Set the next map without starting a vote.

External Controls

  • ggmc_mapvote_start [time] - Starts a map vote externally and sets nextlevel to the winning map.
  • ggmc_mapvote_with_change [time] - Starts a map vote externally and changes map after the vote ends.
  • ggmc_auto_mapchange - Changes to a random valid map.
  • ggmc_nortv - Temporarily disables RTV.
  • ggmc_change_nextmap - Immediately changes to the previously selected next map.
  • reloadmaps - Reloads GGMCmaps.json.

Suggested Server Testing

  • Start with a pool-based GGMCmaps.json containing at least two pools.
  • Set PoolVoteSettings.Enable = true.
  • Use rtm, !rtm, or css_rtm and confirm that a pool vote starts after the configured vote threshold.
  • Confirm that ties and votes for the current pool keep the existing active pool.
  • Switch pools from css_maps and confirm that nominations and pending selected maps are cleared.
  • Set LowPlayerMaxPlayers above the current online count and confirm RTV/map vote uses LowPlayerMaps.
  • Test NominationsMenuMode, EndMapVoteMenuMode, and PoolVoteSettings.MenuMode with wasd, chat, and both.
  • Set RememberNominatedMaps above 0, nominate a map, complete a vote, and confirm the map cannot be nominated again until it leaves cooldown.
  • Set MaxExtendMapCount = 1, enable ExtendMapInVote, extend once, and confirm the extend option is not available again on the same map.
  • Set RTVDelayFromStart = 0 and confirm RTV is available immediately after the match starts.

Important Notes About Usage

  • If the server has an assigned Workshop collection (+host_workshop_collection [collection number]), map names from that collection can be used without mapid.
  • If Workshop maps are not from the assigned collection, fill in mapid.
  • If mapid is missing for a Workshop map outside the collection, the server might not be able to change to it by name.
  • Workshop map names should match the actual Workshop names exactly, especially when WorkshopMapProblemCheck is enabled.
  • Pool voting requires at least two pools.
  • Pool voting must happen before the next map vote. It can be blocked by BlockBeforeMapVoteSeconds or BlockBeforeMapVoteRounds.
  • If both VoteDependsOnTimeLimit and VoteDependsOnRoundWins are enabled, or both are disabled, pool voting is disabled.
  • Low-player maps are separate from normal pools and do not appear in pool votes.

Plugin Compilation

To compile the plugin, download or reference the API project from ggmcAPI.

Plugin APIs

The plugin exposes these capabilities to other plugins.

  • Maps API:
    • public bool GGMC_IsVoteInProgress(); - returns whether a map vote is currently in progress.
  • WASD Menu API:
    • public IWasdMenu CreateMenu(string title = "", bool freezePlayer = true, bool displayOptionsCount = false); - creates a WASD menu.
    • public void OpenMainMenu(CCSPlayerController? player, IWasdMenu? menu); - opens a menu as the main menu.
    • public void OpenSubMenu(CCSPlayerController? player, IWasdMenu? menu); - opens a menu as a submenu.
    • public void CloseActiveMenu(IWasdMenu? menu); - closes an active menu object.
    • public void CloseActiveMenu(CCSPlayerController? player); - closes the player's active menu.
    • public BaseMenu MenuByType(string menuType, string title, BasePlugin plugin); - creates an adapter menu by type name.
    • public BaseMenu MenuByType(Type menuType, string title, BasePlugin plugin); - creates an adapter menu by type.

Disclaimer

The plugin is provided "as-is" and fulfils the specific requirements it was designed for. Suggestions that benefit a broader user base are welcome.

Credits

Thank you to UMC Mapchooser for the main ideas.

Special thanks to T3Marius for WASD menu ideas and design.

Thanks to:

  • crashzk for the Portuguese translation.
  • YuYueCraft for the Chinese translation.

Donations

Donate with PayPal

About

Map changing management for CS2 on CounterStrikeSharp

Resources

Stars

56 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages