Cvar Binding Reference

February 11, 2026 · View on GitHub

Console variable (cvar) bindings connect Quake engine state to the RmlUI menus. This document maps bound cvars: engine registration, UI binding name, type, and where they are used in templates (or whether they are currently unused).

For the binding system architecture, see RmlUI Integration Guide.

Architecture

Data Flow

Engine cvar_t ──► QuakeCvarProvider::GetFloat() ──► CvarBindingManager backing store ──► RmlUI data model "cvars"
                  (Cvar_VariableValue, double→float)     s_float_values / s_int_values       {{ name }}, data-value, data-if

Read path (engine → UI): UI_PushMenu() calls SyncToUI(), which iterates all bindings, reads each cvar via Cvar_VariableValue(), and writes into backing stores. MarkDirty() triggers RmlUI to re-evaluate template expressions.

Write path (UI → engine): User interaction fires cvar_changed('name') (sliders) or cycle_cvar('name', 1) (toggles/enums). MenuEventHandler calls SyncFromUI() or CycleEnum(), which updates the backing store and calls Cvar_SetValue().

Feedback loop prevention: SyncToUI() sets a 2-frame ignore window so that UI-triggered changes don't re-fire cvar_changed events.

Type Safety

All extern "C" declarations correctly match engine signatures:

FunctionEngine Return TypeC++ DeclarationFiles
Cvar_VariableValue()doubledoublequake_cvar_provider.cpp:11, ui_manager.cpp:32, notification_model.cpp:12
Cvar_SetValue()void (takes float)void (takes float)quake_cvar_provider.cpp:9
Cvar_VariableString()const char*const char*quake_cvar_provider.cpp:13

One implicit narrowing: QuakeCvarProvider::GetFloat() returns float from a double source. Harmless for Quake's value ranges but worth noting.

Source Files

FileRole
src/internal/cvar_binding.h/.cppBinding registration, sync, cycle logic
src/internal/quake_cvar_provider.h/.cppICvarProvider impl, extern "C" wrappers
src/internal/menu_event_handler.cppDispatches cvar_changed() and cycle_cvar() actions
src/types/cvar_schema.hCvar metadata (type, range, step, enum values)
src/types/cvar_provider.hICvarProvider interface

Float Bindings (Sliders)

Registered via RegisterFloat(engine_name, ui_name, min, max, step). Used in RML as <input type="range" data-value="name" ... onchange="cvar_changed('name')"/>.

Engine CvarUI NameDefaultRangeStepRML FileNotes
fovfov9050–1305options_graphics.rml
gammagamma0.90.5–2.00.05options_graphics.rml
contrastcontrast1.40.5–2.00.05options_graphics.rml
host_maxfpsmax_fps20030–100010options_graphics.rml
volumevolume0.70–10.05options_sound.rml
bgmvolumebgmvolume10–10.05options_sound.rml
sensitivitysensitivity31–200.5options_game.rml
scr_sbaralphahud_opacity0.750–10.05options_game.rmlHooks into post-process UI opacity
scr_uiscaleui_scale10.5–3.00.25options_game.rmlRegistered in engine (gl_screen.c)
cl_bobview_bob0.020–0.050.005options_game.rml
cl_rollangleview_roll2.00–5.00.5options_game.rml

Bool Bindings (Toggles)

Registered via RegisterBool(engine_name, ui_name). Toggled in RML with onclick="cycle_cvar('name', 1)" and displayed with data-if="name".

Engine CvarUI NameDefaultRML FileNotes
vid_fullscreenfullscreen0(unused in RML templates)Video menu uses command path (vid_nextfullscreen) + computed label
vid_vsyncvsync0(unused in RML templates)Video menu uses command path (vid_nextvsync) + computed label
vid_palettizepalettize0options_graphics.rml
r_dynamicdynamic_lights1options_graphics.rml
r_waterwarpunderwater_fx1options_graphics.rml
r_lerpmodelsmodel_interpolation1options_graphics.rml
m_pitchinvert_mouse0.022options_game.rmlSign-based: reads m_pitch < 0 ? 1 : 0, flips sign on toggle
cl_alwaysrunalways_run1options_game.rml
m_filterm_filter0options_game.rml
r_drawviewmodelshow_gun1options_game.rmlCVAR_NONE — not archived
cl_startdemosstartup_demos1options_game.rml
bgm_extmusicbgm_extmusic1options_sound.rml
snd_waterfxsnd_waterfx1options_sound.rml

