Unvanquished 0.56 is there, 17 months after the last major release (0.55), 6 months after the 0.55.5 release. After 5 point releases, and 2 release candidates. We do deliver!
That’s a big release, with lots of stuff to talk about. Impressive background work has finally been merged and is ready to use. 🚀️
Among all the awesome work that has been contributed by many people who are credited below, it’s important to especially thank Slipher and Illwieckz for the huge amount of work they poured the month preceding that release in reviewing, merging, polishing, testing, debugging, and finally producing the release. That’s commitment, and they made it real.
It’s time to download and play the game! ![]()
Linear blend regime
OK, now that is a big topic to start a blog post with… Unvanquished 0.56 makes the official debut of our Linear blend regime.
This is part of a now decades-old effort at improving the lighting and rendering pipeline of the Unvanquished game.. On the Dæmon engine side, the research, and work on designing and plumbing that colorspace-aware pipeline itself started 7 years ago in 2019 on the Dæmon engine side. Xonotic people actually started the work on the Q3map2 map compiler side 15 years ago in 2011. For Unvanquished, this adds up to other efforts we did in the past 10 years (early research being done in 2016), like investigating better build options for better light falloff and bouncing.
So, what’s that linear blend regime about?
Once upon a time, game engines didn’t care about how color and light were blended. They did it the most naive way possible, they didn’t care about your nice textures meticulously crafted in your favorite image editor being stored in a specific colorspace, and the computed light being produced in a specific colorspace, and the final result being presented to the screen in a specific colorspace… and you guessed right, those colorspaces weren’t the same, and computations can only be done in one of those.
Those early engines just took all of this and mixed everything together. The games may have looked fine for unaware players : green, blue and red were still green, blue and red, but their intensities weren’t the right ones, and when blending them together, mistakes were mixed with more mistakes.
Players didn’t know, this was like muddy water for a pond fish, they didn’t know about clear water. Creators struggled with weird results and had to learn esoteric arcane knowledge to deal with them.
You could not expect seeing in game your textures the same way you seen them in editor. They looked similar, not the same. All colors were there, but slightly distorted from what you drawn. Now they will look the same. Also, you could not predict the outcome of a blend operation just based on what your mind expected. Blending 0.5 light from the [0,1] range would not be perceived as something receiving half the light intensity. All shadows were there, but wrong. Now this is fixed.
We inherited that original sin from our ancestry. Such mistakes were present in many games from the early 2000s like Quake 3, Doom 3 and others… Our Dæmon engine being originally based on Quake 3’s engine (with decades of work above), we inherited from that mitochondrial Eve the genetic disease. That disease was woven not only throughout the whole body, but also throughout every body of the population. Treating this required meticulously unraveling the chromosomes of every individuals one by one, without killing anyone of them.
Our friends from Xonotic already did the job on the map compiler side, Q3map2. We continued the work on the Engine side, Dæmon.
We also did something impressive but time consuming: we actually kept the disease encoded in the genetic code but made it dormant, so it can be activated anytime one of the thousands of accumulated community maps for Unvanquished and Tremulous (or any Quake3 derivative) is played, to keep them rendered as they were before.
Fixing all those mistakes is required for physically based rendering, light computation and texture blending requires it to be correct.
The whole authoring and rendering pipeline is now wired properly to do it right. What’s very interesting is that such physically correct pipeline was perfectly implementable in the early 2000’s, it was just a matter of using proper math equations. If you run the Dæmon engine from today on a compatible devices from that era, that physically correct pipeline will be used and will work. It’s just a matter of math being done properly. Just for fun, the screenshot used as an illustration for this blog post was taken on a Radeon X1950 PRO:

