This is the authoritative current-state index for openQ4 engine capability claims. It answers whether a capability exists in the tree as audited on 2026-08-23; proposals describe intent, and release notes describe historical changes, but neither overrides this matrix. Domain documents linked below own their detailed acceptance evidence.
Status means:
- Implemented — a functional scoped path is integrated with the named implementation evidence. It may remain optional and default-off pending release promotion; the scope/qualification column limits the claim and never implies every platform or asset is certified.
- Experimental — the scoped implementation is incomplete, trial-grade, or lacks the minimum evidence claimed by its row.
- Missing — there is no production implementation. A plan, cvar stub, shader prototype, or unused data structure does not count.
Any change that moves a row between these states must update this file and its evidence in the same change. When documentation disagrees, treat the narrower claim here as current.
| Capability | Status | Scope and qualification | Evidence |
|---|---|---|---|
| Network-driven executable updater | Implemented (retired safely) | The legacy version-check wire exchange remains compatible, but the client sends no GUID identity, ignores all server-provided text/URL/MIME/action fields, contains no updater download or execute path, and can only open the compile-time project releases URL without forcing exit. Pure-server package negotiation is a separate, bounded compatibility path described below. | AsyncClient.cpp, licensee.h, openq4_pure_pack.py |
| Server-supplied package transport | Implemented (validated redirect path; direct transfer build-conditional) | Pure-server redirects and PK4 download entries accept only bounded http:// or https:// URLs whose authority contains a syntactically valid DNS name, IPv4 literal, or bracketed IPv6 literal. Standard Meson packages do not enable libcurl, so syntax-validated redirect prompts remain available but in-process direct PK4 transfer reports unavailable. In a separately integrated curl-enabled build, the generic downloader revalidates the URL, restricts libcurl to HTTP(S), disables redirects, and applies connect, stall, and whole-transfer limits; package size, checksum, and destination-path validation remain mandatory. This validates syntax and protocol, not DNS ownership or server trust. |
AsyncClient.cpp, FileSystem.cpp, BuildDefines.h, URLPolicy.h, openurl_security.py |
| Pure multiplayer game-module boundary | Implemented (contained protocol 2.41 compatibility path) | Pure mode enforces the ordered asset-PK4 list while the legacy game-code field carries the stock 1.4.2 game300.pk4 checksum only as a platform-independent token for a module already resolved from trusted local openQ4 package/module roots. Pure negotiation never selects, downloads, extracts, or restarts into executable code. The token is not a hash of the loaded module, cryptographic module-equality proof, or anti-cheat guarantee. |
Official PK4 checksums, server security, FileSystem.cpp, openq4_pure_pack.py |
| Malformed network and snapshot input handling | Implemented (hardened legacy boundary) | Bit-message reads record underflow instead of silently continuing, bounded queue and user-command decoders reject incomplete payloads, and SP/MP snapshot readers validate covered entity, player, spectator, weapon, instance, projectile-owner, PVS, hit-scan, and game-state fields before use. Audited leaf readers stage decoded fields until their payload is valid. A late malformed top-level snapshot tears down the affected session before another game or presentation frame; the legacy entity lifecycle is not claimed to provide whole-snapshot rollback. This is targeted hardening of the audited paths, not a claim that every legacy parser is formally verified. | BitMsg.cpp, AsyncNetwork.cpp, network_security.py, in-tree game sources snapshot readers |
| Connection challenge entropy | Implemented | Client IDs, server-instance identity, and connection challenges use the OS CSPRNG and fail closed when it is unavailable. A connection challenge is endpoint/client-bound, expires after 30 seconds, and is consumed on successful admission; the legacy pure handshake may validate the same transaction across connect/pure/connect messages before admission. | AsyncClient.cpp, AsyncServer.cpp, network_security.py, CoreSafetyTest.cpp |
Authenticated remote console (rcon2) |
Implemented | Challenge/proof exchange uses CSPRNG nonces, endpoint binding, PBKDF2-HMAC-SHA-256 password verification, request binding, constant-time proof comparison, one-use expiry, and secret zeroing. It does not transmit the password. | Rcon2Protocol.cpp, CryptoHash.cpp, AsyncServer.cpp, network_security.py |
| Rcon abuse limits and secret redaction | Implemented | Per-source and global OOB/rcon limits plus cooldowns bound unauthenticated work. Private assignments are suppressed before dispatch from in-game, Win32, SDL, and TTY echo/history; old persistent history is purged; $ cvar expansion, startup dumps, config persistence, generic cvar output, and console completion previews redact; private journal payloads are omitted; and consumed command buffers are cleared. The password is case-sensitive/private. |
AsyncServer.cpp, CVarSystem.cpp, Console.cpp, PrivateCommand.h, network_security.py |
| Legacy plaintext rcon | Implemented (contained compatibility path) | Insecure plaintext rcon is disabled on both client and server by default. It is available only through explicit net_clientUseLegacyRcon 1 / net_serverAllowLegacyRcon 1 opt-in and should be limited to trusted legacy environments. |
AsyncNetwork.cpp, AsyncClient.cpp, AsyncServer.cpp, network_security.py |
| Doom 3 / Doom 3 BFG provenance inventory | Implemented | Both retained header families, their distinct Additional Terms, official pinned snapshots, and the six BFG-headered OpenAL files found through an intermediate RBDOOM lineage are inventoried without asserting a legal conclusion. | Source provenance, audit_source_provenance.py |
| Reproducible retail-PK4 SP/MP compatibility evidence | Implemented | Offline retail/overlay/runtime identity, windowed SP save/restore, demo record/playback, pure MP listen/client, logs, and engine screenshots have one non-interactive harness. It binds the approved-manifest file and current Git provenance, rejects dry-run/failure-bearing reports, reconstructs each exact role launch, and inventories every packaged-overlay path that supersedes a retail virtual path instead of calling the run stock-only. MP roles explicitly use archived ui_autoJoin 1 and prove an active, non-spectating player with a visible HUD; only a join-menu/initial-spectator test may explicitly set ui_autoJoin 0. A human visual/gameplay review and final-package/platform evidence remain required for promotion. |
Retail-PK4 compatibility baseline, stock_asset_baseline.py |
| Capability | Status | Scope and qualification | Evidence |
|---|---|---|---|
| Retail PK4 filesystem and idTech 4 asset/decl loaders | Implemented | Stock Quake 4 PK4 search, decls, materials, maps, MD5 models/animations, images, sounds, GUIs, cinematics, and scripts are the compatibility foundation. Full content behavior is still qualified scene-by-scene rather than claimed universally. | FileSystem.cpp, DeclManager.cpp, renderer validation |
| Unified SDK-licensed SP and MP game modules | Implemented | game_sp and game_mp are built directly from canonical src/game/ and src/mpgame/ sources in this repository and consumed under the unified baseoq4/ runtime. Proprietary retail DLL compatibility is intentionally out of scope. |
meson.build, meson_sources.py |
| BSE effects runtime | Implemented | BSE is first-party in-tree client code and supports stock Quake 4 effect declarations; dedicated builds retain the disabled manager path. | BSE_Manager.cpp, BSE research/validation |
| Save-game write/read compatibility | Implemented | Versioned openQ4 saves, integrity checking, recovery, legacy read support, entity-filter state, and save/load tests are present. Cross-version compatibility is governed explicitly rather than assumed. | Save compatibility policy, savegame_v3_contract.py |
| Render demos and multiview demos | Implemented | Render-demo record/playback and server multiview recording/playback exist with versioned compatibility checks. | Session.cpp, MultiViewDemo.cpp, demo_playback.py, multiview_demo.py |
| Fixed 60 Hz simulation with high-refresh presentation | Implemented | Authoritative simulation remains 60 Hz while presentation/interpolation and frame-pacing diagnostics support higher display rates. This does not change save/demo/network cadence. | Session.cpp, renderer_gameplay_benchmark.py |
| In-engine map compilation with AAS navigation | Implemented | dmap writes .proc and .cm and then rebuilds every AAS type declared by the shipped aas_types entityDef; runAAS, runAASDir and runReach drive the same compiler directly and register with dmap rather than inside ID_ALLOW_TOOLS. Unused AAS types receive the placeholder file the runtime recognises through idAASFile::IsDummyFile(). Compiled game/core2 reproduces the retail file's geometry CRC and navigation bounds exactly, with area/edge/face/reachability counts within roughly 8%, and loads with no AAS warnings. Raven's tactical feature lump is not generated, so recompiled maps lose navigation-mesh cover and lean positions while retaining full pathing. |
AAS compiler, AASBuild.cpp, dmap.cpp, aas_compiler_contract.py |
| Dedicated server | Implemented | Headless dedicated builds avoid client renderer/BSE presentation and have stock-map smoke coverage. | dedicated.cpp, linux_dedicated_stock_map_smoke.py |
| Background job system for general engine work | Implemented | Client, tool, and dedicated builds own one portable service with bounded list/job/dependency admission, sleepable waits, low/normal/high priority aging, dependency ordering, cooperative cancellation, deterministic inline fallback, shutdown joining, and observable counters. Dedicated builds default inline, and jobs_enable 0 executes rather than drops work. The learned level-load read/PK4-inflate and framing/integrity pipeline is its first production consumer; it uses independently opened VFS handles and publishes only sealed immutable source DTOs. Existing Milestone A current-build lifecycle evidence remains valid, while clean final-package recapture and the new consumer's retained Milestone B parity/cancellation evidence remain pending. |
ParallelJobSystem.cpp, LevelLoadPipeline.cpp, ParallelJobSystemTest.cpp, portable job-system contract |
| Learned level-load manifests and bounded read/decode staging | Experimental (implemented, default-off; performance requalification required) | A successful opt-in map load learns an exact map plus full-SHA-256 mode/entity-filter and ordered search/PK4/settings manifest. Matching reads, bounded worker preparation, transactional model/world/collision and version-3 animation caches, cancellation, corruption handling, and source fallback are integrated. A regression audit found materially excessive stock loading time and cache rewrite churn under the former default-on policy, so com_levelLoadModernization 0 now gates every cache/preload/animation read and write and preserves classic loading even when older individual settings remain archived on. This is not portal-aware live reprioritization, general asset streaming, or a speed-up claim; cold and warm performance must be requalified against the classic baseline before promotion. |
loading/cache contract, LevelLoadCacheManager.cpp, level_load_cache.py, LevelLoadCacheFormatTest.cpp |
| General asynchronous asset decode and GPU/audio upload streaming | Partial (level DDS images read and fingerprinted on worker threads since 2026-10-06; general streaming missing) | Since 2026-10-06 LoadLevelImages reads and fingerprints the precompressed DDS of upcoming images on up to four worker threads while the main thread uploads (image_prefetchLevelImages, Air Defense 1 about 2 s faster); files are still opened and adopted by their owner thread. The production level-load worker stage now performs source framing and integrity decode, but deliberately stops before asset-specific image, sound, declaration, model, world, collision, animation, or other owner parsing/transformation. Those owners still parse/decode, adopt, finalize, and upload through their established main-owner paths; there is no general runtime streaming scheduler, portal-aware dynamic reprioritization, or arbitrary worker-side renderer/audio API use. |
loading/cache contract, ImageManager.cpp, idTech 5-level roadmap |
| Capability | Status | Scope and qualification | Evidence |
|---|---|---|---|
| Classic ARB2 interaction renderer | Implemented | This is the supported/default visible-lighting path and compatibility rollback for stock assets. | draw_arb2.cpp, renderer validation |
| Modern OpenGL scene packets/resources/render graph | Experimental | Scene packets, material/geometry tables, render-graph resources, upload rings, and a modern executor exist. They are opt-in infrastructure, not proof that a complete stock frame is modern-owned. | ScenePackets.cpp, MaterialResourceTable.cpp, GeometryResources.cpp, RenderGraph.cpp, ModernGLExecutor.cpp |
| Modern visible lighting ownership | Experimental | Separate shared classic interaction and fog/blend ownership now exists for complete eligible root-view domains, a provenance-tagged in-world GUI subset has its own depth-aware transaction, and a special-subview transaction seals direct SS_SUBVIEW mirrors plus eligible remote-camera, mirror, reflection, refraction, and x-ray child-view/capture edges, including exact 2D/cubemap color/depth target aspect and face. Eligible nested special-view trees seal parent/root/depth records, retain depth-first command order, and publish only after their outermost special view completes; a rejected member rolls back the complete tree. Cinematic/authored-post and render-demo/Raven special-frame transactions seal other eligible exceptional ranges. The material-deform dependency distinguishes finalized CPU output from generated/skinned geometry and lets those domains seal completed, intentional-empty, and classic source-preserving receiver roles. Unsupported or stale results still roll back atomically. This does not mark the older aggregate r_rendererModernVisible lighting contract proven. |
Shared Classic Interaction-Lighting Domain, Shared Classic Fog/Blend Domain, Shared Classic In-World GUI Domain, Shared Special-Subview Transaction, Shared Classic Cinematic and Authored-Post Transaction, Shared Render-Demo and Raven Special-Frame Transaction, Shared Classic Material-Deform Contract, Modern visible-lighting ownership, renderer validation |
| Shared fixed-function 2D GUI ownership | Implemented (default-off; release promotion pending) | r_rendererSharedGui promotes only a complete eligible root 2D view. The material table preserves repeated stages and opaque image identities, the shared domain evaluates register-driven condition/color/matrix/state once per draw, and GL/Vulkan preflight the full view before submitting it. Any unsupported surface, material, state, resource, target, or backend condition executes the untouched classic view. This is scoped GUI ownership, not modern world-lighting ownership. |
Shared Classic 2D GUI Domain, ClassicGuiDomain.cpp, renderer_classic_gui_domain.py |
| Shared in-world GUI ownership | Implemented (default-off; release promotion pending) | r_rendererSharedInWorldGui promotes only the complete provenance-tagged GUI subset emitted by R_RenderGuiSurf for an eligible ordinary 3D view. Its world-category packet stream compiles ordered fixed-function passes with the established 3D depth semantics; GL/Vulkan preflight the complete tagged subset before the ambient walks, and only a recorded owned subset is removed from the matching classic walker. Any unsupported source, packet, material, resource, target, capacity, or backend condition keeps every tagged GUI surface on the untouched classic path. |
Shared Classic In-World GUI Domain, ClassicGuiDomain.cpp, renderer_classic_gui_domain.py |
| Shared classic world ambient/material ownership | Implemented (default-off; controlled local validation passed) | r_rendererSharedWorldAmbient promotes only a complete eligible ambient-only 3D world view. Packet-derived surface/fixed passes preserve ordered evaluated state, opaque/perforated draws require matching established depth packets, and GL/Vulkan preflight the full pre-fog/post-fog plan before committing. Stock maps/tools/mv2 GL/Vulkan captures prove exact option-off/on output and named zero-draw deform fallback. Any non-owned pass, unsupported source/material/resource, missing depth prerequisite, or backend rejection executes the untouched complete classic ambient view; clean-package/platform promotion remains open. |
Shared Classic World Ambient/Material Domain, ClassicWorldAmbientDomain.cpp, renderer_classic_world_ambient_domain.py |
| Shared classic interaction-lighting ownership | Implemented (default-off; controlled local validation passed) | r_rendererSharedWorldInteraction promotes only a complete eligible fixed-classic interaction view. Explicit packet identities and bounded records seal all interaction primitives plus classic stencil volumes, projected single-map and CSM/parallel shadows, point cubes, mixed mapped/stencil lights, complete hybrid supplements, dynamic mapped casters, and perforated alpha stages. GL and Vulkan retain complete plans before visible ownership and reconcile exact coverage. Unsupported work executes the untouched complete classic interaction walker. The controlled five-case GL/Vulkan profile has same-backend classic image parity, visible shadow deltas, and named atomic fallback evidence; stock fixed-camera, clean-package, and platform promotion remain open. |
Shared Classic Interaction-Lighting Domain, ClassicInteractionDomain.cpp, renderer_classic_interaction_domain.py, renderer_vulkan_shadow_compatibility.py |
| Shared classic fog/blend ownership | Implemented (default-off; controlled local validation passed) | r_rendererSharedWorldFogBlend promotes only the complete fog/blend phase of an eligible ordinary root 3D view. One bounded transaction preserves original light and receiver order, every active/inactive blend stage, fog receiver/cap work, evaluated state, images, and exact coverage. GL and Vulkan preflight the whole phase; unsupported work executes the untouched classic walker. The controlled suite passes exact same-backend classic parity, nonempty ownership, visible fog/blend deltas, and atomic rollback on both backends; authored-stock fog and clean-package/platform promotion remain open. |
Shared Classic Fog/Blend Domain, ClassicFogBlendDomain.cpp, renderer_classic_fog_blend_domain.py |
| Shared special-subview transaction | Implemented (default-off; controlled nested GL/Vulkan fixture passed; broader release qualification pending) | r_rendererSharedSubview seals direct mirror camera/clip/scissor semantics and exact parent/child 2D or cubemap color/depth capture records for eligible remote-camera, mirror, reflection, refraction, and x-ray views. Eligible trees seal parent/root/depth and depth-first order; ownership remains unpublished until all child work and capture/direct edges finish. The final R6 acceptance proves one capture-backed color-2D mirror coupled to a nested cinematic plus _currentRender tail, including exact parity, ownership, and atomic named fallback on Windows GL/Vulkan. Direct mirrors, multi-level nested-subview chains, the other capture kinds/aspects/faces, _currentDepth, final-package, and platform/driver breadth remain unqualified. |
Shared Special-Subview Transaction, ClassicSubviewDomain.cpp, renderer_classic_subview_domain.py |
| Shared classic cinematic and authored-post ownership | Implemented (default-off; controlled nested GL/Vulkan fixture passed; broader release qualification pending) | r_rendererSharedCinematicPost admits only a complete eligible root 2D video/audio view or complete ordered post tail. Scene packets reconcile source identity/order and retain the cinematic clock plus _currentRender/_currentDepth diagnostics. The final R6 acceptance proves one cinematic plus _currentRender post tail inside one capture-backed mirror on Windows GL/Vulkan, with exact parity and bidirectional atomic fallback. Root cinematic, ordinary-root post, _currentDepth, broader special-view, final-package, and platform/driver qualification remain open. OpenGL and Vulkan retain their mature decoder, feedback, and custom-program executors. |
Shared Classic Cinematic and Authored-Post Transaction, ClassicCinematicPostDomain.cpp, renderer_classic_cinematic_post_domain.py |
| Shared render-demo and Raven special-frame ownership | Implemented (default-off; implementation evidence recorded; release promotion pending) | r_rendererSharedSpecialFrame admits only a complete ordinary root 3D view identified by the active render-demo session stream, or an exact normal-root Raven special-effects controller with a nonempty blur/AL mask. OpenGL and Vulkan dispatch the complete established executors and report ownership only after exact coverage; incomplete session, source, packet, resolve, effect, or backend state preserves the classic path. Runtime breadth, clean-package, and platform qualification remain open. |
Shared Render-Demo and Raven Special-Frame Transaction, ClassicSpecialFrameDomain.cpp, renderer_classic_special_frame_domain.py |
| Shared classic material-deform dependency | Implemented (default-off; controlled local validation passed) | r_rendererSharedDeform authorizes the shared classic domains to consume ordinary geometry published by the authoritative CPU material-deform path. Per-draw records seal source/result geometry, cache lifetime, evaluated inputs, freshness, consumer role, outcome, and semantic hash. Particle/particle2, skip/failure, stale cache, or provenance mismatch rejects the complete owning transaction. The controlled GL/Vulkan suite passes exact classic parity, nonzero completed ownership, visible deform delta, and named zero-commit rollback; clean-package and platform promotion remain open. |
Shared Classic Material-Deform Contract, ClassicDeformDomain.cpp, renderer_classic_deform_domain.py |
| GPU-driven GL submission / clustered Forward+ | Experimental | SSBO/compute/MDI, clustered-lighting, Hi-Z, and persistent/DSA paths exist at capable tiers, but remain opt-in and depend on the incomplete modern-visible path. | ModernClusteredLighting.cpp, ModernGLSubmitPlan.cpp, ModernGLExecutor.cpp |
| Vulkan renderer | Stable on Windows x64 (supported opt-in; signed off 2026-10-04); experimental on Linux and macOS | Stock world and model materials (including the stock ARB/GLSL program families), interaction lighting, stencil and mapped shadows, fog/blend lights, decals, GUIs, ROQ cinematics, MD5R, SMAA/MSAA, and the opt-in TAA, screen-space-lighting, and GPU-skinning leaves reach validation-clean gameplay on the Windows NVIDIA development machine, where the recorded runs were faster than OpenGL. Its final display mapping applies brightness/gamma once, after the whole frame, as OpenGL does. Since 2026-09-18 it also has the CRT back-buffer pass, baked light-grid indirect light, soft particles, MSAA alpha-to-coverage, the classic SSAO/bloom/HDR-tone-map/motion-blur chain, multiplayer player-visibility overlays, cel shading, the underwater view, and the r_show*/debug-draw tooling (vk_PostProcess.cpp, vk_SceneEffects.cpp, vk_DebugTools.cpp), each compared against OpenGL captures under the validation layers. It stays non-default: complete modern PBR/probe parity remains incomplete, and only Windows has real-hardware evidence. Authored material programs run: GLSL ambient and per-light paths compile actual source pairs, respect stock-name overrides and pass local live-edit, failed-source repair and restart controls, and ARB assembly material programs are translated to GLSL, with all 15 laboratory controls within one display level of OpenGL's native ARB execution. Authored 2D lookups flip for render targets Vulkan stores top-down. r_showShadows, r_enhancedMaterials, the renderer-owned r_resolutionScaleMode 2/3 upscales and translucent moment shadows (r_shadowMapTranslucentMoments, a frame-boundary moment atlas whose blocks mirror the depth-atlas blocks) match OpenGL; in a moment laboratory scene the moment contribution agrees with OpenGL within one display level for 95% of the affected pixels on both the NVIDIA and the Intel GPU. All 29 stock single-player maps load and draw their opening view, 20 stock multiplayer maps host bot matches, and a 25-minute 16-load soak runs, validation-clean on the RTX 4060 and on Intel Iris Xe graphics (driver 101.5590), with no warning OpenGL does not also log; the Intel run found and fixed pipeline sample locations used without variableSampleLocations. Custom lighting binds per-light semantics and uses receiver-specific retail stencil fallback when mapped shadows are requested; full-scene shadow parity and broader shader/state coverage remain open. Vulkan now has an explicit RGBA16F scene and automatic exposure, with backend-owned MSAA color/depth resolves and screenshot/restart lifetime handling. Stock SP/MP 0x/4x and GPU fixture tests pass locally on v63; The stock highlight/portal-sky repair passes production tone-map and sky-mask GPU fixtures, frozen GL/Vulkan controls, and all four SP/MP HDR/MSAA lifecycle cases; broader controlled visual parity remains open. See Vulkan HDR. Cubemap faces, depth-only targets, and up to five color attachments (bounded by the device limit) now have validation-clean GPU draw/readback coverage, including mixed formats, blend masks, resumed scopes, all-attachment MSAA resolves, resize, selected-face restoration, and shared 2D depth attachments. Loading/device-probe failures and window, surface, swapchain or mandatory-resource startup failures recover to OpenGL in the same process. Startup owner teardown finishes before the failed module unloads; the requested Vulkan preference and original log survive. A lost device during play queues an automatic renderer restart (three per session, r_vkPresentationRecoveries) before the next-launch OpenGL recovery; a lost surface is rebuilt in place; a strict swap interval that loses its present mode presents with FIFO instead of stopping; minimized windows no longer idle the device every frame; live resizes keep the render size in step; and shadow-resource resizes never retire images under a recording frame. A later full vid_restart device failure still selects OpenGL for the next launch. Renderer ABI v14 requires matching engine and renderer modules. Linux x64/ARM64 push and ARM64 pull-request jobs run mandatory lavapipe startup, render-target, recovery and fallback tests, and pass. Physical GPU/platform qualification, the promotion gate and sign-off, five-run comparisons, and user soak remain open in the gap-closure ledger. SMP is not a gap, because OpenGL has no live SMP path either. |
What Vulkan does not do yet, vk_Backend.cpp, renderer_vulkan_world_interaction_compatibility.py, renderer_vulkan_shadow_compatibility.py |
| Backend-neutral whole-frame GPU timing | Implemented | OpenGL uses a delayed four-slot timestamp ring and Vulkan resolves per-slot timestamps only after its existing frame fence retires. Renderer ABI v11 exposes one common microsecond sample with backend/frame/generation identity and cumulative availability, drop, and reset diagnostics; map/device/context discontinuities invalidate old generations. Benchmark capture pairs unique valid GPU frames with high-resolution whole-renderer CPU samples without current-frame query waits. | GpuFrameTimingCore.h, RendererMetrics.cpp, VulkanGpuFrameTiming.cpp, renderer_gpu_frame_timing.py |
| Replay-verifiable per-map CPU/GPU budgets | Implemented (locally validated; release promotion pending) | A versioned contract selects exact map/backend/profile rows, requires independent CPU/GPU samples and percentiles, and fails closed on missing GPU timing, identity drift, threshold failure, changed contracts/runtimes/artifacts, or replay mismatch. Promotion captures also bind an exact bordered-window 1280x720 display contract so archived settings cannot change the measured workload. Gameplay reports can bind either GL or Vulkan; the fixed retail baseline binds OpenGL SP plus pure, auto-joined MP roles. A schema-10 four-role stock capture and replay pass, current-build storage/campaign evidence exercises both timing backends, and the final immutable development runtime passes and replay-verifies all eight OpenGL and all eight Vulkan required-profile cases. Clean committed-source and final-package capture plus platform/driver qualification remain open. The v1 20/28 ms values are initial target ceilings, not universal performance claims. | renderer_per_map_budgets.json, renderer_budget_contract.py, renderer validation, retail baseline |
| Shadow maps | Experimental | Projected/point maps, CSM, cutout handling, caching, debug views, and stencil fallback exist. The compiled r_useShadowMap default stays off; the quality and ultra performance presets enable it, and projected lights default to PCSS-lite filtering (r_shadowMapFilterMode 2, radius 2.0). Vulkan now degrades a receiver to unshadowed direct lighting for a frame if both mapped and stencil ownership fail, avoiding whole-light pop-out while retaining a diagnostic and sticky stencil recovery. |
Shadow mapping, Interaction.cpp, renderer_gameplay_benchmark.py |
| Baked light grids | Experimental | Bake, packed atlas, visibility/distance moments, portal-aware sampling, streaming controls, and worker-assisted baking exist. They require generated per-map data and are not a stock-asset default. | Light grids, RenderWorld_lightgrid.cpp, draw_common.cpp |
| SMAA post-process anti-aliasing | Implemented | Supported post-AA path for current renderers; it remains the compatibility/low-cost choice for future temporal work. | draw_common.cpp, material_smaa_edge.frag |
| Internal HDR scene/post chain and bloom | Experimental | Floating-point scene/post, exposure, tone mapping, bloom, and color controls exist, but modern-visible handoff and complete parity qualification constrain the path. This is not true HDR display output. | draw_common.cpp, display settings |
| True HDR display output (scRGB/HDR10) | Missing | Swapchain/window colorspace negotiation, paper-white UI composition, HDR screenshots, and platform qualification are not implemented. | VulkanDevice.cpp, display settings |
| GPU skeletal skinning | Experimental (implemented, default-off; 2026-10-06 measurement: not beneficial for stock content) | r_gpuSkinning admits only exactly representable four-weight MD5/MD5R surfaces. Dedicated full-precision skin attributes and canonical 12-float joint palettes feed bounded OpenGL/Vulkan compute paths which emit the ordinary idDrawVert ABI for depth, ambient, interactions, subviews, view models, and shadow maps. CPU positions remain current for collision, hits, decals, overlays, and software consumers; stencil volumes and every invalid/capability/allocation case use complete CPU fallback. Vulkan defers admitted surfaces without a CPU basis and repairs only refused ones; sidecars are validated once at load. Stock maps skin about 1,500 vertices per frame (about 15 microseconds of CPU), so the 2026-10-06 strict pairs could not show a whole-frame win; promotion would need batched OpenGL dispatches, persistent per-mesh source buffers and an animation-heavy workload. |
GPU animation contract, GpuSkinning.cpp, GpuSkinningGL.cpp, vk_GuiExecutor.cpp |
| Temporal AA / temporal upscaling | Implemented (automatic below native resolution by default since 2026-10-06; native-resolution TAA opt-in) | Native-resolution ping-pong history, camera/depth reprojection, capture/cut invalidation and native UI composition on OpenGL and Vulkan. The velocity pass owns every moving surface per pixel: exact vectors for rigid entities, for skinned MD5 surfaces from each vertex's previous model-space position, and for the first-person weapon through its own depth-hack projection; particles, effects, GUIs, subviews and translucent moving geometry mark per-pixel reactive coverage instead of whole screen regions. The resolve clips a Catmull-Rom history to a YCoCg variance box, takes velocity from the nearest depth, and presents with contrast-adaptive sharpening that is never fed back into the history. r_temporalAA 2 (default) upscales whenever the 3D scene renders below native resolution with a smooth scale mode or dynamic resolution, and stays off at native resolution, on OpenGL ES and without GLSL 1.30; r_temporalAA 0 retains SMAA. Local Windows GL/Vulkan (validation-clean) game/airdefense1 captures show complete ownership with no missed surface; clean-package and platform/driver qualification remain open. Temporal presentation, TemporalPresentation.cpp, renderer_temporal_presentation.py |
|
| Automatic dynamic resolution | Experimental (implemented, default-off; release promotion pending) | r_rendererDynamicResolution 1 consumes delayed generation-bound whole-frame GPU timestamps without a current-frame wait, applies bounded aligned drops and hysteretic recovery, and feeds the shared native-history TAAU path. Unsupported/stale timing stays at the configured safe ceiling; captures freeze or explicitly force native scale without contaminating timing/history; fixed r_screenFraction remains available. Local Windows OpenGL/Vulkan gameplay exercised forced scale drops; broader hardware and release-package qualification remain open. |
Temporal presentation, TemporalPresentation.cpp, renderer_gpu_frame_timing.py |
| Namespaced PBR materials and IBL/specular probes | Implemented (PBR materials default-on; authored probes default-off; OpenGL and Vulkan qualified on Windows and Linux Mesa) | Since the production-readiness plan the classic OpenGL light loop (draw_pbr.cpp) and native Vulkan own every admitted PBR surface in ordinary gameplay, every light keeping its shadows; stock materials are never PBR and a frame without a PBR material skips all PBR preparation. Roughness, metalness and AO reach every term (multiple-scattering energy compensation, specular, horizon and multi-bounce occlusion); irradiance is calibrated to the classic light term and each draw composes into the display-referred frame. Authored ambient lights act as uniform environments, baked light grids and opt-in authored probes (r_rendererReflectionProbes) light PBR on both backends, and SSAO occludes only indirect light. Paired OpenGL/Vulkan laboratory suites qualify every channel and term on Windows (NVIDIA; Vulkan also on Intel) and on Linux Mesa (llvmpipe and lavapipe). Animated and MD5R-converted models are PBR on both backends; probes can be box-projected (boxParallax) and captured in the engine (bakeReflectionProbes); an OpenGL context without GLSL 1.30, such as macOS's GL 2.1, keeps PBR materials classic. Review on Mac hardware is pending. |
PBR materials guide, draw_pbr.cpp, PBR material plan, Material.cpp, MaterialResourceTable.cpp, ModernSpecularProbeAtlas.cpp, ModernGLShaderLibrary.cpp, vk_Interactions.cpp, renderer validation |
| Clustered decals and reflection probes | Experimental (implemented for OpenGL, default-off; local contract gate passed; broader visual/release qualification pending) | Authored specular probes share the bounded clustered-light grid through at most 32 records and deterministic top-two-per-cluster indices backed by an eight-cubemap atlas. Eligible clustered decals use an atomic prepare/seal ownership transaction capped at 1,024 records and 65,536 cluster references; malformed, stale, incomplete, or overflowing input publishes no ownership, so the complete affected subset remains classic. Dependency-light and engine contracts pass locally, but no broad authored probe/decal scene or RenderDoc coverage is claimed. Clustered decals are an OpenGL modern-path routing transaction whose forward+ decal mode outputs the decal texel times its baked color, the classic decal result; Vulkan draws decals natively and has nothing to route. Native Vulkan authored probes are now connected and undergoing qualification. Both domains require their separate default-off leaf cvars plus r_rendererModernQuality and do not promote GPU-driven visible lighting: MODERN_LIGHTING_PARITY_PROVEN_DOMAINS remains 0. Final committed-package, platform/driver, retained visual review, and release promotion remain pending. |
ModernClusteredLighting.cpp, ModernSpecularProbeAtlas.cpp, renderer validation |
| Froxel volumetrics, SSR, and SSGI | Experimental (implemented as independent default-off GL/Vulkan leaves; release promotion pending) | The shared native scene-presentation tail consumes resolved scene colour/depth and bounds work to 16 view-depth froxel slices, 16 depth-normal reflection steps, and eight depth-derived diffuse-GI taps. Each leaf can run alone or with TAA; effect-only presentation does not allocate temporal histories, captures retain current-frame effects, and missing resources keep the established current/classic presentation path. r_rendererModernQuality 0 publishes an exact zero-feature packet even when archived leaves remain on. These are explicitly screen-space approximations: there is no shadowed per-light volumetric injection, material-roughness/G-buffer SSR, off-screen reflection recovery, or world-space/multi-bounce GI claim. Current-source native/static checks, individual/combined windowed OpenGL gameplay, and combined validation-clean Vulkan gameplay pass locally; clean-package, platform/driver, and retained visual promotion remain open. |
Advanced screen-space lighting, AdvancedScreenSpaceCore.h, draw_common.cpp, temporal_resolve.frag, renderer validation |
| Backend-neutral renderer contracts | Implemented (scoped Milestone D consumers; broader modern-renderer use pending) | Pure authored and evaluated material/pass records retain repeated stages, bounded register evaluation, inactive/no-op disposition, state semantics, and fail-closed atomic evaluation. The implemented consumers cover eligible root GUI, world ambient, interaction, fog/blend, provenance-tagged in-world GUI, special-subview, cinematic/authored-post, render-demo/Raven special-frame, and material-deform work. Special-view and nested cinematic/post records share exact root/depth identity, defer publication together, and roll the complete tree back on either-domain rejection. Shared clip/viewport conversion, semantic layouts, and typed generational buffer slices retain dependency-light coverage. The domains remain default-off with clean-package/platform promotion gates. | Shared Classic 2D GUI Domain, Shared Classic In-World GUI Domain, Shared Classic World Ambient/Material Domain, Shared Classic Interaction-Lighting Domain, Shared Classic Fog/Blend Domain, Shared Special-Subview Transaction, Shared Classic Cinematic and Authored-Post Transaction, Shared Render-Demo and Raven Special-Frame Transaction, Shared Classic Material-Deform Contract, GPU animation contract, RendererContracts.h, RendererContractsTest.cpp |
The Android/GLES additions below were reviewed on 2026-09-08 and originate in Emile Belanger's port. They remain experimental independently of desktop renderer qualification.
| Capability | Status | Scope and qualification | Evidence |
|---|---|---|---|
| SDL3 platform foundation | Implemented | Shared SDL3 window/display/input infrastructure is integrated with platform-specific bridges where required. Platform qualification is tracked separately below. | sdl3_backend.cpp, SDL3 migration |
| Android ARM64 client and SP/MP modules | Experimental | Meson/NDK API 24+ native port and standalone SDLActivity host. Native cross-build/export/alignment checks pass; device lifecycle, gameplay and input qualification remain open. | Android build guide, integration evidence and credit |
| OpenGL ES 3.0 renderer | Experimental | Optional desktop module and Android default; specialized GLSL shaders, stencil shadows, ETC2/EAC images and mobile presentation. Temporal resolve, CRT, some desktop post effects and immediate debug drawing are outside the implemented scope. | Android/GLES integration |
| SigmaTouch host bridge | Experimental | Optional adapter from emileb's GPLv3 fork, with synchronized command/analog input and overlay restoration. External host libraries are excluded and require compatible licensing; complete host/device qualification remains open. | Host integration and licence boundary |
| Windows x64 client/server | Implemented | Primary build/package target with staged client, dedicated server, renderer modules, and game modules. | meson_setup.ps1, platform-support.md |
| Linux x64 client/server | Implemented | Native builds, Wayland/X11 paths, packaging, and physical-host stock SP/dedicated evidence exist. | platform-support.md, linux_wayland_stock_sp_smoke.py |
| macOS (Apple Silicon) client/server | Implemented (preview support tier) | Native arm64 CI builds, packages, and starts both package variants and the dedicated server on every push, and players have run stock SP and MP with audio on macOS 26. Packages are unsigned, and older macOS releases down to the macOS 11 floor, the Metal bridge package, controllers, and the stock-map dedicated server have no real-hardware evidence. Intel and universal2 builds are CI-only. |
Support tiers, community hardware reports, macOS workflow, macos_matrix_policy.py |
| Linux ARM64 client/server | Implemented (preview support tier) | Native ARM64 CI builds and packages the client, starts it under Weston and Xvfb, and runs the dedicated server; an x64-hosted cross-build checks the ABI. The physical-hardware signoff record is still pending. | linux_arm64_release_evidence.py, platform-support.md |
| Windows ARM64 client/server | Experimental | Native windows-11-arm CI builds and stages it on every push and pull request and starts the dedicated server without game data through the staged arm64 MP module; the release workflow builds and package-validates it. The client has never been started by automation, and no real-hardware report exists. |
Support tiers, windows_dedicated_server_smoke.py |
| OpenAL spatial audio, streaming, HRTF, and EFX | Implemented | The OpenAL backend includes streaming voices, device recovery, HRTF controls, EFX routing, and diagnostics. Retail Quake 4's per-area EAX reverb (efxs/*.efx, maps/*.reverb, four portal-tracking slots, EAX occlusion) runs on EFX; see retail-audio-reverb.md. Provider/feature availability remains platform/device-dependent. |
AL_SoundHardware.cpp, AL_SoundVoice.cpp, macos_openal_provider_policy.py |
| IPv4/IPv6 transport and LAN discovery | Implemented | Dual-stack UDP, IPv6 literals/zones, DNS, fragmentation policy, and IPv6 multicast LAN discovery exist with self-tests. | Multiplayer networking, network_ipv4_support.py, network_ipv6_support.py |
| Prediction and lag compensation | Implemented | Client prediction and opt-in server rewind/lag compensation exist; gameplay defaults and tuning remain game-mode policy. | Multiplayer networking, AsyncNetwork.cpp |
| Voice chat | Missing | A disabled game-side capture/playback skeleton exists, but reliable transport, codec, user controls, moderation, and production validation do not. | Multiplayer networking |
“Implemented” is not shorthand for “release-qualified everywhere.” Renderer default promotion still requires the full evidence token defined by the renderer validation matrix, including clean warnings, visual/gameplay/RenderDoc/performance/presentation/rollback passes with debug features off. Retail-asset compatibility changes additionally require a passing retail-PK4 compatibility baseline plus the manual review gates recorded with that bundle.