Match options control every aspect of your CS2 match, from basic settings like match type to advanced configurations like timeout permissions. This guide details all available options.
Basic Settings
Match Type
Select the competitive format:
e_match_types_enum . Competitive // Standard 5v5 competitive
e_match_types_enum . Wingman // 2v2 wingman format
e_match_types_enum . Custom // Custom format
Competitive
Wingman
Custom
Standard 5v5 competitive format:
5 players per team
MR12 default (12 rounds per half)
Full economy system
Active Duty map pool
2v2 format:
2 players per team
MR8 default (8 rounds per half)
Wingman-specific maps
Faster-paced gameplay
Fully customizable:
Any player count
Custom round settings
Any map pool
Maximum flexibility
Number of maps to play:
const bestOfOptions = [ 1 , 3 , 5 ]. map (( rounds ) => ({
value: rounds . toString (),
display: `Best of ${ rounds } ` ,
}));
The best-of value determines the veto process and match length. BO1 uses simplified veto, while BO3 and BO5 use full pick/ban sequences.
Map Configuration
Map Veto
Enable structured map selection:
< FormField v-slot = " { value , handleChange } " name = "map_veto" >
<FormItem>
<Card class="cursor-pointer" @click="handleChange(!value)">
<div class="flex justify-between items-center">
<FormLabel>Map Veto Settings</FormLabel>
<Switch :model-value="value" />
</div>
<FormDescription>
Teams alternate picking and banning maps until the required
number is selected
</FormDescription>
</Card>
</FormItem>
</ FormField >
Disabled : Direct map selection
Enabled : Teams follow veto protocol
Map Pool Selection
// Use Valve's official competitive map pool
match . options . custom_map_pool = false ;
match . options . map_pool_id = defaultMapPoolId ;
Map Pool Logic
The form automatically adjusts map pools based on settings:
watch : {
[ 'form.values.type' ]: {
handler ( type ) {
// Reset map pool when type changes
this . form . setFieldValue ( 'map_pool' , []);
if ( this . form . values . map_veto ) {
this . form . setFieldValue ( 'map_pool_id' , this . defaultMapPool . id );
}
},
},
[ 'form.values.map_veto' ]: {
handler ( mapVeto ) {
if ( mapVeto ) {
this . form . setFieldValue ( 'custom_map_pool' , false );
} else {
this . form . setFieldValue ( 'custom_map_pool' , true );
}
},
},
}
For non-veto matches with best-of > 1, the system limits map selection to the best-of value.
Game Settings
Max Rounds (MR)
Rounds per half before overtime:
< FormField v-slot = " { componentField } " name = "mr" >
<FormItem>
<FormLabel>Max Rounds</FormLabel>
<FormDescription>
Number of rounds per half (MR8, MR12, MR15)
</FormDescription>
<Select v-bind="componentField">
<SelectContent>
<SelectItem value="8">8</SelectItem>
<SelectItem value="12">12</SelectItem>
<SelectItem value="15">15</SelectItem>
</SelectContent>
</Select>
</FormItem>
</ FormField >
MR8 : Wingman matches, shorter competitive games
MR12 : Standard competitive (Valve default)
MR15 : Legacy competitive format (pre-CS2)
Overtime
Enable overtime rounds:
< FormField v-slot = " { value , handleChange } " name = "overtime" >
<FormItem>
<div class="flex flex-row items-center justify-between">
<div>
<FormLabel>Overtime</FormLabel>
<FormDescription>
Enable overtime periods if score is tied
</FormDescription>
</div>
<Switch :model-value="value" @update:model-value="handleChange" />
</div>
</FormItem>
</ FormField >
When enabled:
MR3 overtime periods (6 rounds total)
Economy reset each overtime
Repeat until winner determined
Knife Round
Starting side selection via knife round:
< FormField v-slot = " { value , handleChange } " name = "knife_round" >
<FormItem>
<div class="flex flex-row items-center justify-between">
<div>
<FormLabel>Knife Round</FormLabel>
<FormDescription>
Winner chooses starting side (CT or T)
</FormDescription>
</div>
<Switch :model-value="value" @update:model-value="handleChange" />
</div>
</FormItem>
</ FormField >
Knife rounds occur before each map. The winning team decides which side to start on.
Region Settings
Single Region
Select one server region:
< Select v-model = " select_single_region " >
<SelectContent>
<SelectItem
v-for="region in regions"
:value="region.value"
>
{{ region.description }}
</SelectItem>
</SelectContent>
</ Select >
Region Veto
Enable region selection process:
< FormField v-slot = " { value , handleChange } " name = "region_veto" >
<FormItem>
<Card @click="handleChange(!value)">
<div class="flex justify-between items-center">
<FormLabel>Region Veto</FormLabel>
<Switch
:model-value="value"
:disabled="form.values.lan"
/>
</div>
<FormDescription>
Teams alternate vetoing regions until one remains
</FormDescription>
</Card>
</FormItem>
</ FormField >
With region veto:
Select multiple preferred regions
Teams ban regions alternately
Final region hosts the server
// Region veto enabled
match . options . region_veto = true ;
match . options . regions = [ 'us-east' , 'us-west' , 'eu-west' ];
// Single region
match . options . region_veto = false ;
match . options . regions = [ 'us-east' ];
LAN Mode
For LAN tournaments:
< div class = "flex items-center gap-4" >
<span>LAN Match</span>
<Switch
:model-value="form.values.lan"
@update:model-value="(checked) => form.setFieldValue('lan', checked)"
/>
</ div >
LAN mode disables region veto and uses LAN-optimized server settings.
Player Settings
Substitutes
Allow additional players beyond starting lineup:
< FormField v-slot = " { value } " name = "number_of_substitutes" >
<FormItem>
<FormLabel>Number of Substitutes</FormLabel>
<FormDescription>
Substitutes can be swapped in during pauses (0-5)
</FormDescription>
<NumberField
:min="0"
:max="5"
:model-value="value"
@update:model-value="(val) => form.setFieldValue('number_of_substitutes', val)"
>
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>
</FormItem>
</ FormField >
Coaches
Coach functionality requires server plugin support. Not available on all servers.
Broadcast Settings
TV Delay
GOTV spectator delay:
< FormField v-slot = " { value } " name = "tv_delay" >
<FormItem>
<FormLabel>TV Delay</FormLabel>
<NumberField
:min="0"
:max="120"
:model-value="value"
>
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>
<FormDescription>
Delay in seconds (0-120) for GOTV spectators
</FormDescription>
</FormItem>
</ FormField >
Purpose:
Prevent stream sniping
Protect team strategies
Standard: 90 seconds for competitive matches
Match Flow Settings
Check-in Settings
Who must check in before match:
const checkInSettings = [
{
value: e_check_in_settings_enum . Admin ,
display: 'Admins Only' ,
},
{
value: e_check_in_settings_enum . Captains ,
display: 'Team Captains' ,
},
{
value: e_check_in_settings_enum . Players ,
display: 'All Players' ,
},
];
Ready Settings
Who can ready up the team:
const readySettings = [
{
value: e_ready_settings_enum . Admin ,
display: 'Admins Only' ,
},
{
value: e_ready_settings_enum . Captains ,
display: 'Team Captains' ,
},
{
value: e_ready_settings_enum . Coach ,
display: 'Coaches' ,
},
{
value: e_ready_settings_enum . Players ,
display: 'All Players' ,
},
];
Auto-Cancellation
Prevent abandoned matches:
< FormField v-slot = " { value , handleChange } " name = "auto_cancellation" >
<FormItem>
<div class="flex justify-between">
<div>
<FormLabel>Auto Cancellation</FormLabel>
<FormDescription>
Automatically cancel if players don't check in or match stalls
</FormDescription>
</div>
<Switch :model-value="value" @update:model-value="handleChange" />
</div>
<div v-if="value" class="space-y-4">
<FormField name="auto_cancel_duration">
<FormLabel>Check-in Timeout (minutes)</FormLabel>
<Input type="number" min="1" />
</ FormField >
< FormField name = "live_match_timeout" >
<FormLabel>Live Match Timeout (minutes)</FormLabel>
<Input type="number" min="1" />
</ FormField >
< / div >
</FormItem>
</FormField>
Timeout Settings
Tactical Timeouts
Who can call tactical timeouts:
const timeoutSettings = [
{ value: e_timeout_settings_enum . Admin , display: 'Admins' },
{ value: e_timeout_settings_enum . Coach , display: 'Coaches' },
{ value: e_timeout_settings_enum . CoachAndCaptains , display: 'Coaches & Captains' },
{ value: e_timeout_settings_enum . CoachAndPlayers , display: 'Everyone' },
];
Technical Timeouts
Separate permissions for technical issues:
< FormField name = "tech_timeout_setting" >
<FormLabel>Technical Timeout Permissions</FormLabel>
<FormDescription>
Who can call technical timeouts for issues
</FormDescription>
<Select>
<SelectContent>
<SelectItem v-for="setting in timeoutSettings" :value="setting.value">
{{ setting.display }}
</SelectItem>
</SelectContent>
</Select>
</ FormField >
Advanced Options
Match Mode
Control match progression:
const matchModeSettings = [
{
value: e_match_mode_enum . auto ,
display: 'Auto' ,
description: 'Match progresses automatically' ,
},
{
value: e_match_mode_enum . admin ,
display: 'Admin Controlled' ,
description: 'Admin must manually progress match' ,
},
];
Recommended for most matches:
Server automatically goes live when ready
Knife round proceeds automatically
Maps start without manual intervention
For controlled environments:
Admin must manually start each phase
Useful for broadcasts
Prevents accidental starts
Default Models
Force default player models:
< FormField v-slot = " { value , handleChange } " name = "default_models" >
<Card class="cursor-pointer" @click="handleChange(!value)">
<div class="flex justify-between items-center">
<FormLabel>Default Models</FormLabel>
<Switch :model-value="value" />
</div>
<FormDescription>
Force default player models (disables agent skins)
</FormDescription>
</Card>
</ FormField >
Enabling default models may improve competitive integrity by ensuring consistent player visibility.
Lobby Access
Control who can join the match:
e_lobby_access_enum . Open // Anyone can join
e_lobby_access_enum . Friends // Steam friends only
e_lobby_access_enum . Invite // Invite code required
e_lobby_access_enum . Private // Manual addition only
See Match Lobbies for detailed lobby access information.
Options Validation
The form validates all options:
import matchOptionsValidator from '~/utilities/match-options-validator' ;
const form = useForm ({
validationSchema: toTypedSchema (
matchOptionsValidator (
this ,
{
pug: z . boolean (). default ( true ),
team_1: z . string (). optional (),
team_2: z . string (). optional (),
},
useApplicationSettingsStore (). settings ,
),
),
});
Saving Options
Options are saved via GraphQL mutation:
await this . $apollo . mutate ({
variables: setupOptionsVariables ( form , {
mapPoolId: mapPoolId ,
matchOptionsId: this . match . options . id ,
}),
mutation: generateMutation ({
update_match_options_by_pk: [
{
pk_columns: { id: $ ( 'id' , 'uuid!' ) },
_set: setupOptionsSetMutation ( !! mapPoolId ),
},
{ id: true },
],
}),
});
Lock Behavior
Some options lock once match starts:
computed : {
isLocked (): boolean {
return (
!! this . match &&
[ e_match_status_enum . Veto , e_match_status_enum . Live ]. includes (
this . match . status ,
)
);
},
}
Once a match enters Veto or Live status, most options cannot be changed. Plan your configuration carefully.
Next Steps
Creating Matches Apply these options when creating matches
Match Lobbies Configure lobby access and notifications
Statistics See how options affect match statistics