That new linear blending regime is only activated by the Dæmon engine when loading maps (game levels) made for it. All previously made maps are rendered the same as before. For building a map for the new blend regime, the map author has to use explicit map compiler options. The linear light pipeline spans over the full production pipeline, from mapping, baking, and rendering.
On mapping side, some existing textures meant to be blended may have to be tweaked, since they were likely tested using broken rendering formulæ, and then initially designed to workaround the bugs. We implemented some material keywords to make it easy to port legacy transparent textures by either disabling some color conversion on a per-texture basis, or by making possible to write shader stages targetting specific pipelines.
Us providing this new production and rendering pipeline doesn’t deprecate any of previously released maps, they’re all rendered like before. In fact that new pipeline was already released in the 0.55.5 release, but wasn’t used yet for the simple reason no official map were shipped for it and then no map enabled it.
This 0.56 Unvanquished game release now ships with its official maps ported to the linear blend regime. We focused on fixing the most obvious regressions, but more polishing may come.
Since maps made for the linear blend regime requires to be baked the linear way, a new NetRadiant release will hopefully come soon. The updated build menu will provide entries for building maps for the new linear pipeline, as well as entries for building maps the old way. The linear build option will be usable for anyone wanting to port a map to the new pipeline, while the other compatibility build options will be there for those needing it, for example to quickly fix something in an existing map while postponing the port.
Map ports are usually straightforward, all map sources can be rebuilt the new way without any change, but people may want to tweak some transparent textures or some backlights for better results.
Related to colorspace, we also implemented a trick we learnt from Xonotic: storing lightmaps in sRGB space. They’re still baked in linear space and blended in linear space, but stored in sRGB space. This trick biases the storage to allocate more precision to the low lights, allowing smooth shadows. The visual quality is somewhat similar to what would produce a 12-bit storage, while storing in any 8-bit image format…
War on jaggies



We implemented not one, but two anti-aliasing systems! First, thanks to Reaper, there’s our flagship MSAA (multisample anti-aliasing). This works by internally rendering at higher resolution at the boundaries between objects. It has a high performance cost, especially for high-resolution displays, so it is enabled only for the “Ultra” graphics preset. Now the Ultra preset can bring your GPU to its knees like it should.
As a resource-efficient alternative, we offer FXAA (“fast approximate anti-aliasing”). This is an edge detector + blur filter option which also takes care of jaggies, at the cost of some false positives.
An “FXAA” option was long present in the menu, but it didn’t do anything useful until now. Illwieckz repaired FXAA by
configuring the correct interpolation mode when reading off the pixels. He also tweaked it a bit it’s configuration to make it look better with our maps (to limit as much as possible the blurring). Illwieckz also modified it to work on luma to be more efficient and also integrated it properly with the linear pipeline.
Sound system

