End-of-map voting, rock-the-vote, nominations and map extensions for ModSharp CS2 servers.
A complete map-management module for ModSharp CS2 servers: end-match map voting on the native CS2 vote panel, rock-the-vote, player nominations, and time-limit extensions — with a map pool that automatically matches the engine's active mapgroup. Built for and used on YappersHQ.com TTT servers.
Copy the build output into your ModSharp install (<sharp> = your sharp directory):
| From | To |
|---|---|
.build/modules/YappersHQ.MapChooser/ |
<sharp>/modules/YappersHQ.MapChooser/ |
.build/shared/YappersHQ.MapChooser.Shared/ |
<sharp>/shared/YappersHQ.MapChooser.Shared/ |
.build/gamedata/yappershq.mapchooser.jsonc |
<sharp>/gamedata/yappershq.mapchooser.jsonc |
.build/locales/YappersHQ.MapChooser.json |
<sharp>/locales/YappersHQ.MapChooser.json |
The map pool config (configs/mapmanager/maplist.jsonc) is auto-generated from a template on first run. Restart the server or change map to load.
Uses the ModSharp first-party modules (ship with ModSharp): CommandCenter (rtv / nominate / ext commands), LocalizerManager (28-language localization), and MenuManager (the nomination map menu — optional; nominate-by-name still works without it).
External plugins:
| Plugin | Required? | Why |
|---|---|---|
| AdminPanel | ⚪ Optional | Adds a Map Management entry to the admin panel (change map / start map vote / force end-match vote / go next round), gated by the admin:map permission. MapChooser runs fully standalone without it. |
| Command | Description |
|---|---|
rtv |
Cast (or opt in to) a rock-the-vote to change the map |
unrtv |
Take back your rock-the-vote |
nominate [map] |
Nominate a map for the end-match vote — no argument opens a picker menu |
ext |
Vote to extend the current map's time limit |
mapmanager_reload |
(console) Reload maplist.jsonc into the pool live — no restart |
Chat commands use your server's configured chat trigger (e.g. !rtv, .nominate). Nominated maps are prioritized in the end-match vote; remaining slots are filled randomly from the pool, excluding recently played maps.
Map pool — configs/mapmanager/maplist.jsonc:
ConVars:
| ConVar | Default | Meaning |
|---|---|---|
mapmanager_format_prefix |
{whitespace}{red}YappersHQ.com{whitespace}{muted} |
Chat message prefix |
mapmanager_vote_success_ratio |
0.6 |
Fraction of players needed for an RTV / extend vote to pass |
mapmanager_countdown_after_changelevel |
180 |
Seconds after a map change before RTV / extend are allowed |
mapmanager_maps_in_cooldown |
3 |
Number of recent maps excluded from votes and nominations |
mapmanager_enable_rtv |
true |
Enable rock-the-vote |
mapmanager_rtv_enabled_in_warmup |
true |
Allow RTV during warmup |
mapmanager_rtv_min_rounds |
0 |
Rounds that must be played before RTV is available |
mapmanager_rtv_min_players |
1 |
Minimum player count for RTV |
mapmanager_rtv_ignore_spec |
true |
Block spectators from using RTV |
mapmanager_enable_nominate |
true |
Enable nominations |
mapmanager_activate_nominate_min_players |
1 |
Minimum players to allow nominations |
mapmanager_enable_extend |
true |
Enable map-extension votes |
mapmanager_extend_min_rounds |
0 |
Rounds that must be played before extend is available |
mapmanager_max_extend_count |
3 |
Maximum times a map can be extended |
mapmanager_ext_time |
15 |
Minutes added per extension |
MapChooser hooks CSource2Server::ApplyGameSettings to read the engine's active mapgroup, so its pool always matches the maps the server actually serves. The end-match vote drives the native CS2 panorama vote screen — nominations take priority, the rest of the slots are filled at random from the pool with recently played maps excluded. RTV and extend are ratio-based chat votes with configurable player/round/warmup gates.
Other modules consume IMapManager from YappersHQ.MapChooser.Shared (resolve in OnAllModulesLoaded):
var mapManager = sharpModuleManager
.GetRequiredSharpModuleInterface<IMapManager>(IMapManager.Identity)
.Instance!;
var maps = mapManager.GetMaps(); // maps in the pool
mapManager.ChangeLevel("de_dust2"); // change map programmatically
mapManager.MapConfigLoaded += () => { }; // fires on live maplist reloaddotnet build -c ReleaseOutputs .build/modules/YappersHQ.MapChooser/YappersHQ.MapChooser.dll plus the shared interface, gamedata, and locales under .build/.
Forked from laper32/Ptr by laper32 — the original ModSharp map-chooser this module is built on.
Made with ❤️ by yappershq
⭐ Star this repo if you find it useful!
[ { "MapName": "de_dust2", // required "WorkshopId": null, // Steam Workshop ID (loads via host_workshop_map); null for stock maps "Countdown": 3, // cooldown weight "MinPlayers": 0, // 0 = no minimum "MaxPlayers": 0 // 0 = no limit } ]