Player guide
Client behaviour changes
Behaviour the console reference cannot express, because it is not controlled by a cvar. What changed, why, and what you have to provide to use it.
Override shaders: .oshader
Two mods that both patch a shader living in the same base .shader file used to be
impossible to combine. Each shipped its own copy of the whole file, so installing both meant
one silently replaced the other, and the only fix was merging them by hand.
TaystJK adds a second shader extension. The renderer lists shaders/*.oshader alongside
shaders/*.shader, and a shader defined in an .oshader file wins over every .shader
definition of the same name from any pk3, including the base assets.
The mechanism is worth knowing because it explains the guarantee. All shader files are
concatenated into one buffer before parsing, and .oshader contents are placed at the
front of it
(tr_shader.cpp).
Lookup walks the hash bucket and returns the first match it finds
(FindShaderInShaderText),
so whatever sits earliest in that buffer is what the game draws.
All three renderers implement it: rd-vanilla, rd-rend2, rd-vulkan.
Overriding one shader
Say a map’s glass is drawn by textures/example/glass, defined in shaders/example.shader
inside the map’s pk3, and you want it opaque without touching that pk3.
Create shaders/myfixes.oshader containing only the shader you are replacing:
textures/example/glass
{
{
map textures/example/glass
blendFunc GL_ONE GL_ZERO
}
}
Package that file as shaders/myfixes.oshader inside your own pk3. You do not copy the
rest of example.shader, and you do not have to load after the map’s pk3. The extension
alone decides. Every other shader in example.shader keeps working.
The count of loaded override files is printed at startup, so you can confirm yours was found.
Precedence between .shader files
.oshader does not change the ordering described here; it sits in front of it. The
ordinary rules are unchanged, and they are worth knowing, because they are what the
override extension works around.
Two pk3s shipping the same filename, both carrying their own shaders/gfx.shader,
resolve the ordinary way. The file list is uniqued by name
(FS_AddFileToList),
so the name is listed once and the renderer reads whichever pk3 has priority. This is why
mods ship a whole copy of a file to change one shader in it, and why installing two such
mods loses one of them.
The case that surprises people is one shader name defined in two differently named files. That is settled by position in the concatenated text, and the order comes out inverted relative to normal file precedence:
FS_ListFileswalks the search paths from highest priority to lowest (FS_ListFilteredFiles). Pk3s are mounted in ascending name order (paksort) and each one is pushed onto the front of the search path (FS_AddGameDirectory), sozzz.pk3’s shader files are listed first andassets0.pk3’s last.- The
.shaderbuffers are then concatenated in reverse list order (tr_shader.cpp), which puts the lowest-priority file at the front of the text. - First match wins.
So if gfx/2d/charsgrid_med is defined in shaders/original.shader inside the base assets
and again in shaders/fonts.shader inside your pk3, the base assets definition is the one
used. Naming your pk3 to load later does not change it. Within a single pk3 the order is
just the order of the entries in the archive, so do not rely on it either.
.oshader sidesteps all of this rather than reordering it: override buffers are placed
ahead of every .shader buffer, so they win regardless of which pk3 they came from. Among
.oshader files themselves the order is forward
(tr_shader.cpp),
so between two overrides of the same shader the higher-priority pk3 wins, restoring normal
precedence.
Binds
Modifier combinations. Every key holds a separate binding per modifier: plain, alt+,
ctrl+ and shift+
(keys.h),
so bind ctrl+x kill leaves plain X alone. bind and unbind both take the
prefix
(cl_keys.cpp).
A modifier key cannot be bound to itself with its own prefix.
Right-side modifiers. RCTRL, RALT and RSHIFT are their own key names and take
their own bindings
(cl_keys.cpp),
so bind rctrl kill affects only the right-hand key.
If the right-hand key has no binding of its own, the press falls back to the generic one
(CL_ParseBinding).
So bind ctrl +attack gives you both Ctrl keys, and bind rctrl kill on top of it
overrides only the right one. There is no fallback in the other direction: SHIFT, CTRL
and ALT are the left-hand keys, and nothing you bind to RCTRL reaches them.
Which modifier counts as held. Only the left-hand modifier arms a ctrl+ style binding
(cl_keys.cpp).
Hold the right Ctrl and press X and you get plain X, not
ctrl+x. The right-hand keys can carry bindings, but they cannot act as modifiers for
another key. When more than one is held, the order is alt, then ctrl, then shift.
Console and chat editing
Both the console and the chat prompt support word-wise editing. Ctrl plus
Backspace, Delete, Left or Right acts on a whole
word instead of a character, and adding Shift changes where the word boundary is
taken
(cl_keys.cpp).
Each shortcut accepts either the left or the right modifier.
con_height sets how far the console drops down.
con_datetime draws a date and time display in the console
(cl_console.cpp).
Use con_timestamps for per-line timestamps
(cl_console.cpp).
Look these up in the console reference for their defaults and flags.
Widescreen assets
The client prefers widescreen art where an author provides it, and falls back to the 4:3 original otherwise. Nothing breaks if you supply neither.
| Provide | Used instead of | Where |
|---|---|---|
levelshots_16_9/<mapname> |
levelshots/<mapname> |
loading screen and the map list |
menu/art/unknownmap_mp_16_9 |
menu/art/unknownmap_mp |
map with no levelshot |
menu/splash_16_9 |
menu/splash |
startup splash |
As a map author, add the widescreen levelshot to your pk3 under levelshots_16_9/ using the
same name as the map. All three renderers load the splash image.
Sharper fonts
r_fontSharpness scales glyph rendering with your vertical resolution rather than the
fixed 480-line reference
(tr_font.cpp).
It only helps where the font assets carry enough detail to scale up; with the retail fonts
there is nothing extra to reveal.
Last changed History Edit this page on GitHub