Reaper made some enhancements to the audio system. Most prominently, it is now possible to attach more than one looping sound to an entity. You can finally hear the buzz of your Painsaw and the purr of your jetpack at the same time!
Also, sounds produced by your own player will be prioritized in case there are too many active sounds to play them all.
Emancipated skeletons
Reaper did it again! Yet another impressive rework being landed in the 0.56 release is a feat of the Reaper.
Reaper moved model skeleton building and blending into the engine. What’s the deal with it? Well, you probably already know, and if you don’t know I’ll tell you, our game code is virtualized. The engine runs natively on the hardware and operating system of the player, while the game code itself is run virtualized and sandboxed in a virtual machine (currentl, NaCl). To communicate with the engine, the game code uses an IPC, an inter-processus communication channel. But the IPC is slow, so the more things we untie from that IPC, the more performant is the game!
That rework to optimize IPC communication or avoid IPC communication has already been done on many other things of the engine: like particles. Now it’s the turn of model skeleton building and blending to be unchained from that IPC.
He also implemented an entity cache. Those improvements adds-up because, as you guess, models are usually depicted using models who happen to have skeletons.
In another topic, Reaper also worked on implementing PushBuffers, an mechanism to improve performance by avoiding a bunch of driver calls and such. So this other improved communication isn’t between game and engine, but between engine and driver.
Speeding-up models on low-end and lesser-known GPUs… with OpenMP on CPU
As always we do testing on a wide range of hardware to make the game as accessible as possible.
Illwieckz integrated OpenMP into the Daemon engine and used it to accelerate CPU-based rendering of skeletal models. We have to use CPU-based (instead of GPU-based) on lower-end GPUs or ones with poor driver support. For the curious, you can check the log:
if you see a message like Missing GPU vertex skinning, models are not hardware-accelerated or
Using GPU vertex skinning with max *N* bones in a single pass, some models may not be hardware accelerated, you may benefit from this innovation.
An example of actual GPUs from the market that benefit from this OpenMP work is the Chinese MTT S80 from Moore Threads. Despite having a raw power comparable to a RX 6700XT in some aspects (so, close to an Xbox Series X or PlayStation 5), and supporting OpenGL 4+, for some reasons it exposes some “max vertex uniforms” limitations similar to some 2.1 GPUs from the early 2000’s, probably a side-effect of its PowerVR-based architecture which is usually found in mobile devices, not in discrete PCIe cards for gaming PCs. Owners of such devices can use the “Ultra” graphics preset but are recommended to enable the “Low“ model quality option so the engine dispatches more models to the GPU while the processing of remaining models dispatched on CPU will enlist many threads to speed-up the work thanks to OpenMP.
Illwieckz also did some rewriting of this fallback model CPU code for it using cheapest but faster variants of some computations to speed it a bit more.
OpenMP may be used in the future to speed up more things benefiting more people, be it at loading time (decompressing multiple images at the same time, maybe?) or at render time (particles may benefit from it for example, but would require some deeper rewrite first). OpenMP is now enabled by default in Linux and Windows release builds, starting with Dæmon 0.56. Those who build the engine themselves have to set the USE_OPENMP CMake option to ON.
Fixed light grid code when deluxe mapping is disabled
In the process of rewriting the light grid code for better interpolation, slipher fixed the issue of excessively bright models when deluxe mapping is disabled. Deluxe mapping is disabled when selecting the “Low” or “Lowest” graphics presets. So models are illuminated more in line with the rest of the level when using those presets.
Low and lowest graphics preset are only meant to be used with very low end and slow devices. If your hardware is weak, try the medium preset first, then try the low one if not enough, and only resign to the lowest one as a last resort. The lowest the preset, the uglier it looks.
At least with this fix the low preset looks a bit better.
Not trusting OpenGL drivers when they brag about texture barriers
We have continued to improve the handling of depth buffer sampling, which is used for soft particles, SSAO, and now fog. Various systems have long suffered from issues with soft particle rendering, in the past because we didn’t obey the OpenGL dictates correctly, and more recently because the drivers are wrong. Some OpenGL drivers shamelessly lie about their degree of support for related functionality, so we have to evaluate GPUs on a case-by-case basis and tweak the behavior to avoid bugs.
The OpenGL hardware and driver detection framework and the workaround management framework, both introduced in recent Dæmon versions, prove themselves very handy in this case.
More and more

