UZDoom version history/5.x
This page tracks the 5.x release cycle of UZDoom by listing the main features of each version.
| 2026 |
|---|
2026
5.0 (xx xx 2026)
After an over year-long development cycle and a truckload of internal reworks, UZDoom 5.0 has finally arrived! Starring bone manipulations for IQM models, significantly improved controller support (including haptic feedback!), the overhauled multiplayer, ZScript debug support, and much more, we knew this version would need a full upgrade. We appreciate everyone being patient since we know it took a while, but we promise it was worth the wait. With the updater being added, we can now make smaller releases more often so long periods of development like this should be an issue of the past. Our focus going forward will be on making releases as big new features are added.
General
- Multiple security fixes. This update is being deemed as critical. If you’re using a version older than 5.0, it’s highly recommended you update to the latest.
- Improved localization support. Added support for Босански, Català, Hrvatski, Bahasa, Latina, Svenska, Українська, and 简体中文.
- Removed Discord RPC support. This allowed Discord to display information about the current UZDoom instance but was unfortunately causing crashes on launch. Since this library has been deprecated for over half a decade, its been removed until a new library can be found.
- Controller support has been improved significantly. Missing buttons e.g. paddles can now be assigned properly and analog stick curves have been tweaked to feel much more natural. Binds for these have been cleared as a result in order to update all configurations to the new handling.
- Added haptic feedback for controllers.
- When auto-starting a game via e.g.
-skill #, UZDoom will now use the first map in the first episode found. This should make starting games with unorthodox map setups more streamlined. - When auto-starting a game, the default skill set in MAPINFO will now be the skill it defaults to.
- Alt tabbing while in fullscreen will now respect the relevant video cvars.
- Improved the crosshair graphics.
- Reworked double tap binds so they're now either/or instead of executing both.
- Allowed quit sounds to be longer (up to 5 seconds).
- Added the
-episode #command-line argument for more easily starting from episodes rather than needing to know the map name. - Added the
-optfilecommand-line argument. Files specified this way will ignore missing file errors by default. - Added the
-showlaunchercommand-line argument. Forces the launcher to always show up. - Added the
-helpcommand-line argument (aliases:-h,/?). This will display a list of valid command-line arguments for UZDoom alongside a description of what they do.-help-allcan be used to get fuller descriptions for each. - Added
RecursivePath=to the config for IWAD and file look up that allows all subfolders in the given directory to be searched as well. This won’t work for subfolders that act as files. - Added support for Boom's multiple help screens.
- Added support for the multiplayer lobby and error windows on Linux.
- Improvements to serializing. This should make both saving and loading a little faster.
- Fixed the auto language option not detecting the system language.
- Fixed multiple splashes spawning when falling in liquids in certain cases.
- Fixed explosions being able to damage outside of their radius in rare cases.
- Fixed locks not properly checking the player's inventory if a voodoo doll triggered the check.
- Fixed the
SMF_PRECISEflag inA_SeekerMissilenot tracking crouching players properly. - Fixed
A_LookExnot respecting the+LOOKALLAROUNDflag in all cases. - Fixed looping sound sequences not playing back correctly.
- Fixed the death cam not working with players that called A_SkullPop (e.g. when the player is gibbed in Heretic).
- Fixed a VM crash in Heretic when a player who fired a powered up Hellstaff leaves the game while it's active.
- Fixed a crash when opening the scoreboard in niche scenarios.
- Fixed a potential crash when saving.
Launcher
- Added a new updater! This will now automatically check for updates periodically when launched with controls for it in the Options tab. Options include being prompted to install the latest update if one is found, merely notifying that a new update was found, or disabling entirely. Updates can be checked for manually in the About tab.
- Added both light and dark mode themes alongside auto theme detection.
- Added a Release Notes tab that contains the patch notes.
- Added an About tab that contains a list of all contributors to the project. This will also allow the Release Notes tab to be reopened if needed.
- Added an option to remember additional parameters between sessions.
- Added an option to disable loading support WADs e.g. the Legacy of Rust assets if you have Doom + Doom II installed.
- Added an option for whether or not UZDoom should throw an error if files specified by the
-filecommand-line argument weren't found. - Added options for dynamic lights and v-sync.
- Added a multiplayer tab for hosting and joining net games.
- Added support for dragging and dropping files into the launcher window while open.
- Holding shift will now also stop mods from auto-launching games. Now works on Linux.
- The window size will now be saved between sessions.
Accessibility
- Added a new accessibility menu. This will be the new home for all of UZDoom's accessibility features going forward, and will have other related accessibility options (like the HUD flashing) ported over to it at a later time.
- Added Extra Light option. This modifies the light curve of all sectors, allowing brightness to be controlled via the actual game lighting.
- Added Light Radius option. This controls the range of the radial light that emanates from the player.
- Added Double-click Threshold option. Allows controlling the duration of time needed for a double tap bind to register.
Menu
- Various improvements to the option menu handling.
- Increased maximum shadowmap quality.
- Increased maximum auto-aim range to 70 degrees vertically. This is still capped to 35 degrees if freelook is disabled.
- Sliders can now set values directly by pressing enter on them.
- Made the default dimming less harsh.
- Reworked the brightness adjustment options. Gamma now has various sliders for adjusting general and black compensation levels. An image is provided to help best fit to your monitor's gamma. Brightness itself has been reworked to give better results.
- Reworked the ZDoom transparency options to have improved heuristics when determining preferences. A new Auto mode has been included that'll turn transparency off only on vanilla entities while enabling it for modded ones.
- Added tooltips to menus. In the future these will give better explanations of what each option does with hover tooltips being used to further explain the specifics of each value when necessary.
- Added a bind for deleting saves with controllers.
- Added the ability to reset options to their defaults by pressing backspace.
- Added a sector fill color option for the automap, allowing sectors to be filled in with a generic color to differentiate them from the background.
- Added an auto gameplay compatibility option. This enables certain non-intrusive compatibility options based on game and/or map type to better fit the author's original intent.
- Added a compatibility option to emulate Mikoportals for vanilla maps that rely on them.
- Added a compatibility option to transfer sector secrets in Boom maps.
- Exposed controls for Heretic’s, Hexen’s, and Strife’s items.
- Fixed a bug where using a mouse button to close a menu would cause Windows to lose track of which window is focused.
- Fixed certain fonts rendering incorrectly compared to the vanilla Doom graphics.
- Fixed the
+DONTTRANSLATEflag being ignored in the player menu.
Console
- The
turbocvar is now considered a cheat. - Added
changeepisodecommand. Allows changing episodes via episode number instead of needing to know its starting map. - Added
profilecsthinkerscommand. Allows profiling client-side Thinkers and dynamic lights. Dynamic lights will no longer show up underprofilethinkers. - Added
acsandacsncommands as alternatives topukeandpukenamerespectively. - Added
cl_debugpredictioncvar for testing latency within singleplayer games. The value is the number of ticks of lag to emulate. - Added
i_searchdistributorscvar that, when set to false, disables lookup of IWADs from Steam, GOG, etc. - Added an option to stack duplicate messages. This can be changed via the
con_stackidentcvar. - Fixed a crash with the
setinvcommand. - Fixed
stat velocitydisplaying inaccurate values and made it multiplayer friendly. - Fixed the
nointerscrollabortcvar not being respected.
Rendering
- Restructured dynamic light linking. This should help moving dynamic lights from e.g. projectiles perform better in maps with complex level geometry.
- Spotlights attached to cameras will now update their angles in real time to match the camera's view direction.
- Rotating skies will now pause with the game.
- Added
InputTime,InputTimeGame, andInputTimeDeltauniforms for post-processing shaders. These store the total engine time, the current level's game time, and the frame delta respectively in seconds. - Added
LastInputTexturefor post-processing shaders that stores the image from the previous frame. - Fixed mirrored surfaces not rendering correctly through portals.
- Fixed canvas textures being unable to support translucency.
Maps
- Tweaked desaturation model to make colors look better at lower sector light levels.
- Added ability to set alpha on sides.
- Added a flag to sides to allow blocking rendering entirely, acting like an artificial one-sided line.
- Miscellaneous fixes for level compatibility across various WADs.
- Minor fixes for MBF21.
- Minor fixes for id24.
- Fixed UMAPINFO using the wrong finale music in intermissions.
- Fixed the “no infighting” flag not working.
- Fixed linked crushers not respecting the parent crusher's crush mode.
Lumps
MENUDEF
- Added
DoubleTapControlandDoubleControloption menu settings.DoubleTapControlbindings allow for double tapping a key to execute an action whileDoubleControlbindings allow for both a single tap and double tap action to be bound to a key at the same time. - Added
Tooltipkeyword. This can be used with both list and option menus and binds a description to the widget defined before it. If a widget has a tooltip, it will be displayed at the bottom of the menu when selected. In addition, Option Values now accept a third optional parameter, a description, that is displayed next to the option when it's hovered over for a second. This allows for explanations of complex options that can't be handled by the basic tooltip. - Added a new gray check property to option menu widgets that allows determining how they should work. This includes
Gray(current behavior),Hide(completely hide the element),GrayInv(gray if the element isn't the given gray check value), andHideInv(hide if the element isn't the given gray check value). - More option widgets now have access to gray checks.
MODELDEF
- Added
ViewModelFOV. When a model is being used as a PSprite, this will allow for directly setting its field of view. Positive values are fixed FOVs while negative values act as a scalar from the default 90 FOV.
ANIMDEFS
- Canvas textures now support x and y offsets via the
offsetkeyword. If used with no values, uses the texture's offsets.
GLDEFS
- Added an option for stricter warnings on invalid materials via the
gl_strict_gldefs_errorscvar.
MAPINFO
- Added
Skymistto map blocks. This allows setting a transparent overlay texture on skies that acts as a layer of fog. Supports animated textures and skyboxes. - Added
ThickFogDistanceandThickFogMultiplierto map blocks for additive fog.ThickFogDistancecontrols what range it starts andThickFogMultipliercontrols the density of the fog. - Added
UsePauseStringto the gameinfo block. Allows displaying the PAUSED text as a string instead of a graphic. - Setting the status screen classes to
Nonewill now disable them entirely.
LANGUAGE
- IETF BCP 47 language tags are now used instead of custom language codes
- Error messages will now print the full file name to make it easier to differentiate which one is causing issues.
- Added a warning if a missing translation was attempted to be used.
SNDINFO
- Sounds with missing lumps will now give a warning when in
developer2 mode or greater.
ZScript
- DAP debug servers will now work with ZScript. This can be used with e.g. VisualStudio Code in order to properly debug ZScript via stepping, pausing, etc. You can find UZDoom's own VSCode extension on GitHub at https://github.com/UZDoom/UZDoom-VSCode.
- Added Behaviors. These pseudo-interfaces are meant to replace Inventory tokens, have a much simpler API, and can only have one of a given type at a time making it easier to manage. BehaviorIterators can be used to iterate across either all Behaviors on a given Actor or all Behaviors of a given type currently in the game. All Behaviors are guaranteed to have an Actor that owns them, allowing them to be passed around as a handle if behavior-based typing is needed.
- Added client-side Thinkers. These are ran after the client has backed up any needed values, making them safer for multiplayer. They can be spawned via LevelLocals’
SpawnClientSideThinkerfunction or by marking Actors with+CLIENTSIDE. These have heavy restrictions on what they can interact with as other clients in net games will not know about them, so caution should be used when modifying the world directly from them. Objects can be checked if they're client-side via theIsClientSidefunction. Note: These have their own Actor, Behavior, and Thinker iterators. A parameter to get client-side Thinkers has been provided for these when creating them. They will not appear in the blockmap or sector thing lists. - Reworked the level traveling system. All Actors can now be set to travel between levels similar to the player via their
AddToTravellingListfunction. Note that this can only be done once traveling has been initiated. TheTravellingandPostTravelledvirtual functions have been moved to all Thinkers as a result. - Removed the ability to manually assign Actors to the
STAT_STATICstatnum and all Thinkers to theSTAT_TRAVELLINGstatnum. This was always unintended behavior that resulted in bugs. - Exposed the
Elevator,Door,Platform, andCeilingmap thinkers. Allowing for reading of their states. constfunctions will now properly makeselfconstant. To get the previous behavior back, useunsafe(const).- Added
unsafe(clearscope)scope for fields. This can be used to make fields that seamlessly interact betweenplayanduiscopes. Note: This has a high chance to desync multiplayer, so use with caution. - Added the
norollbackkeyword forunsafe(clearscope)fields. This will prevent them from being backed up while predicting, keeping their values untouched at all times.uifields are automatically not rolled back. - Classes and structs can now be marked as deprecated.
- The HUD will now tick again while the world is paused.
- Added
MinRespawnTicsandRespawnDiceproperties to Actors to control their respawn logic when enabled. - Added
+INTERPOLATESCALEand+INTERPOLATEALPHAflags to Actors. - Added the
+NODYNAMICLIGHTINGflag to Actors to allow disabling dynamic lighting on them. - Re-added the
+WEAPON.BFGand+WEAPON.EXPLOSIVEflags. All Doom, Strife, and Raven weapons have been flagged appropriately. - Actors will now track how they were spawned in their
SpawnFlagsfield.MTF_MAPTHINGis for Actors placed in the map andMTF_CONSOLETHINGis for Actors spawned via the console. All other Actors are considered manual spawns. - PlayerPawn's
FilterCoopRespawnInventoryfunction is now virtual and can be overridden. - Added
nailrangeparameter to A_Explode to control the range of nails shot from them. - Added
fadeoutstepparameter to A_SpawnParticleEx, allowing particles to first fade in when spawned and then back out. This requires eitherSPF_FADE_IN_OUTorSPF_FADE_IN_HOLD_OUTto be set. - Added
gibtypeandzOfsparameters to A_TossGib. Now also returns the Actor that was spawned. - Added
flagsandangleparameters to DoSpecialDamage and TakeSpecialDamage. - Added
angleparameter toModifyDamage,AbsorbDamage, andGetModifiedDamage. - Added the
PRINT_NOCONSOLEflag to PrintfEx. - Added the
SPF_NODYNAMICLIGHTINGflag to particles and Visual Thinkers to disable dynamic lighting on them. - Added
WorldPausedfunction to LevelLocals for checking if the world is currently considered paused (menu open, console down, etc.). - Added
ChangeSkyMistfunction to LevelLocals for changing the skymist texture. - Added
SetSkyFogandSetThickFogfunctions to LevelLocals for controlling fog levels. - Added
SpawnThinkerandSpawnClientSideThinkerfunctions to LevelLocals, allowing Thinkers to be created with a default stat num. - Added
SpawnClientSideVisualThinkerfunction to LevelLocals for spawning client-side Visual Thinkers. - Added
RemoveUUIDSaveSlotsfunction to SavegameManager. This allows all saves related to the current game session to be deleted at once. - Added
GetNextPlayerandGetNextPlayerNumberstatic functions to PlayerInfo. Allows iterating through players more easily. - Added
SetFullbrightModefunction to PlayerInfo. Allows setting the type of fullbright mode (e.g. from the Infrared) manually. Can be eitherFBMODE_DEFAULT(choose between fullbright or night vision based on player preference),FBMODE_FULLBRIGHT,FBMODE_NIGHTVISION, orFBMODE_TORCH(emulates Heretic's Torch). - Added
GetDeltaTimeandGetPhysicsTimeStepfunctions.currentinGetDeltaTimecan be used to get exact measurements. Both return time in seconds. - Added
GetStatNumfunction to Thinkers. - Added
GetSelfObituaryvirtual function for overriding self inflicted death obituaries. - Added
OnRevivevirtual function for performing actions on Actors when they’re guaranteed to have been revived. - Added
DepleteByvirtual function for Inventory items. This is called when attempting to remove an amount of an item from the inventory. - Added
OnSelectandOnDeselectvirtual functions for Weapons when they’re selected and deselected respectively. - Added the UFO operator (
<=>). - Exported
CloseDialogfor StrifeDialogReplys. - Exported EpisodeInfo and SkillInfo structs. This will make it possible to create custom selection menus for these.
- Exported
IsIntandIsDoublefunctions for strings. - Exported the HUD’s
Drawvirtual function in its entirety, making full overrides possible. - Exported the scoreboard drawing logic to allow creating custom ones.
- Exported
ReactToDamagevirtual for overriding pain logic in Actors. Returns true or false based on whether or not the Actor entered a pain state. - Fixed
MTF_NOINFIGHTINGdoing nothing, it now turns on the+NOINFIGHTINGflag on affected actors. - Fixed an error that would occur when chain assigning deprecated Actor flags.
- Fixed a crash that could occur in
CheckSight. - Fixed an instance where canvas textures couldn't be fetched if being used as a sprite replacement.
- Fixed
static constarrays not respecting theinternalmodifier. - Fixed
Pre/PostMorphvirtual functions being called twice for monsters. - Fixed
LookForEnemiesExfunction not detecting non-players correctly. - Fixed traveling Thinkers not getting restored back to their previous stat num.
IQM Bone Manipulation
With 5.0 comes the ability to manipulate bones directly for IQM models. This has been a long requested feature and allows for things like spawning effects at specific positions, rotating an actor's head to look at its target, attaching one actor to another, etc. While blend-tree-based animation blending would require a more in-depth solution to handle properly, some functionality has been exposed that allows custom blends to be created programmatically. The Named variants of these functions allow a name to be used instead of a bone index.
Bone Setters
Set(Named)BoneRotatation(Angles)Set(Named)BoneTranslationSet(Named)BoneScalingClear(Named)BoneRotation/Translation/ScalingClearBoneOffsets
Default Bone Getters
Get(Named)BoneOffsetGetRootBonesGetBoneIndex/NameGetBoneCountGet(Named)BoneParentGet(Named)BoneChildrenGet(Named)BoneBaseTRSGet(Named)BoneBasePositionGet(Named)BoneBaseRotationGet(Named)BoneFramePoseGetAnimStartFrameGetAnimEndFrameGetAnimFramerate
Bone Getters
These require the IQM_GET_BONE_INFO model flag to be set on the Actor via the SetModelFlag function's second argument due to how expensive bones can be to passively update while animating. The IQM_GET_BONE_INFO_RECALC flag can be used if more precision is needed as this will instead update any time the bones change at the cost of more overhead on setters.
Get(Named)BoneTRSGet(Named)BoneEulerAnglesGet(Named)BonePositionGet(Named)BoneMatrixRawTransformBy(Named)BoneGetObjectToWorldMatrixRaw
Animation Blending
AnimateBones(this is a new UI-scoped virtual function)SetBones(UI)SetBonesRange(UI)SetBonesMask(UI)OverwriteBonesOverwriteBonesRangeOverwriteBonesMaskSetAnimationLayerAnimation(UI)SetAnimationLayerFrameRate(UI)FindAnimationFrameAtFindAnimationFrame(UI)CalculateAnimationFrameCalculateAnimation(UI)BlendAnimationFramesOffsetAnimationFrameForceRecalculateBones
Multiplayer
Whether you're partaking in jolly cooperation or duking it out in deathmatch, multiplayer has always been a fundamental part of Doom's experience. Unfortunately the mainline ZDoom ports were never that good at it, and it's long been neglected in favor of ports designed for online play. While this was an acceptable solution back then, the lack of a good multiplayer experience only hurts more and more as UZDoom continues to grow its collection of exclusive mods and even games. While multiplayer will continue to rely on deterministic gameplay for the foreseeable future, 5.0 comes with some massive improvements to its networking stability. Packet-Server, a once forgotten networking mode, has been fixed up and is now the default. This works similar to client/server where everyone talks to the host directly, removing the peer-to-peer nature and getting rid of those nasty connection issues once and for all. There's still a lot to improve (in-game joining, weapon prediction, the list goes on), but this is a huge stepping stone towards adding these, and you can expect to see more features in the future.
- Increased the max player count to 64.
- Overhauled the net game lobby. Everyone will now be able to see who has joined and hosts will be able to better manage guests. Hosts can now preemptively start the game instead of needing to wait for the lobby to fill fully, allowing for arbitrary max player counts. Note: Bans are IP-based and only temporary.
- Networked the host’s
-loadgameargument. This will still require everyone to have the save file with its given name, but should make reopening a playthrough easier since now only the host needs to specify it. Guests can still manually specify-loadgameto override this should they need a different file name. - Players can now only connect if they’re using the same engine and file versions. This will be improved in the future to allow files specified via
-optfileto be ignored. - Significant improvements to connect rejection messages.
- Auto loaded files and support WADs are now disabled when playing online. These must always be specified manually to avoid accidental desyncs.
- Overhauled the scoreboard to be significantly more readable.
- Hosts can now control who can pause the game including disabling it entirely.
- Hosts can now control who’s able to initiate conversations with NPCs.
- Passing -1 as the position in the
changemapconsole command will now pistol start the following map (changeepisodeautomatically pistol starts). - More items have been marked with
+WEAPONSPAWNto remove things like added ammo when playing with multiplayer weapons disabled. - Improved the last valid position logic when respawning in place is enabled.
- Reworked save file management for net games. These will now have their own subfolder,
NetGame, in order to prevent accidentally overriding singleplayer saves. Files saved also use their given name instead of thesave##format to make them easier to load. Only hosts can save by default now (can be changed via thenet_limitsavescvar). - Reworked the connection stabilizer. When experiencing packet loss, the game will now attempt to smoothen out the gameplay at the cost of felt latency. This can be disabled if stuttering is preferred.
- Renamed settings controllers console commands to
addsettingscontrollers,removesettingscontrollers,removeallsettingscontrollers, andlistsettingscontrollers.addsettingscontrollersandremovesettingscontrollerscan now take multiple player numbers as arguments. As a reminder, settings controllers are also capable of setting certain server options like gameplay variables. - Re-added intermission readying and unreadying. Alternative types of readying systems have been added including vote-based, host only, or anyone. If voting, a timer has been added when enough players are ready to force continue the game.
- Added a cool down for repeatable actions e.g. opening doors.
- Added new options for the chat including what messages to allow and disabling of certain properties e.g. the chat sound.
- Added
mute,muteall,unmute,unmuteall, andlistmutedconsole commands. Messages from muted players will be ignored.muteandunmutecan take multiple player numbers as arguments. - Added the
-coopcommand-line argument for more easily setting up co-op friendly game sessions. - Added the
-passwordcommand-line argument to let hosts require a password to enter the lobby. Guests must enter this same password when connecting. - Exposed controls for spy cam previous and clearing the spy cam.
- Fixed the inventory bar closing faster than intended under high latencies.
- Fixed certain things not predicting correctly during packet loss. This should help alleviate issues like interpolation not resetting and the camera not bobbing correctly during poor net conditions.
- Fixed an issue with player data assignment when loading a save.
- Fixed
+playerclassnot being respected for new players joining an existing save. - Fixed various potential crashes with the prediction.
- Fixed the net game lobby having a black background taking up the entire screen behind it.
- Fixed various potential desyncs related to items in the player's inventory.
Known Issues
- Players disconnecting in net games can cause desyncs under poor net conditions.
- Players crashing in net games can cause the game to softlock or VM abort.
- Controllers continue to get haptic feedback when using mouse and keyboard.
- The initial loading screen now takes longer to appear. This is purely visual and does not impact how long the engine takes to actually start.
- The ZScript debugger is currently untested on Linux.