Skip to content

Latest commit

 

History

History
200 lines (194 loc) · 53.3 KB

File metadata and controls

200 lines (194 loc) · 53.3 KB

OpenQ4 Release Completion List

Use this file as the source list for release changelog entries.

Process:

  1. Add completed work under "Ready For Changelog".
  2. When cutting a release with curated notes, save them in docs-dev/releases/vX.Y.Z.md; the manual release workflow will use that tracked file instead of the auto-generated history summary.
  3. If no tracked release file exists, the workflow falls back to the generated release notes from commit history.
  4. Move shipped items into a historical release section here (optional), and keep remaining work in "Carry Forward".

Ready For Changelog

  • Shadow-map quality and pacing controls advanced: static projected lights can now reuse resident shadow maps with hysteresis instead of rerendering every view, update budgets account for cached reuse separately from fresh work, optional stable Poisson and projected PCSS-lite filters improve soft-shadow tuning, the experimental point-light cubemap path remains available behind r_shadowMapPointLights 1, and translucent shadow moments gained separate softness and light-bleed controls.
  • Shadow-map diagnostics and stability improved: projected and authored parallel lights now report richer caster/timing/atlas metrics with semantic light class separated from backing resource shape, optional GL timer-query diagnostics, rejected-caster reason breakdowns, off-screen shadow-map casters submitted independently from visible receiver scissors, projected CSM bias reports per-cascade near/far ranges, receiver bias uses texel-aware terms with scalar bias as a compatibility floor, hashed alpha uses stable world-space seeds, new debug/tuning cvars expose compare sampling, filter tap budgets, update budgeting, and a bias heatmap, and multiplayer maps such as mp/q4dm1 keep their authored point lighting/shadows by using the legacy stencil path for point lights unless the experimental point-shadow-map path is explicitly enabled.
  • Filter-style decal mips now fold coverage alpha into the neutral multiply color per generated level, so stock terrain stains such as game/airdefense1 no longer reveal their decal bounds when the flashlight crosses them.
  • Retail BSE trail-material parity is restored for shared bullet-impact effects: particle templates now retain the authored/default trail-material name, motion trails resolve that material at finish time instead of relying on an early static pointer, and the stock machinegun/shotgun impact spark trails once again use Quake 4's gfx/effects/particles_shapes/motionblur trail instead of falling back to the engine default texture.
  • Ragdoll startup now follows Quake 4's retail articulated-figure path again: stock corpses no longer pick up OpenQ4-only AF handoff velocity/depenetration heuristics or extra per-body angular-velocity injection during pose transfer, and the AF contact solver is back on retail's tighter contact budget and per-pair planar-contact cap for SP/MP ragdolls.
  • Animated MD5 reference bounds now use exact posed mesh extents when available, eliminating the fixed-screen-square scissor clipping that could chop up player heads/bodies and attached weapons in stock scenes such as the normal game/airdefense2 launch path.
  • VS Code launch-task runtime parity is fixed on Windows: the client and dedicated entry path now preserves native Windows argv quoting, startup +set handling now preserves the full multi-word value tail for debugger/task launches that fail to quote space-containing arguments cleanly, and projected shadow-map defaults now carry enough receiver bias to stop stock flashlight scenes such as game/airdefense2 from collapsing into near-black self-shadowing.
  • Decl reload progress now uses a shared retail-style tool print path: Common.* centralizes tool-routed print behavior, reloadDecls progress lines now use that helper instead of printing straight to the runtime console, and the decl browser can surface reload progress in its status bar while normal runtime sessions still fall back to the usual console/log output.
  • Decl late-load warning suppression now uses one shared retail-like any-tool helper: Common.* centralizes the "is any tool active?" check alongside the existing masked tool helpers, and decl late-load warnings now read through that path instead of open-coding focus and editor-bit state inside the decl manager.
  • Decl tool-state checks now share one retail-style helper: masked tool-flag queries live in Common.*, entityDef media caching uses that shared helper instead of a raw editor-bit test, and decl-validation state checks now read through the same path so tool-sensitive decl behavior stays centralized.
  • Articulated-figure fastEval text now matches retail style: the parser still accepts explicit boolean forms for tools, bare fastEval behaves like retail anywhere in the settings block, rebuilt AF text only emits fastEval when true, and default AF definitions stop writing fastEval 0.
  • Packed .decls writer policy is now explicit: OpenQ4 keeps its extended game-section export coverage by default, exact-retail game-type coverage is selectable through com_singleDeclFileWriteMode or writeDeclFile retail, and export logs now report which policy produced the file.
  • Effect decl allocation is now a hard integrated-BSE invariant: startup probes the effect allocator before registration, allocator failures fatal instead of producing plain idDecl stubs, and dedicated servers keep the disabled BSE runtime while still using the real BSE effect-decl parser.
  • Playback decl finalization now fires the retail-style playback-finished tool bridge after resampling recorded paths, giving editor/tool workflows a completion signal while remaining a no-op in normal runtime builds.
  • Articulated figure decl content masks now preserve Quake 4's vehicleclip, flyclip, and itemclip collision bits when parsing or resaving AF files, restoring retail collision-mask round-tripping for stock and SDK-derived articulated figures.
  • Light-grid baking now writes versioned v5 metadata with a deterministic bake-settings/layout hash, records probe and atlas layout stats, prints per-phase timing/counter summaries including async readback stalls, and rebuilds stale baked outputs automatically when the map layout or bake-affecting settings change.
  • Light-grid interpolation is now visibility-aware: bakes emit companion area*_lightgrid_vis.tga atlases with directional distance moments, and runtime sampling uses those moments with a self-shadow bias to reduce wall/corner light leaks.
  • Light-grid probe placement now detects solid/near-solid positions, relocates probes within a bounded search when possible, records richer validity states and relocated origins in v7 metadata, emits compact area*_lightgrid_pos.tga probe-position atlases for runtime interpolation, and reports relocated/near-solid probe counts in bake diagnostics.
  • First-person weapon/viewmodel surfaces now receive baked light-grid indirect diffuse through a dedicated weapon pass that samples the active view area's probes while keeping depth-hacked weapon geometry out of the main world receiver pass.
  • Light-grid area transitions now blend across visible, unblocked portal neighbors near doorway/window boundaries, using r_lightGridPortalBlend to smooth indirect-light seams without changing baked asset formats.
  • Light-grid atlas residency now keeps visible areas and unblocked portal neighbors hot for an age-based window controlled by r_lightGridResidencyFrames, reducing reload churn and traversal hitches when moving through connected areas.
  • Light-grid indirect rendering now uses a material-compiled representative diffuse stage instead of redrawing every diffuse stage, reducing extra geometry submissions for multi-diffuse materials while retaining a fallback when the preferred stage is conditionally disabled.
  • Startup asset validation now ignores retail Quake 4 game-binary PK4 archives (game000.pk4 through game300.pk4, plus gamex*.pk4 variants), so OpenQ4 only requires and verifies the stock media PK4s it actually uses.
  • Retail decl loading parity improved: Quake 4 decl folders now honor retail recursion/unique-file behavior, no-cache decl lookups reach entityDef inheritance/media caching, legacy Doom 3 PDA/email/video/audio console commands are no longer exposed as supported decls, and playback/table/lip-sync/material-type decl parsing plus playback runtime sampling/record hooks now handle more shipped Raven asset data safely.
  • Packed decl-manager parity advanced: the retail single-decl-file API is enabled again across engine/game headers, packed .decls sections can be read and written through controlled cvars/commands, stored decl indices are preserved during load, validation/allocation/tool hooks are available, packed stub decls expand lazily from their original source text, PDA/email/video/audio decl families are included in the framework packed section, and the startup/session/network asset-log wiring now selects and refreshes per-map packed decl files when the retail cvars are enabled.
  • Packed decl asset-log wiring now follows the retail assetlogs/<map> naming contract, including entity-filter suffixes, while the decl manager preserves the real maps/... path when selecting per-map .decls files.
  • Regenerated collision caches now keep the first map entity named as the world model even after OpenQ4's trace-model slots are initialized, preventing MP map loads from null-dereferencing the clip world when a stale stock .cm has to be rebuilt.
  • Material decl parity advanced: per-level material use counts now resolve onto image diagnostics like retail, Quake 4 material tokens for alphaFunc, fragmentParm, sky, and needCurrentRender now preserve their authored behavior instead of being ignored or defaulting to Doom 3-only semantics, sort gui and retail sort constants now resolve consistently, and unknown materialType references now warn like the shipped engine.
  • Sound shader decl parity improved: descriptions, min/max frequencyshift, frequentlyUsed, no_shakes, minSamples, and +10 dB volumeDb clamping now survive parsing, sound shader memory/list diagnostics include their retained decl state, level-load reference marking now propagates from sound decls to their loaded samples, retail entry-only default/duration queries are restored, and the retail rvSoundShaderEdit bridge now exposes sample/shake/purge/load helpers for tools.
  • Effect/player-model/skin decl parity advanced: skin and player-model decl diagnostics now report retained allocations and useful player-model fields, BSE effect decls now expose retail-style segment lookup/copy/editor-original helpers with safe bounds handling, and the integrated BSE path now wires the retail rvDeclEffectEdit bridge instead of leaving it null.
  • Decl editor/tool wiring advanced: AF, playback, and lip-sync decl edit adapters are now available engine-side, lip-sync decls can rebuild retail-style text, Raven decl parsers now expose the no-caching signatures expected by the shared SDK headers, player-model parsing performs the retail media-cache pass, and table/material-type parsing now follows recovered retail edge-case behavior.
  • Retail decl validation parity advanced: table, skin, entityDef, AF, material-type, lip-sync, playback, and player-model validation now performs the retail temporary-decl parse/default-state check instead of accepting every text block, and the base idDecl no-caching parse shim now preserves the caller's cache-suppression request.
  • Added a default-off r_motionBlur graphics option for subtle camera motion blur, including depth-aware sampling, safe history resets on map/view changes, and a debug vector view for tuning.
  • Added optional rigid-object motion vectors behind r_motionBlurObjectVectors, improving blur on moving doors, platforms, and other non-skinned opaque objects while preserving the camera-only fallback for unsupported surfaces.
  • Packed MD5R light interactions now advance along the retail ARB2 path without regressing the stable hybrid renderer: packed interaction passes switch to the stock md5rinteraction* vertex-program family, upload the retail MD5R interaction parameter block in program.env[75..91], interaction lightTris now emit the retail per-prim-batch headered index stream instead of staying on the older flat filtered list when the packed builder succeeds, packed interaction rendering consumes that headered batch stream directly while continuing to fall back to the classic interaction path if a packed program/buffer bind or retail packed light-tri build is unavailable, retail-style packed stage texturing now picks the correct MD5R program variant and submits full ambient/material stage batches directly from the packed draw buffers when the stage path is fully prepared, ARB ambient material-program stages with an authored md5r*.vp alias now use the same prepared packed draw/runtime path instead of forcing the classic ambient-cache vertex layout, packed late blend-light passes now explicitly refresh the frame-temp ambient/index view they need instead of depending on earlier light submission to have populated it, the deferred light-grid indirect pass now does the same so packed surfaces stop assuming a prior ambient submission already materialized classic cache-backed draw data, the shared depth / ambient shader passes now run through the same packed cache-prep helper before they touch classic ambientCache state, the generic RB_RenderTriangleSurface / RB_T_RenderTriangleSurface path now gives packed surfaces the same frame-temp classic draw view instead of dropping them straight to immediate-mode fallback, the last-resort RB_DrawElementsImmediate path can now materialize packed prim-batch triangles on demand instead of assuming classic verts/indexes residency, the GLSL material/projected-shadow/point-shadow interaction creators now recover packed ambient-cache state from the source ambient surface instead of assuming earlier interaction submission already populated classic draw-vertex data, the draw core now recognizes a second prepared packed direct-draw context so the MD5R depth and fog passes can route their per-prim-batch submission through RB_DrawElementsWithCounters() instead of each carrying a separate private loop, those ARB2 packed depth/fog entry points now attempt direct MD5R submission before falling back to the older classic-cache requirement, and renderer diagnostics such as r_showLightCount, r_showNormals, r_showEdges, and the other raw-geometry overlays now rematerialize packed interaction/ambient data instead of silently skipping MD5R-backed surfaces.
  • Fixed the active light-parity fog regression in game/storage1 and other stock scenes: fog passes now force the fog light's current color instead of inheriting stale per-vertex color arrays, the generated _fog / _fogEnter lookup textures once again stay full RGBA instead of collapsing to alpha-only classification, and packed MD5R fog again routes through the retail md5rbasicfog* variant/palette path for skinned packed surfaces.
  • Collision-model parity improved for generated/runtime CM data: retail Quake 4 primitive tracking and polygon texture-basis data are now preserved during CM generation/serialization, render-model collision no longer over-merges across distinct source surfaces, and .proc CRC validation now matches retail CM load behavior more closely.
  • Collision-model load parity improved for stock maps and SP entities: CM parsing now reuses existing model slots instead of exhausting submodel capacity, world/map submodel naming matches retail expectations more closely, retail-style SP clipmodel fallback no longer probes entity names, and stock game/medlabs map init no longer emits contains different model/no free slots CM failures.
  • Collision-model lifetime parity now more closely matches retail Quake 4: map teardown drops CM reference counts instead of clearing the entire manager, purges free model geometry in place for slot reuse, and SP/MP map shutdown now purges unreferenced CM data before the next level load.
  • MCC med-bed intro overlay now keeps its retail 128x128 ambient data/static layers tiled at native scale across the expanded GUI canvas, and edge-hugging detail widgets anchor to the appropriate wide/tall screen sides.
  • Stock split-map loading screens now preserve Raven entity filters such as game/storage1 first / second, restoring the filtered mapDef title, levelshot, autosave name, and load-size metadata instead of falling back to the raw map path.
  • Main menu placeholder art rotation now uses a randomized montage of eligible loadscreen levelshots, with proper wide/tall expansion-tile composition and slow zoom transitions per shot.
  • Startup/loadscreen placeholder now hands off to the main menu automatically after 3 seconds, main-menu entry transitions use a short black fade-in stretched to native screen extents, and startup logo videos can be skipped with default-on com_skipLogoVideos 1.
  • Added a depth-aware r_lensFlare graphics option with quality levels for lightweight light coronas and high-quality lens ghost/streak overlays.
  • Material handling fixes completed; engine startup no longer depends on custom material script overrides in repo q4base/.
  • Startup material/icon sizing now tolerates stock decls without drawable stages, preventing an application-load crash during UI icon registration.
  • Decl parse dispatch now follows the retail SDK no-caching path through idDeclBase again while material and sound shaders expose explicit three-argument parser overrides, preserving stock material stage/image parsing and preventing fully black map rendering after level load.
  • Decl-manager folder registration and packed-decl writing now mirror more retail bookkeeping: startup logs per-type load time/text memory again, and packed .decls writes store the decl's current linear-list slot with the retail index fallback.
  • Decl late-load diagnostics now match retail more closely by warning when uncached decls are parsed after startup/level precaching outside active editor sessions.
  • Decl editor/helper safety improved: CreateNewDecl now mirrors retail null-tolerant filename/default-definition handling, and DeclByIndex range errors report the decl type and requested/max indices.
  • Legacy PDA/email/video/audio decl families are registered engine-side again with retail list/print command wiring and parser stubs, restoring Quake 4's full decl type surface for game and tool lookups without adding content overrides.
  • Retail light material parsing parity improved: lights/* material stages and lightFalloffImage entries now load through the renderer's light image bucket instead of generic material image classification, restoring Quake 4's intended projection/falloff handling for stock map lights.
  • Retail programmable material decl parsing now recognizes Quake 4's symbolic fragmentMap bindings for lightfalloffImage, lightImage, ambientNormalMap, normalCubeMap, and specularTableImage, keeping light-driven slots tokenized instead of misloading them as ordinary images.
  • Retail guide-template decl wiring restored: rvDeclGuide now has its retail parse/evaluate/remove-bracing implementation, guide reloads clear the previous table before reparsing, duplicate guide names are rejected like retail, and guide/inlineGuide material expansion now shares the same parameter substitution path.
  • Decl validation/tool parity improved: the base idDecl::Validate wrapper now delegates through the decl base like the Quake 4 SDK, the local decl fallback validates by parsing a temporary decl instead of accepting every block, validation runs now assert the retail DoingDeclValidation() editor bit so parser-side hard errors can downgrade to warnings, entityDef media caching observes the recovered retail editor-mask bits, material/sound decls expose the retail validation slot, sound shader decls can rebuild text for resaveDecl tooling, and the engine-side idCommon/UI manager surface again exposes Raven's decl/tool hooks used by SDK validation, editDecls, model-view, debugger, and always-think GUI paths.
  • Game-library decl wiring tightened: SP model and camera decl validation now performs temporary-decl parsing instead of accepting every text block, SP validation-only model/animation failures downgrade through the same DoingDeclValidation() warning path as MP/the SDK, SP def/af folder registration uses the same Raven wrapper path as MP/the SDK, and camera validation now allocates the dedicated DECL_CAMERADEF slot rather than the SDK's stale model-def allocation.
  • Packed decl writer/export support improved: generated game-section .decls files can include the registered model and playerModel decl slots alongside entity/camera/AF/export data in OpenQ4 mode, while the interactive writeDeclFile command is exposed from the same loose-decl startup branch as retail.
  • Decl SDK/header wiring tightened: restored PDA/email/video/audio decl declarations now expose both retail parse entry points to the companion game-library headers, and optional decl-folder scans tolerate absent file lists while continuing recursive discovery.
  • Player-model decl parsing now follows the recovered retail rules more closely: malformed unquoted keys warn/default instead of being accepted, only canonical def_head / def_head_ui fields populate head data, and the fallback definition matches Quake 4's minimal marine/Kane-head pair.
  • Playback decl runtime sampling now follows retail timing more closely: recorded paths are resampled on finish, offset/angle queries return the playback expiration state, and button/impulse callbacks preserve their event offsets for game playback drivers.
  • BSE effect decl parsing now follows retail keyword handling more closely: the effect decl exposes the retail no-caching parser slot used by the decl manager, effect/segment/particle tokens are case-insensitive, doubleVision/shake/tunnel segment IDs use the shipped ordering, malformed effect bodies report failure at the same closing-brace boundary, trail segment lookups are case-insensitive, effect duration bounds rebuild on every finish, invalid particle-template entries warn/recover like retail, empty particle models fall back to _default, and overfull spawned-effect lists warn instead of terminating the client.
  • Game-library decl validation now shares the engine's temporary-decl validation/free helpers so SP/MP model and camera validation reject defaulted parses and clean allocated decl/base pairs consistently, and the companion playerModel header exposes the same retail parse overload surface as the engine.
  • Sound-shader decl parsing now reads the retail s_maxSoundsPerShader cvar, so stock configs and quality presets control per-shader sample admission instead of being ignored by the old OpenQ4-only s_maxSamples name.
  • Decl command tooling now follows retail default-creation semantics for resaveDecl <type> <name> and touch <type> <name>, sharing the same valid-type listing and materializing/defaulting named decls through FindType instead of treating absent loose declarations as hard misses.
  • Guide-template decl expansion now follows retail consumption semantics: found guide and inlineGuide calls are consumed even when their argument list does not match, inline-guide replacement runs as a single pass over the original definition, and missing inline-guide definitions return the retail failure state instead of partially succeeding.
  • Decl-file guide dispatch now follows the retail loader path in loose, packed, and lazy packed-stub parses: guide decls run the guide expansion attempt and the inline-guide pass without treating a failed expansion return as a skip, and duplicate loose decl definitions warn unconditionally like the shipped engine.
  • Decl source replacement now follows retail editor/save wiring: invalid source files report an empty filename, external-modification checks close their read handle before returning, and resaveDecl/decl-editor writes target fs_devpath instead of the launch CD path.
  • Retail guide parsing parity advanced: guides/*.guide now loads through a recovered guide-table path, guide creation shares the retail GetNewGuide helper, and unrelated top-level guide-file tokens are tolerated like the shipped engine instead of aborting startup parsing.
  • Packed decl serialization and intake now track retail more closely: loose/packed decl loaders let ParseBracedSectionExact consume non-guide bodies directly, inline-guide expansion runs from the same post-body step, and generated packed decl entries always write the retail type name header before the stored body or stub.
  • Guide-template substitution now follows retail's evolving-definition replacement loop, preserving correct behavior when guide arguments overlap with parameter names or later replacements shift the body, and the obsolete pre-retail guide preprocessor has been removed.
  • Loose decl reloads now honor retail's renderer-side image_writeProgramImages parse trigger, allowing the program-image generation path to force newly loaded decls through ParseLocal() once the renderer is running even when they have not already been referenced this level.
  • The checkDecls command now follows retail's reparse gate for every loaded decl that is not already DS_PARSED, so defaulted decls are checked again instead of being skipped as if they were clean.
  • Packed decl loading now initializes placeholder decl records completely before indexed replacement, preventing the retail com_SingleDeclFile/checkDecls path from dereferencing debug-fill memory when sparse packed indexes are replayed.
  • Decl reload/tooling diagnostics now follow the retail path more closely: reloadDecls reports per-file progress, and decl text-memory totals walk GetNumDecls/DeclByIndex(false) so packed sparse indexes and editor summaries share the normal decl access surface.
  • Guide-template edge cases now match retail parser recovery more closely: malformed parameter comma counts warn under the same rule, inline-guide body unbracing follows the shipped two-step trim, and missing guide names no longer skip ahead past the lexer position retail leaves for subsequent parsing.
  • The packed-decl cvar surface now matches retail wiring more closely: com_SingleDeclFile is exported through the shared engine headers instead of staying private to the decl manager, so renderer/session/game code can bind to the same cvar symbol as the SDK headers expect.
  • Packed-decl startup naming now follows retail's default asset-log handoff: the filesystem seeds assetlogs/default during init, and the decl manager derives default.decls from the active asset-log basename instead of falling back to OpenQ4's older decls.decls name.
  • Asset-log ownership now follows retail's decl-packaging handoff more closely: SetAssetLogName renames the active asset log without implicitly clearing collected entries, leaving log reset/write ownership to the explicit asset-log paths.
  • Retail programmable material-decl parsing now recognizes Raven GLSL shaderParm and shaderTexture built-ins from guide-expanded stages, including light origins/projection/falloff, color modulation/addition, diffuse/specular colors, matrix rows, shared lookup images, and dynamic light image slots.
  • Retail custom-lighting material stages now stay out of the ambient pass and run through the per-light interaction path, with material-authored GLSL programs receiving Quake 4 interaction uniforms, dynamic light textures, stable tangent-space attribute bindings, and the same packed MD5R ambient-cache recovery used by the other GLSL interaction paths while shadow-map lighting falls back to the stencil path for those custom material programs.
  • Retail lighting parity restored for distance-cull portal fades, Raven special-effect pass ordering, ARB2 specular scaling, and noSelfShadow stencil-shadow routing.
  • Retail light/interaction parity improved again: fog/blend lights now honor Quake 4's noFog interaction contract, sound-driven light/material shader expressions once again receive referenceSoundHandle amplitude inputs, entity ambient submission now honors retail r_lod_entities scissor-LOD gating for tiny on-screen coverage, retail r_useEntityScissors behavior is once again enabled by default so entity scissor tightening matches stock Quake 4 out of the box, view entities now follow retail's sort-by-model submission order before ambient/light interaction work, authored light detail levels once again gate view-light admission through retail-style r_lightDetailLevel, light/shadow submissions now honor retail r_limitBatchSize tiny-batch dropping before drawsurf allocation, interaction shadows now respect retail shadow-LOD / noDynamicShadows gating instead of keeping distant or explicitly disabled dynamic shadows alive, and light/shadow routing once again keys off the original interaction material instead of letting shader overrides change noSelfShadow ownership.
  • Retail packed MD5R light-submission parity advanced again in the current hybrid renderer: packed ambient surfaces, packed-backed light interactions, and packed shadow-map casters now refresh frame-temp draw/index data per visible frame instead of forcing long-lived classic cache ownership, interaction lightTris retain retail packed ownership metadata in the front end, and packed temp-cache submissions no longer trip idVertexCache::Touch().
  • The final tracked renderer light-parity gap is now closed in code: packed MD5R depth, fog, ambient, material-stage, interaction, and stencil-shadow submission now bind retail-style MD5R vertex programs and draw packed buffers directly instead of falling back through transient classic draw-vertex uploads, while material parsing also resolves the retail md5r*.vp stage-program aliases needed by those packed paths.
  • Added a live renderer light-report tool (r_showViewLights) that prints detailed per-light diagnostics for lights affecting the current view origin/player position.
  • Added a persistent visual overlay for r_showViewLights (r_showViewLightsVisuals) that draws each last-reported light's origin marker, color, and radius volume in-world until the next report refresh.
  • Retail deform rectsprite material support restored so shipped Quake 4 multiplayer flag-display shaders follow the renderer's rectangular autosprite path.
  • Menu rendering issues fixed.
  • Settings menus now present cleaner Display/Game pages with compact single-display spacing, smooth clipped scrolling, corrected scroll extents, and Proper Case OpenQ4 setting labels while keeping section headings uppercase.
  • SDL3 backend integrated as the default platform path (legacy Win32 backend remains transitional).
  • Meson + Ninja build system introduced as canonical build path.
  • External dependencies moved to Meson subprojects/wraps (sdl3, glew, stb_vorbis, openal-soft-prebuilt).
  • Vendored GLEW updated to 2.3.1 (both subprojects/glew and src/external/glew) while preserving local static-link/include-path compatibility tweaks.
  • Vendored OpenAL Soft updated to 1.25.1 headers/defs/import libs (both subprojects/openal-soft-prebuilt and src/external/openal-soft), with Win64 runtime DLL refreshed under src/external/openal-soft/bin/win64/OpenAL32.dll.
  • Dependency refresh validated with clean Meson reconfigure (setup --wipe) and successful rebuild in builddir.
  • Ogg Vorbis (.ogg) playback support integrated (decoded via stb_vorbis).
  • C++23-targeting baseline enabled on MSVC (cpp_std=vc++latest).
  • MSVC 2026 toolchain direction documented and implemented as an optional enforceable baseline (-Denforce_msvc_2026=true).
  • Meson setup wrapper improved to auto-recover missing/stale build directories and avoid VS tool discovery null-crash.
  • Windows SDL3 key/input parity improvements: backspace fix, control-char synthesis, locale-aware RightAlt behavior.
  • Manual key matrix audit completed and documented for console, GUI edit fields, chat, binds, numpad, and modifiers.
  • GUI scaling behavior updated to preserve uniform/aspect-correct rendering on window resize.
  • Engine-side console/UI relayout now handles wide and narrow/tall aspect ratios, with live updates on screen size/aspect changes.
  • Console mouse handling now uses native console-space cursor routing/drawing bounded to the live console rect, and adds archived con_height control for the console open height (0.1 to 1.0, default 0.5).
  • Platform/architecture roadmap documentation added for Windows/Linux/macOS direction with x64 baseline.
  • Legacy/redundant build-system artifacts reduced (CMake path retired from active source tree).
  • BSE manager/renderer lifecycle contract restored: effect completion now propagates correctly through ServiceEffect -> UpdateEffectDef, preventing immediate client-effect teardown and enabling proper expiry reporting.
  • BSE sound capability path restored at render-world boundary: EffectDefHasSound now delegates to decl metadata and manager checks instead of unconditional false.
  • BSE segment runtime no longer compiles as pure no-op stubs; core segment timing/attenuation/check/update/count plumbing has been re-enabled as the phase-4 runtime foundation.
  • BSE game-lib network/event parity restored: EVENT_PLAYEFFECT_JOINT no longer hits an assert placeholder, receive paths now validate decl/filter/rate-limit consistently, and networked effects restore gravity assignment parity.
  • BSE save/restore stability improved for active effects by clearing stale referenceSoundHandle on restore so emitters are safely reallocated.
  • Temporary BSE visibility fallback added (bse_fallbackSprite, default 1): active client effects now emit a sprite-backed render entity until full particle-surface rendering is fully restored.
  • BSE segment activation timing fixed: rvBSE::Service no longer applies a large negative per-segment spawn offset that delayed segment starts by multiple seconds.
  • BSE segment spawn lifecycle restored for SEG_EMITTER, SEG_TRAIL, and SEG_SPAWNER, including attenuation-aware interval/count spawning and loop-time progression tracking.
  • BSE trail/child spawn placement improved: non-zero spawn offsets now propagate into particle init positions, and trail segments spawn using interpolated local movement offsets.
  • BSE moving-emitter transform parity improved: non-locked particle position/velocity evaluation now converts from spawn-space into current effect-space using stored spawn origin/axis.
  • BSE owner wind propagation restored by transforming renderEffect_t::windVector into local effect wind each update.
  • BSE decal segment path restored from no-op to active world projection (SEG_DECAL now builds/projections decal winding via ProjectDecalOntoWorld using sampled spawn size/rotation).
  • BSE spawn ordering parity improved: runtime particle insertion is no longer unconditional LIFO; linked segments preserve stable chronological/end-time list order while complex segments retain front-insert behavior.
  • BSE segment draw-order refinements applied for linked-strip rendering: depth-sort is disabled for linked strip topologies and initial strip index budgeting is handled explicitly.
  • BSE runtime sort utility implemented (rvSegment::Sort) with stable depth ordering for deterministic per-segment ordering when used.
  • BSE network/entity receive rate-limiting corrected by removing duplicate cost consumption (Filtered already applies category rate checks; explicit second CanPlayRateLimited checks removed).
  • BSE particle spawn-parameter sanitization restored (rvParticleTemplate::FixupParms no longer compiles as a no-op stub).
  • BSE segment attenuation scaling parity restored: emitter interval/count attenuation now uses bse_scale interpolation semantics.
  • BSE particle cap parity restored: bse_maxParticles now drives runtime segment allocation/count clamps instead of compile-time-only MAX_PARTICLES paths.
  • BSE owner-state parity improved: mLightningAxis is now derived from current origin/end-origin direction with stable basis fallback.
  • Temporary BSE trace spam removed from hot runtime paths (spawn/expire/remove and segment render skip/state traces), and renderer counter cvar default restored to off (bse_frameCounters=0).
  • Full clean rebuild validation completed in builddir/ with both OpenQ4.exe and OpenQ4-ded.exe linking successfully after BSE parity updates.
  • BSE particle gravity parity restored: template gravity ranges now contribute spawn acceleration in rvParticle::FinishSpawn.
  • BSE debris parity advanced: debris particles now spawn client moveable entities (entityDef) through game->SpawnClientMoveable and stop CPU-side particle rendering.
  • BSE shader-parm safety defaults hardened: client effects now initialize RGBA/brightness/timeoffset in rvClientEffect::Init, with zeroed-parm fallback in rvBSE::UpdateFromOwner.
  • BSE template runtime contract completed by implementing missing declared helpers (rvParticleTemplate::Compare, GetTraceModel, GetTrailCount, ShutdownStatic).
  • BSE unlocked-bounce matrix reprojection parity improved: post-impact velocity/position persistence now uses inverse current->init axis mapping with origin-delta compensation, avoiding frame-space double transforms in moving/rotating emitter paths.
  • BSE owner-kinematics parity improved: rvBSE::UpdateFromOwner now preserves last valid owner velocity across same-timestamp updates instead of zeroing mCurrentVelocity on tiny frame deltas.
  • BSE oriented-particle matrix parity improved: oriented quad corner ordering/signs now match decompiled transform basis usage, removing mirrored orientation in rotated oriented-particle paths.
  • Startup command parsing hardening completed: oversized +wait stress launches no longer crash during early StartupVariable cvar processing (command-line overflow/drop handling and idCmdArgs::AppendArg bounds checks tightened).
  • Multiplayer server-side hitscan lag compensation added with configurable rewind controls (net_mpLagCompensation, net_mpLagCompMaxMS, net_mpLagCompBiasMS) and server diagnostics (net_mpLagCompDebug).
  • Multiplayer non-local prediction mode is now runtime-selectable through net_mpPredictMode (0 legacy limited behavior, 1 enhanced per-frame prediction).
  • Scope/zoom handling documentation updated to reflect multiplayer zoom stability and scope yaw alignment behavior.
  • High-refresh view interpolation now includes tunable local first-person biasing (pm_presentViewBias) so the camera, FOV, and view weapon spend less time a full tic behind at high presentation rates without changing authoritative gameplay timing.
  • High-refresh local first-person biasing was retuned so the default interpolation path no longer surges to the newest snapshot and stalls mid-tic; pm_presentViewBias now remains an opt-in bias that eases forward more gently when needed.
  • High-refresh first-person weapon FX now stay aligned with the interpolated local/spectated camera on the fire frame: view-weapon muzzle flashes refresh in presentation space immediately, and hitscan tracer/path origins sample the presentation-space muzzle instead of the last authoritative pose.
  • High-refresh multiplayer carrier/powerup halo lights now follow interpolated player presentation on repeated-state frames instead of stepping only at the 60 Hz simulation tick, keeping CTF/powerup light halos aligned with moving carriers.
  • High-refresh vehicle crash/scrape effects now interpolate persistent world-space crash FX between collision snapshots on repeated-state frames, keeping scrape contact visuals smoother when vehicles slide along world geometry.
  • High-refresh projectile fly trails and player powerup effects now keep their presentation-time attenuation/origin parameters in sync with interpolated movement on repeated-state frames instead of stepping only when the 60 Hz gameplay tick rewrites those effects.
  • Multiplayer joiners now reconstruct terminal non-predicted projectile snapshots into visible detonate/impact FX instead of silently hiding those projectiles when they arrive already exploded, restoring host-fired projectile hit visuals on clients.
  • Multiplayer clients now receive authoritative hitscan impact FX through a dedicated remote-impact packet while the legacy hitscan trace message continues to drive path/tracer replay; that replay now bypasses local effect-rate throttling, reaches the firing remote client as well as other viewers, preserves the authored bullet/shotgun impact color, and still reapplies tint for railgun-class impacts that explicitly opt into hitscan coloring.
  • High-refresh listen-server view-weapon movement offsets now collapse duplicate same-tic acceleration samples during prediction reruns, preventing forward/side movement input changes from stacking extra shove into the local first-person gun after the earlier view-bias and turn-history fixes.
  • High-refresh listen-server view-weapon presentation no longer feeds render-only interpolated weapon poses back into shared weapon state, preventing the local first-person gun from regaining the forward lunge while repeated-state draw frames refresh muzzle-flash / flashlight / GUI-light alignment.
  • Multiplayer draw now reuses the same render-prep path as single-player, so the local or spectated first-person view recalculates its render view and refreshes presentation-space player/world/view-weapon transforms immediately before RenderPlayerView() instead of drawing the weapon from a stale simulation pose during listen-server movement.
  • High-refresh first-person muzzle flashes and other bound view-weapon firing FX now refresh from the corrected draw-time presentation pose on both simulation and repeated-state frames, so they no longer stick at the pre-correction gun position on the fire frame after the listen-server lunge fix.
  • High-refresh lightning-gun follow-up was narrowed to the local first-person beam only: trailEffectView now refreshes from the corrected presentation-space muzzle/chest joint and a presentation-time local beam trace on both simulation and repeated-state render frames, while the authoritative world/chain-lightning effects remain on the normal gameplay update path.
  • High-refresh bespoke visual-owner follow-up now refreshes gib skeleton side-models and security-camera model presentation on repeated-state frames, keeping those visuals aligned with interpolated transforms instead of stepping only at the 60 Hz simulation cadence.
  • High-refresh alternative camera/view-source follow-up now refreshes remote entity render views, security-camera feeds, portal-sky/playback cameras, and steam-pipe side models from presentation-space or interpolated repeated-state data instead of leaving those views and side visuals pinned to the last 60 Hz simulation sample.
  • High-refresh bespoke-visual follow-up now interpolates SP/MP idMultiModelAF side-model render defs on repeated frames and aligns the MP jump-pad activation FX origin with the SP centered-physics path, closing another pair of effect/render-owner presentation gaps that still sat outside the base entity refresh hooks.
  • High-refresh brittle-fracture callback models now rebuild from interpolated shard transforms on repeated-state frames, keeping dropped shard geometry smooth through shatter/fall/settle motion instead of stepping only on the 60 Hz simulation tick.
  • High-refresh weapon render lights now stay aligned with interpolated weapon/player presentation on repeated-state frames, keeping active muzzle-flash, world muzzle-flash, flashlight, and weapon GUI light defs from stepping at the 60 Hz simulation tick.
  • Ragdoll activation quality improved without changing the fixed 60 Hz simulation cadence: startup now keeps owner/world motion, handles initial penetrations more cleanly, and preserves slightly richer contact support for grounded corpses.
  • Rigid-body physics timing-safe quality pass applied without changing the fixed simulation cadence: angular velocity handoff now respects world inertia, water is handled as drag instead of a one-time collision-state hack, rigid-body contacts keep richer deduplicated support points, and impacts now preserve time-of-impact momentum while consuming a small bounded amount of leftover fixed-step time.
  • Script compiler x64 pointer-temp parity fix ported from OpenD3: right-associative indirect-expression retagging now guards 4-byte object-ref temp vs 8-byte pointer temp storage mismatch by allocating pointer-sized result defs when needed, preventing trigger/door script chain corruption.
  • Retail AAS placeholder parity restored: stock dummy .aas files now load/discard like retail instead of warning-spamming and failing stock map init, and AAS tactical data is cleared correctly between loads.
  • Bloom stability and quality improved: live r_bloom/r_bloom* changes now use the offscreen scene-target path immediately, scratch render targets rebuild their FBO attachments safely after runtime reallocations, map handoffs no longer rely on the fragile back-buffer bloom path, and bright-pass extraction now keeps only highlight energy so broad lights stop producing solid white bloom discs.
  • Manual release packaging builds are healthy again: the engine restored the shared idCommon timing/error/tool accessors expected by the SP/MP game libs, fixing the cross-platform release-build break that stopped the v0.1.011 workflow before artifacts were produced.
  • High-refresh mover riding is now stable on lifts such as game/storage2: the player keeps descending mover carry, ignores tiny mover-seam pseudo-landings/step jolts, and interpolates first-person view state relative to the mover so the camera stays smooth above 60 FPS instead of vibrating against platform motion.
  • High-refresh projectile and weapon-hit impact regressions were corrected by keeping client-predicted projectile collision/explode work on authoritative game ticks only while repeated-state redraws use the dedicated projectile interpolation path, preventing lingering rocket models and impact/scorch FX from replaying every render frame after a hit.
  • Renderer effect lifetime replay regression fixed: expired one-shot BSE impact effects now stay finished until their client-effect owner frees the handle, preventing bullet marks, scorch decals, and hit sounds from being recreated every frame after a hit.
  • Phase 4 repeated-state rendering overhead reduced: SP/MP scene refresh no longer scans all spawned entities every redraw for projectile interpolation, and active entities now skip repeated-state transform/non-model refresh work unless they actually have presentation deltas or interpolation-sensitive auxiliary visuals, recovering a major agame/airdefense1 FPS regression introduced during the high-refresh work.
  • High-refresh BSE overhead reduced again: repeated-state client effects now keep renderer owner-time on authoritative game ticks instead of wall-clock presentation time, avoiding render-rate ambient effect spawning on maps like agame/airdefense1, and renderer effect servicing now runs once per rendered frame instead of repeating per view.
  • Repeated-state client-entity work is now pruned more aggressively in SP/MP: static client models and client effects no longer rerun redraw-time presentation work by default, while bound client entities only stay on the high-refresh path when their owner actually has an interpolated transform delta and client moveables stay there only while their own transform/scale interpolation is active.
  • Collision-model retail parity improved again: .proc loading now matches Quake 4's looser version-token behavior, CM precache requests stay on the .cm-only path instead of generating render-model collision data, and extension-mismatched authored collision caches (for example .lwo/.ase names requested through runtime render aliases) now reuse the existing loaded CM without renaming or duplicating cache entries.
  • Collision-model loader parity improved again: CM .proc and .cm parsing now use Quake 4's binary-aware lexer path instead of bypassing it, restoring compiled-companion fallback behavior (.procc / .cmc), normal search-path precedence, retail-style CM loader diagnostics, retail proc-clip slot reservation during map builds, retail-style .cm serialization that no longer forces synthetic proc-clip models into saved map collision caches, retail-style binary companion generation (.cmc) when com_BinaryWrite is enabled, stock load pacifier updates around collision-data generation, retail-style fatal map-load handling when the required .proc build data is missing, explicit map-entity CM exports back on fs_devpath, and the retail PROC/AAS out-of-date overlays during content bring-up.
  • Collision-model trace/debug parity improved again: rotation and contents paths now restore retail-style materialType propagation, SP/MP share the retail two-argument CM debug interface with player-view-oriented replay hooks, retained translation/rotation failure replay now mirrors retail debugging more closely, and stock game/airdefense1 no longer crashes at player spawn/level load when retail-style CM material-type lookups run against parsed .cm data.
  • Level-load filesystem robustness improved: empty-path ReadFile probes now resolve as normal missing-file checks instead of raising a fatal dialog, which unblocks stock map startup paths such as game/airdefense1 and keeps the runtime log alive for any follow-up diagnostics.
  • Collision-model diagnostics parity improved again: local CM ModelInfo() reporting is no longer a stub, single-player restores the retail collisionModelInfo debug command alongside multiplayer, Contacts() once again follows retail's translation-only contact sweep semantics, and SP validation on game/airdefense1 plus collisionModelInfo all now completes cleanly with the updated CM debug/reporting paths.
  • Collision-model cache-write parity improved again: runtime-generated .cm caches now follow retail Quake 4's fs_devpath destination instead of being diverted to fs_savepath, keeping generated CM outputs on the normal authored/dev override path alongside the existing map-entity export behavior.
  • Collision-model render-source parity improved again: LoadRenderModel() now matches retail Quake 4's authored-CM source-model whitelist by admitting only .ase, .lwo, and .obj when generating collision data from render models, dropping the extra .mdr / .dae CM-generation path that was broader than retail.
  • Single-player clip-query parity improved again: idGameLocal::ClipModelsTouchingBounds() no longer falls back from non-zero clip worlds into world 0 for trigger queries, so the SP bounds-query path now matches multiplayer and retail behavior instead of keeping the temporary OpenQ4 multi-instance trigger override.
  • MD5R parity improved again: SoA Pos3Swizzled vertex buffers now decode into usable packed geometry instead of falling back to metadata-only loads, MD5RProc companions now preserve and round-trip the real retail map CRC token instead of a stub value, and retained MD5R vertex exports now keep specular-color / point-size fields instead of discarding them.
  • Decal parity improved again: packed MD5R surfaces now prefer a retail-style native sil-trace decal projector over the transient draw-vertex materialization fallback, while still falling back safely when packed mesh state is incomplete; the fallback now reuses the current live draw geometry when available so dynamic skinned recipients do not drop back to bind-pose decal projection, the native packed path now only runs on true packed sil-trace buffers instead of misusing draw-order silTraceVerts mirrors, decal fade cleanup no longer needlessly invalidates cached tangent/plane data every frame when the decal mesh itself did not change, and decal draw-surfs now snapshot vertices plus per-stage color data into one retail-style transient upload block instead of splitting them across separate temp cache allocations.
  • SDL3 keyboard layout parity improved: printable key events now use SDL3's active-layout translation instead of the fixed US scancode map, non-English console-toggle lookup now follows the translated grave/console scancode again, and UTF-8 text input is tracked as decoded codepoints in the SDL3 event path rather than a stale byte-splitting backlog item.
  • POSIX startup now enforces the same single-instance guard as Windows by holding a per-user advisory launch lock, while sys_allowMultipleInstances 1 keeps multi-instance testing available when explicitly needed.
  • Retail flare/material deform parity improved again: ambient submission no longer clips deform flare / sprite-style materials to tiny authored entity scissors, so stock map-authored effects such as game/storage1's moving beamBlastFlare render as expanded flare geometry instead of a boxed white square; the flare deform path also restores retail prim-batch handling and cleared-temp-vertex setup.
  • Retail decl folder registration parity improved: recursive decl folder scans now register each child folder as its own folder/default-type pair before loading files, and DECL_MODELEXPORT ownership is back on the game-library model/export/camera registration path instead of the framework pre-claiming the parser-only export slot.

Carry Forward

  • Linux and macOS bring-up needs full compile/link/runtime validation to reach first-class status.
  • Replace temporary MSVC compatibility flag (/Zc:strictStrings-) with full strict-strings codebase compliance.