Afontain adjusted the Overmind’s eye to make it spookier: it will look its human enemies right in the eye.
Reaper extended the client/server network protocol to support very large entity baselines. This allows layouts with 700+ buildables to be loaded without bringing down the server.
More renderer goodness
Slipher did a great job at reworking the fog code. It is not only more efficient, the fog looks better. First, when entering a fog volume, that fog is then rendered like a global fog, with a single draw call. Then, the fogs now have softer edges, making them look much better.
The exposure feature is now usable even when tone mapping is disabled. The exposure should be preferred over the gamma option. The gamma option was yet another thing that was part of the broken pipeline. Don’t use it, it breaks colors as soon as you change the default value. If you need to increase brightness, increases exposure. If you used the gamma option before, you’ll better reset it and use exposure instead. The exposure option works with both the new linear blend regime and the old one, and now works when tone mapping is enabled or disabled. The only reason to not use exposure is if the default brightness is fine for you.
Speaking of tone mapping. This is a great feature implemented by Reaper and already released in previous versions of the engine. Illwieckz made sure it integrated properly with the linear pipeline, and also tweaked its default configuration to make it work better with our very large corpus of maps. The tone mapper is now looking great whatever the map you use, such map using the old pipeline or the new one, or featuring very different lighting atmosphere…
The tone mapper is a required component of the upcoming adaptive lighting feature, so we needed to make sure it fitted all our usages, which is now done.
Slipher worked on enabling realtime light on vertex-lit surfaces. The shader language used for describing materials allows to configure a surface to blend a texture with the vertex color (usually carrying light color), meaning the result is a surface that is actually lit, while skipping the lighting code entirely. Since those surfaces are semantically lit, Slipher made sure those surfaces also receives dynamic lights. He also fixed dynamic lights on moving BSP entities, such as doors, which could appear in the wrong location.
UI enhancements
Reaper added a column displaying the server’s version number into the in-game server list. So when you download Unvanquished 0.56 two minutes after it was released, you can see which servers are ready with the new update.
As is customary for a new major release, Unvanquished 0.56 is incompatible with the 0.55.x series. The game will display a warning if you try to connect to a server which is known to be incompatible
with your version of the game.
Detailed changelog
Unvanquished – 0.56.1 branch
- Fix the ABI mismatch popup check, Unvanquished 0.56.1 – Illwieckz
Unvanquished – 0.56.0 branch
- EntityCache: add L2 blocks to find non-full blocks quicker – Reaper
CG_PlayerWWSmoothing(): Fixacosf()of a value >1.0f– Reaper- NUKE unused
refEntity_tfields, improve packing – Reaper - Move skeleton building and blending to engine – Reaper
- Implement a render entity cache – Reaper
- Fix human buildable under construction shader – Slipher
- Enable FXAA with the high graphics preset – Illwieckz
- Fix version data for server list – Slipher
- Fix non-2d shader registered before colorspace known warnings – Slipher
- Fix password protection with local servers – Slipher
- ClientBotConnect: remove useless stuff – Slipher
- Better document the localClient field – Slipher
- better detect hosting client in some cases – Slipher
- Remove usage of no-op
SVF_*flags – Slipher - Update cvar name
r_toneMappingExposure->r_exposure– Slipher - Remove no-op
RF_MINLIGHTflag – Slipher - Don’t set
refEntity_t’slightingOrigin– Slipher - NUKE non-blob shadow code – Slipher
- Fix lcannon warning sound – Reaper
SP_sfx_speakeri: UseSVF_BROADCAST– Reaper- Fix looping sounds – Reaper
glconfig→WindowConfig– Reaper- Update
MAX_PARTICLES– Reaper - Fix
cg_drawClocknot using local time (in NaCl) – Reaper - Add a deprecation warning for
realLight– Reaper - Use
RSF_FORCE_LIGHTMAP– Reaper - Add dynamicLightIntensityCompensate – Reaper
- Fix missing and extraneous dynamic light color division – Reaper
- NUKE
trap_R_AddAdditiveLightToScene()– Reaper - ABI update: Use
trap_GetPingsnot playerstate ping – Slipher - Fix chargebar depth – Reaper
- Fix
changemapcommand not found – Kai - Fix dead/powered down barricade is not predicted – Kai
Unvanquished – master branch since 0.55.5
- Add MSAA to ultra preset – Slipher
- NUKE rim lighting option from menu – Slipher
- Disable
r_rimLightingin presets – Slipher - Fix
keynum_tbinds in bind menu – Slipher - Pre-build shader variants for spawning buildables – Slipher
- Fix prediction errors if using
cg_sprintToggle– Slipher - Enable realtime lighting in medium graphics preset – Slipher
- Improve positioning of “Beta x.y.z.” label – Slipher
- RML cleanup: remove
<blocklink>tag – Slipher - Remove CSS directives not used by any element – Slipher
- Drop some unused CSS classes in
menu_ingame.rml– Slipher - Add overmind Y axis eye offset – Afontain
- Use AngleNormalize180 in
CG_Buildable– Afontain - Make overmind look directly into the eyes of its targets – Afontain
- Fix spectator 3rd person view YAW limits – Afontain
- Remove useless AngleNormalize180 – Afontain
- Fix effectless AngleNormalize360 – Afontain
- Use AngleNormalize360 instead of AngleMod – Afontain
Daemon Engine – 0.56.0 branch
- Disable
ARB_texture_barrieron GLSL 1.20 (GL 2.1) devices – Illwieckz - Fix fog on GLSL 1.20 – Illwieckz
BuildSkeleton(): applyboneMod.translation– Reaper- NUKE unused
refEntity_tfields, improve packing – Reaper - Move skeleton building and blending to engine – Reaper
- Implement a render entity cache – Reaper
- Cap
ompMaxThreadsto 4 in MinGW build – Illwieckz - Reduce
r_FXAAEdgeThresholdto0.25– Illwieckz - Make FXAA configurable with cvars – Illwieckz
- Disable FXAA when MSAA is enabled (prefer MSAA) – Illwieckz
- Fix FXAA sampling by using
GL_LINEARon currentRender – Illwieckz - Add
r_showFXAA– Illwieckz - Implement luma-based FXAA – Illwieckz
- Run FXAA after the camera shader (after tone mapping and color conversion) – Illwieckz
- Also set
u_SRGBin lightMapping shader for the material system – Illwieckz - Add sgame IPC to sync data to Daemon-vulkan – Reaper
- Add cgame IPC to sync data to Daemon-vulkan – Reaper
- Adjust dynamic lights in linear blend regime – Slipher
- Make possible to never compile a shader, do it for “proxy” – Illwieckz
- Delete unused
GLShaderManager::LinkProgram()– Illwieckz - Print shader name in link log in
GLShaderManager::BuildShaderProgram()– Illwieckz - Never build grid deluxe without grid lighting – Slipher
- Remove
GLShader::MissesRequiredMacros– Slipher - Only initialize world shaders AFTER all shader storage has been initialized – Ishq
- Reorder and comment
SVF_*flags – Slipher - Remove
SVF_*flags that do nothing – Slipher - Make models brighter with deluxe mapping off – Slipher
- Rewrite light grid direction interpolation – Slipher
- NUKE
LightForPointfunction and trap call – Slipher - Rework the non-delayed texture loading, fix loading legacy diffuse stage – Illwieckz
- Rename
r_toneMappingExposure->r_exposure– Illwieckz - Set
r_toneMappingContrastto1.4– Illwieckz - Do the tone mapping operation before the color conversion – Illwieckz
- Make
SVF_BROADCAST_ONCEhave a uniqueSVF_*value – Reaper - Clean up
RegisterShaderFlags_tABI interface – Slipher - Remove
glDriverType_tenum – Slipher - Remove unused
RF_MINLIGHT– Slipher - Remove unused
REF_xxx_DLIGHTflags – Slipher - Remove unimplemented
refEntity_t::lightingOrigin– Slipher - NUKE vertex overbright code for
genericshader – Slipher - Enable realtime lights for vertex-lit surfaces – Slipher
- Refactor
SetLightDeluxeMode arguments– Slipher - Implement some sound priorities – Reaper
- Allow multiple sounds per entity – Reaper
- Implement
SVF_BROADCAST_ONCE– Reaper - Destroy dead sounds – Reaper
- Fix looping sounds – Reaper
- Update dummygame for
glconfig_t->WindowConfig– Slipher - NUKE
glconfig_t, useWindowConfiginstead – Reaper - NUKE the remnants of
R_GetEntityToken()– Reaper - NUKE
server_t.entityParsePoint– Reaper - NUKE
trap_GetEntityToken– Reaper - Update
MAX_REF_ENTITIES– Reaper - NUKE unused
RSF_LIGHT_ATTENUATION– Reaper - NUKE unused
RDF_SKYBOXPORTAL– Reaper - Fix entity baseline overflow – Reaper
- Check for stage count with
RSF_FORCE_LIGHTMAP– Reaper - Add
RSF_FORCE_LIGHTMAP– Reaper - Add VM syscall for getting local time offset – Slipher
- Add engine + ABI version to server info response – Slipher
- Multiply with
var_Colorin generic shader before theu_AlphaThresholdcheck – Reaper - give all server info to cgame, not just selected fields – Slipher
- Clean up “nettype” from server info for cgame – Slipher ??-?? Fix bad merge with sv_maxClient – Reaper
- NUKE light intensity/scale – Reaper
- Remove unused shader from
trap_R_AddLightToScene()– Reaper - NUKE
trap_R_AddAdditiveLightToScene()– Reaper - NUKE
RE_AddDynamicLightToSceneQ3A(), renameRE_AddDynamicLightToSceneET()toRE_AddDynamicLightToScene()– Reaper - NUKE
r_lightScale– Reaper - NUKE random dynamic light scaling – Reaper
- NUKE unused
RDF_NOSHADOWS,RDF_UNDERWATER, andRDF_DRAWINGSKY– Reaper - NUKE unused
RF_WRAP_FRAMESandRF_FORCENOLOD– Reaper - NUKE unsued
MAX_DLIGHTS– Reaper - Make shared memory player state pointers const – Slipher
- Add
trap_GetPings, remove ping from playerstate – Slipher
Daemon Engine – master branch since 0.55.5
- Disable rim lighting (
r_rimLighting) by default – Slipher r_showLightGrid: access grid values directly – Slipherr_showLightGrid: fix wrong colors displayed – Slipher- Fix wrong default light grid (when BSP lacks one) – Slipher
R_LoadLightGrid: simplify code for skipping 0 points – Slipher- Don’t create
lightGrid2image when deluxe disabled – Slipher - Don’t store alpha channel for lightGrid2 image – Slipher
- Don’t lose precision while linearizing light grid – Slipher
R_LoadLightGrid: comment suspicious-looking things – Slipher- Frustum cull fogs – Slipher
- Cleanup: rename GLSL shader
fogGlobal->fog– Slipher - Use new depth-based fog shaders in material system – Slipher
- Use depth-based fog shader for all fogs – Slipher
- Draw inside of fog with modified global fog shader – Slipher
- Fix failing to generate depth shader with long name – Slipher
- NUKE cvar
r_wolfFog– Slipher - Fix failing to generate depth shader with long name – Slipher
- NUKE cvar
r_wolfFog– Slipher - For fogs use a small gradient by default – Slipher
- Introduce fogGradient shader keyword – Slipher
- Refactor: save
fogparmsonly on shader, not infog_t– Slipher - Remove some unused fog-related bits – Slipher
- Reduce the default bloom strength – Illwieckz
- Recalibrate the default tone mapper preset – Illwieckz
- Fix lighting for BSP model entities – Slipher
- Skip visited check for BSP entity surfaces – Slipher
- Fix missing
u_Exposurewhen high precision rendering is disabled – Illwieckz - Disable
ARB_texture_barrieron Moore Threads hardware – Illwieckz - Report OpenMP support in
/gfxinfo– Illwieckz - Parallelize
Tess_SurfaceMD5()with OpenMP – Illwieckz - Prepare
Tess_SurfaceMD5()for parallelism – Illwieckz - Parallelize
Tess_SurfaceIQM()with OpenMP – Illwieckz - Prepare
Tess_SurfaceIQM()for parallelism – Illwieckz - Add OpenMP support – Illwieckz
- Rename
u_TonemapExposure→u_Exposure– Slipher - Apply exposure even when tonemapping is off – Slipher
- Add
ifStaticshader keyword – Slipher - Add
linearBlending/naiveBlendingtoexpression_t– Slipher - Warn when loading non-2D shaders before mapa – Slipher
- Add the
linearColorMap,linearSpecularMapandlinearRgbGenkeywords and raw variants – Illwieckz - Delayed animation texture loading – Illwieckz
- Delayed stage texture loading – Illwieckz
- Make cvar defaults match Unvanquished “high” gfx preset – Slipher
- NUKE unused
GLUniformSampler::SetValue()– Slipher GLUniform: addbufferSize– Reaper- NUKE unused
GLUniform.GetSize()– Reaper - Only update PushBuffer if any uniform has actually changed – Reaper
- Fix MSAA with depth-fade and global fog – Reaper
- Add a GL version check for MSAA – Reaper
- Clean-up
Render_generic3D()MSAA resolve – Reaper - MSAA: clean-up FBO bindings – Reaper
- Fix fog and transparent surfaces with MSAA – Reaper
- MSAA clean-up and fixes – Reaper
R_UploadImage(): early return for MSAA images – Reaper- Implement MSAA – Reaper
- PushBuffer fixes – Reaper
- Always enable
glConfig.usingReadonlyDepthon AMD + bindless textures – Reaper - Implement the rest of PushBuffer – Reaper
- Add PushBuffer – Reaper
- Don’t use real uniforms in uniform packing test – Slipher
- Fix console border drawing with negative
con_margin– Slipher - Fix a crash when console width is less than 1 char – Slipher
- Migrate remaining in-game console (
con_*) cvars – Slipher - Migrate many in-game console (
con_*) cvars – Slipher - Fix cvar changes sometimes not writing autogen – Slipher
- Cleanup: InternalSetValue flags argument always 0 – Slipher
- FileSystem: unify
open()wording and deduplicate code – Illwieckz - Simplify the Saigo arm optimization disablement fix – Illwieckz
- Disable PIC with NaCl – Illwieckz
- VMMain: explicitely include
unistdon NaCl to please Saigo – Illwieckz - Fix screenshots with read-only depth buffer – Slipher
- Fix
tr.numFBOs counter– Slipher - Don’t allow loading console font from pak file – Slipher
- NUKE legacy console font (‘bigchars’) – Slipher
- Embed Unifont OTF for the default console font – Slipher
- Properly detect Linux with glibc to detect what’s not – Illwieckz
- Also make generated source depend on generators to regenerate the target – Illwieckz
- Do not copy the embedded files in the map – Illwieckz
- Make possible to chose between
TEXTandBINARYformats when embedding files – Illwieckz - Make the embedded file generator reusable – Illwieckz
- Fix
/listMaterialSystemStagesvariant descriptions – Slipher - NUKE
alphaAddOnebit in color modulate – Slipher - Fix broken shader that prevents game start – Afontain
- Use
WARN_UNUSED_RESULTinq_math.cpp– Afontain - Deprecate AngleMod – Afontain
r_showVertexColors: don’t black out generic shader – Slipher- Allow building NaCl dummy gamelogic – Slipher
- Migrate mouse acceleration cvars
cl_mouseAccel*– Slipher - Fix mouse accel bug: sensitivity applied twice – Slipher
- Implement the builtin
sound/null.wavfile – Illwieckz - Remove
THIS_IS_NOT_A_DEBUG_BUILDhack (not needed for PCH anymore) – Slipher - Use CMake’s
target_precompiled_headerfor PCH – Slipher - Bump CMake minimum version to 3.18.4 – Slipher
- Migrate some input-related
cl_*cvars – Slipher - NUKE debug cvar
cl_showMouseRate– Slipher - Migrate cvar
sensitivity– Slipher - Migrate
m_*(mouse) cvars to new style – Slipher - Fix WAV file loading – Illwieckz
- Migrate
j_*cvars to new style – Slipher - Drop
__MACOS__ifdef inCL_JoystickMove– Slipher - Migrate ROM cvar
in_gameControllerAvailable– Slipher - Rename
in_joystickUseAnalogtoj_useAnalog– Slipher - Move font stuff out of
q_shared.h– Slipher - NUKE font handle table – Slipher
- NUKE
.datpre-rasterized font file format – Slipher - Remove unused font things – Slipher
RE_RegisterFont: fix possibly uninitialized pointer – Slipher- Exclude OpenGL tests from Vulkan build – Slipher
- Fix
file:linelogging in gamelogic – Slipher - Access log suppression cvars less thread-unsafely – Slipher
- Fix unused
Log::(Warn|Notice|Verbose|Debug)decls – Slipher - Simplify
Logger::Prefix(function that adds prefix) – Slipher - Migrate
in_*cvars to new style – Slipher - Migrate cvar
in_joystickNoto new style – Slipher - Add game controller logger (
logs.level.client.controller) – Slipher - Call
IN_ShutdownJoystickin non-pedantic shutdown – Slipher - Remove “StackTrace unavailable” message – Slipher
- Start of daemon-vulkan infrastructure – Reaper
- Faster other
R_CalcTangents()withVectorNormalizeFast()– Illwieckz - Faster
Tess_SurfacePolychain()withVectorNormalizeFast()inR_CalcTangents()– Illwieckz - Faster
Tess_SurfacePolychain()withR_TBNtoQtangentsFast()– Illwieckz - Faster
Tess_SurfaceIQM()andTess_SurfaceMD5()withR_TBNtoQtangentsFast()– Illwieckz - Introduce
R_TBNtoQtangentsFast()andfloatToSnorm16_fast()– Illwieckz

We’ve realized there is an issue with the server version compatibility check. It always displays a warning when trying to join a server, even if the version is compatible. But don’t worry: you can just click through the warning. The server is compatible as long as the version is not displayed in red in the in-game server list.
The server list patch is now published as 0.56.1. As always, users of the Unvanquished launcher will automatically receive it. No action is required from server owners, since the patch only affects the main menu.