Enum Bindings (Cycle Buttons)

Registered via RegisterEnum(engine_name, ui_name, values, labels). Cycled with onclick="cycle_cvar('name', 1)", label shown via {{ name_label }}.

Engine CvarUI NameDefaultValues → LabelsRML FileNotes
gl_picmiptexture_quality00=High, 1=Medium, 2=Lowoptions_graphics.rmlCVAR_NONE
vid_filtertexture_filter00=Smooth, 1=Classicoptions_graphics.rml
vid_anisotropicaniso01/2/4/8/16 = Off–16xoptions_graphics.rml
vid_fsaamsaa00/2/4/8 = Off–8xoptions_graphics.rml
vid_fsaamodeaa_mode00=Off, 1=FXAA, 2=TAAoptions_graphics.rml
r_scalerender_scale11/2/4 = Native/2x/4xoptions_graphics.rml
r_particlesparticles10=Off, 1=Classic, 2=Enhancedoptions_graphics.rml
r_enhancedmodelsenhanced_models10=Off, 1=Onoptions_graphics.rml
snd_mixspeedsound_quality4410011025/22050/44100/48000options_sound.rmlCVAR_NONE
ambient_levelambient0.30=Off, 1=Onoptions_sound.rml
crosshaircrosshair10=Off, 1=Cross, 2=Dot, 3=Circle, 4=Chevronoptions_game.rml
scr_showfpsshow_fps00=Off, 1=Onoptions_game.rml
sv_aimsv_aim10=Off, 1=Onoptions_game.rmlCVAR_NONE
v_gunkickgun_kick10=Off, 1=Classic, 2=Smoothoptions_game.rml
autofastloadauto_load00=Off, 1=Onoptions_game.rml
skillskill10–3 = Easy/Normal/Hard/Nightmareoptions_game.rmlCVAR_NONE
_cl_colorcl_color_top00–13 (color names)player_setup.rmlPacked/unpacked (top nibble)
_cl_colorcl_color_bottom00–13 (color names)player_setup.rmlPacked/unpacked (bottom nibble)
deathmatchdeathmatch00=Cooperative, 1=Deathmatchcreate_game.rml
teamplayteamplay00=Off, 1=No Friendly Fire, 2=Friendly Firecreate_game.rml
fraglimitfraglimit00/10/20/30/40/50/60/70/80/90/100create_game.rml
timelimittimelimit00/5/10/15/20/25/30/45/60create_game.rml

Direct Reads (Outside Binding System)

These cvars are read via raw Cvar_VariableValue() calls in C++ code, not through CvarBindingManager.

CvarRead LocationPurpose
scr_uiscaleui_manager.cppUpdateDpRatio()UI dp_ratio scaling; defaults to 1.0 if <0.5
con_notifytimenotification_model.cppNotify line expiry duration; defaults to 3.0 if <=0
scr_centertimenotification_model.cppCenterprint display duration; defaults to 2.0 if <=0
scr_printspeednotification_model.cppCenterprint character reveal speed (chars/sec); defaults to 8 if <=0

Non-Archived Cvars

These cvars use CVAR_NONE and won't persist to config. Changes made in the options menu are lost on restart unless the engine has another save mechanism.

  • gl_picmip (texture quality)
  • skill
  • sv_aim
  • snd_mixspeed (sound quality)
  • r_drawviewmodel (show gun)

Known Issues

No critical cvar-binding correctness issues are currently known in this layer.

Current limitation:

  • fullscreen and vsync are still registered bindings, but current UI uses vid_nextfullscreen/vid_nextvsync command actions in options_video.rml rather than cycle_cvar() on those specific UI names.