openQ4 Platform And Architecture Roadmap
September 18, 2026 ยท View on GitHub
This document defines the long-term platform direction for openQ4 and how SDL3 + Meson are used to get there.
Target End State
- First-class support on modern desktop operating systems:
- Windows
- Linux
- macOS, currently a preview until the first-class criteria below are met
- First-class support for modern 64-bit desktop architecture:
- x64 (
x86_64) - arm64 (
aarch64)
- x64 (
- Keep original Quake 4 gameplay/module behavior compatible while modernizing platform and build layers.
Support Tiers
Reviewed 2026-09-18. This table is the source of truth for how each published package target is described. User-facing docs, the packaged README, issue templates, and release notes must not claim more than the tier recorded here.
| Target | Tier | What the tier rests on | What moves it up |
|---|---|---|---|
| Windows x64 | First-class | Primary development target: built and packaged on every push, and played on real hardware during development and release qualification. | - |
| Linux x64, Steam Deck/SteamOS | First-class | Built and packaged on every push; pull-request and release jobs start the client under native Wayland and X11, and the stock SP/MP and dedicated-server runs are recorded below. | - |
| macOS, Apple Silicon (arm64) | Preview | Native arm64 CI builds and packages both variants and starts both variants plus the dedicated server on every push and pull request. Players on Apple Silicon Macs running macOS 26 have played stock single-player and multiplayer, with audio, on 0.12.0 and 0.13.1 (issues #98 and #122). Packages are unsigned, and nothing older than the current macOS has been played on. | Signed and notarized DMGs, plus accepted signoff on the macOS 11 floor and the latest public macOS in the macOS signoff evidence index. |
Linux ARM64 (aarch64) | Preview | Native ARM64 CI builds and packages the client, starts it under Weston and Xvfb, and runs the dedicated server on every push and pull request. Raspberry Pi 5 reports found a save-restore crash that was fixed (#78); no hardware report covers a current release. | The accepted physical-hardware record in the Linux ARM64 evidence record. |
| Windows ARM64 | Experimental | Native windows-11-arm CI builds and stages it on every push and pull request and starts the dedicated server without game data; the release workflow builds and validates the package. The client has never been started by automation, and no real-hardware report exists. | A real-hardware SP/MP report. |
macOS, Intel (x86_64) and universal2 | Not published | CI compiles, stages, and starts both, and one Intel iMac source build that crashed at launch runs as of 0.10.0 (#90). No package is published. | A release-lane decision and the matrix expansion evidence in the macOS support matrix policy. |
What the tiers mean:
- First-class: the platform is a primary target, and a regression on it blocks a release.
- Preview: every commit is built, packaged, and started on native-architecture CI runners, and the stock game has been played on real hardware for that target, but the formal signoff the first-class gate asks for is missing. Downloads are labeled as previews and the documented limitations travel with them. A preview drops back to experimental if a current release cannot reach SP or MP gameplay on real hardware.
- Experimental: packages are built, but nothing yet shows that they run. Expect failures, and report them.
The real-hardware evidence here is community reporting on GitHub issues, not the accepted signoff archives the first-class gates require. Reports from other channels can move a target once they are recorded in the matching evidence document.
Renderer backends are tiered separately from platforms. OpenGL is the supported renderer on every platform. The Vulkan renderer is experimental on every platform, macOS included; the "Vulkan renderer" row of the engine capability matrix records why, and Display Settings lists the OpenGL features it does not have yet.
Current Baseline (v0.13.x release line)
- Published releases are currently on the
v0.13.xline. The version inmeson.buildis the release floor consumed by the release-version helper (seeBUILDING.md); builds that do not pinversion_base_overrideraise that floor to the newest publishedv*tag, so a development build reports the release line it was branched from rather than a version that never shipped. - Primary actively validated build targets: Windows x64, Linux x64, preview Linux ARM64 build/package plus assetless compositor startup, and preview macOS arm64 build/package plus assetless renderer and dedicated-server startup. Linux ARM64 real-hardware SP/MP gameplay, dedicated-server, audio, input, and package signoff is still required before claiming complete runtime support. The manual release workflow defaults to
linux_arm64_support_tier=preview;first-classpublication is blocked until the Linux ARM64 evidence record is accepted and machine-bound to the exact source pair, release identity, archive, and four packaged runtime ELFs. - Windows ARM64 is experimental. Push and pull-request CI build it natively on a
windows-11-armrunner, stage it, and runtools/tests/windows_dedicated_server_smoke.py, which confirms that the dedicated server, the MP module, andOpenAL32.dllare arm64 images, then starts the server without game data, provesgame_mpinitialization and a live server frame, and requires a clean game shutdown. The Windows x64 jobs run the same smoke. Those lanes use the debug push and pull-request profiles; the manual release workflow builds the optimized package on the same runner type and validates the staged binaries, PDBs, and OpenAL runtime, but does not start them. The client has never been started by automation, and no real-hardware report has confirmed that the packages run. Stock Windows on Arm may lack a full OpenGL driver, so the Vulkan renderer (r_renderApi vulkan) is the first fallback to try. Its release assets carry no tier suffix, so every front-door mention and the release notes must say experimental. - Preview manual macOS release artifacts are Apple Silicon/arm64 only. The macOS support matrix policy is recorded in
docs/dev/macos-support-matrix-policy.md: current user-facing releases arearm64 only, Intel Mac/x86_64, universal2, and Rosetta compatibility are not supported release targets, and the documented OS floor remainsmacOS 11until changed in Meson, package metadata, docs, workflows, and evidence together. Credentialed release runs publish signed/notarized DMGs; runs without Apple Developer ID signing and notarization credentials publish clearly labeled unsigned/unnotarized-unsigned.tar.gzarchives. The manual release workflow defaults tomacos_support_tier=preview;macos_support_tier=first-classis a hard gate that requires signed/notarized DMGs and fails when Apple signing/notary secrets are missing. Dedicatedmacos-15-intelengine and companion jobs now provide experimental x86_64 compile, staging, thin-slice, assetless renderer, and dedicated MP-module-loader checks for both bridge variants, but no Intel package or compatibility claim is made until real Intel gameplay, package, and signing evidence exists. Intel Mac and universal2 packages are intentionally not claimed by the current release matrix. - Build system: Meson + Ninja.
- Dependency model: Meson subprojects/wraps.
- Platform backend direction: SDL3-first (legacy Win32 backend is transitional only).
- Language baseline target: C++23 semantics (
vc++lateston current MSVC Meson front-end). - Toolchain baseline direction: MSVC 19.46+ (Visual Studio 2026 generation), with compatibility fallback permitted during migration.
- As of March 30, 2026, Linux and macOS default to the SDL3 backend and keep
-Dplatform_backend=nativeas a fallback/comparison path. On macOS,platform_backend=nativeis comparison-only diagnostic infrastructure and is not a supported release backend. - Steam Deck and SteamOS support is delivered through the explicit
openQ4-steamdecklauncher/profile, plus direct-client host auto-detection whencom_platformProfileis stilldefault. - Native Wayland is supported through the SDL3 backend. The bundled SDL fallback dynamically loads Wayland, optional libdecor, and PipeWire support, enables the DBus Fcitx and optional IBus IME paths, and has a
-Dlinux_x11=disabledWayland/EGL-only build mode. PipeWire development headers remain a build requirement, but the finished client can start without the PipeWire runtime; openQ4's game-audio path remains owned by OpenAL. Text input is active only while a console or GUI field can consume it, while the native IBus/Fcitx UI owns composition and candidate presentation using the text-input area supplied by the game. Quake 4's stock edit widgets and bitmap fonts remain single-byte; committed codepoints outside that asset-supported range are ignored rather than narrowed into corrupt characters. The shared SDL3 path logs the selected video driver, active Wayland hints, display content scale, orientation, current/desktop display modes, exact refresh details when SDL reports them, and compositor-accepted window state after screen changes; applies Wayland-aware defaults; avoids persisting compositor-owned window positions; keeps relative mouse-look usable when pointer confinement is unavailable; synchronizes compositor-negotiated size/fullscreen changes before refreshing renderer placement; and tries SDL's unversioned OpenGL compatibility fallback first whenr_glTierisautoon native Wayland. CI exercises assetless native-Wayland SDL3 window lifecycle, relative mouse-capture, and display-diagnostics cases under Weston on x64 and ARM64, including fullscreen/windowedvid_restarttransitions, real libdecor load/opt-out assertions, a direct-X11/GLX dependency rejection lane, and the optional blocking window-operation synchronization path. - Fresh Linux x64 native-Wayland stock-asset validation has entered
game/airdefense1and a two-processmp/q4dm1loopback session, captured valid active-gameplay frames, matched the multiplayer declaration checksum, and shut down cleanly. A packaged dedicated server has also loaded stockmp/q4dm1to post-load readiness while remaining headless, accepted and spawned a separately packaged native-Wayland client with the same checksum, captured its active view, and shut down both processes cleanly. That WSLg/Wayland software-rendering evidence complements hosted Weston CI; it does not replace physical GNOME/KWin/wlroots/SteamOS audio, input-device, suspend/resume, and display-transition coverage. - The opt-in
tools/tests/linux_wayland_stock_sp_smoke.pyrunner makes the stock SP case repeatable: it enforces host-matching client/module ELF files and a real Wayland socket, enables sound, entersgame/airdefense1, saves and reloads an isolated slot, proves a second active lifecycle, validates the save set and a nontrivial post-restore frame, and preserves hashes plus ordered logs. The stock SP and dedicated/client reports now record best-effort virtualization/container inspection, and a claimed physical run fails if a known VM/emulator is detected; the operator attestation remains necessary because software cannot prove bare metal. First-class evidence schema 2 binds both exact report blobs and validates their generated identity, native ARM64/Wayland/physical state, passing lifecycle, and candidate binary hashes before release. The current x64 WSLg run passed native-Wayland rendering, OpenAL/software sound initialization, save/load, and clean shutdown. Software initialization does not mean that automation heard audio; human audible-playback verification and physical-hardware attestation remain separate evidence fields, and neither the WSLg result nor hosted CI replaces physical ARM64 signoff. -Dlinux_x11=enabledand-Dlinux_x11=disabledforce the bundled SDL fallback so the requested Linux video-driver set is actually honored.-Dlinux_x11=automay use a suitable system SDL and leaves X11/XWayland availability to that dependency.- Linux ARM64 compiler-specific regressions are caught in the full engine before packaging: the native Wayland-only/libdecor-opt-out lane builds with Clang, while the native libdecor and dedicated-server lanes retain GCC coverage. A supplementary Ubuntu multiarch cross-build from x64 also compiles the client, dedicated server, and both game modules in Wayland-only mode. A complete x64-hosted run has produced all four AArch64 ELF artifacts and passed architecture, dependency, required PIE/RELRO/NOW/non-executable-stack hardening, distinct-module, and
GetGameAPIexport validation. Native ARM64 runners are authoritative for the current build/package and assetless window/input-startup checks; real-hardware native-Wayland audio, input, dedicated-server, and SP/MP gameplay remain required for release signoff. See Linux ARM64 cross-compilation and the first-class signoff evidence record. - The companion openQ4-game repository also supports standalone native Linux x64 and ARM64 Meson builds with GCC or Clang. Its CI builds distinct SP/MP
.somodules, rejects unresolved definitions at link time, limits the public ABI toGetGameAPI, and validates architecture, hardening, LP64 semantics, alignment, and deterministic checksum behavior; openQ4's staged companion-source build remains authoritative for integrated runtime, packaging, and gameplay validation. - Native Linux x64 and ARM64 CI require asset-free dedicated-server startup and clean shutdown through the staged multiplayer module. Dedicated builds use a separate headless source/link contract: they retain the integrated BSE declaration allocator and common engine behavior but do not directly depend on OpenAL, OpenGL/GLX, SDL, PipeWire, Wayland, or X11/Xext runtime libraries. They also skip splash/system-console video, client GUI preloading, loading wipes/screens, presentation updates, and uninitialized OpenGL vertex-cache teardown while preserving network pacifier updates during map changes. Staged and extracted-package validation fail closed unless both the dedicated executable and its loaded MP module depend only on the architecture-appropriate core C/C++/POSIX/compiler runtime set. The hosted smoke creates a test-only minimal
pak001.pk4, disables official-media validation, provesgame_mpinitialization, waits through a live server frame, and verifies error-free game shutdown; it is not a map/gameplay test. The separate opt-in stock-media harness additionally requires a post-load map-ready marker, a packaged client connection/spawn, matching checksums, ordered nonempty engine logs, active native-Wayland gameplay capture, no dedicated-side SDL/video markers, and clean exits; Linux x64 has passed that strongermp/q4dm1case, while real-hardware ARM64 execution remains pending. - SDL3 Linux VRAM autodetection can enumerate DRM card/render-node sysfs before legacy
/proc/drifallback, and native Wayland skips optional XNVCtrl/X11 probing, so native Wayland and minimal X11-free sessions are less dependent on optional X11 helpers. - SDL3 Linux and macOS desktop-resolution queries fall back from desktop mode to current mode and display bounds, improving startup robustness on compositors or display bridges that do not report a conventional desktop mode.
- Windows, Linux, and macOS SDL3 builds share the same
r_screen,r_multiScreen, fullscreen, exclusive-mode, borderless, windowed-placement, high-DPI drawable, display-change, selected-display spanned-UI viewport, and diagnostic display-list code paths. Native Wayland keeps compositor-owned placement semantics and falls back from multi-display spanning to the selected display when absolute placement is unavailable. The shared SDL3 renderer path also verifies a live, current OpenGL context before screen changes, swaps, deactivation, and teardown, validates extension lookups, uses overflow-safe selected-display viewport math, clamps malformed mouse movement, wheel, controller, and rumble values before integer conversion and event queuing, normalizes unusual app-entry argument state, guards POSIX clipboard/console command/input allocation, terminal and desktop-console cursor and scroll state, pthread setup and initialization state, requires error-checking mutex attributes before enabling critical sections, checks thread/event indexing, signal reporting, process handoff, and fatal-error/print formatting paths, and makes the macOS display selector fall back from requested display to main display to first active display before returning a null display id. - Windows, Linux, and macOS keyboard, mouse, and controller input are routed through the shared SDL3 backend. Linux and macOS explicitly keep SDL's HIDAPI controller stack, enhanced reports, hotplug events, rumble, battery diagnostics, gyro, touchpad, and touchscreen routing available at the same feature level as the Windows SDL3 path while preserving user/SDL environment overrides.
- XWayland remains available as an explicit fallback by setting
OPENQ4_FORCE_X11=1or an SDL video-driver override such asSDL_VIDEO_DRIVER=x11. - The Linux X11/Xvfb fallback lane also runs an SDL3 display-diagnostics smoke in CI so native Wayland and explicit X11 driver paths both prove display enumeration, scale/orientation reporting, and selected-display diagnostics.
- The project-level
OPENQ4_FORCE_X11=1fallback is runtime-validated separately from raw SDL driver overrides; CI launches the staged client under Xvfb with that flag and checks that SDL reports the X11 driver plus normal display diagnostics. - If a native Wayland compositor has decoration, resize, or window-control issues,
OPENQ4_WAYLAND_PREFER_LIBDECOR=1asks SDL to prefer libdecor without changing the default path for other sessions. - If libdecor itself causes startup or decoration issues on a compositor stack,
OPENQ4_WAYLAND_DISABLE_LIBDECOR=1asks SDL to keep libdecor disabled for that launch. - If a compositor applies window changes too asynchronously for diagnosis,
OPENQ4_WAYLAND_SYNC_WINDOW_OPS=1asks SDL to synchronize every window operation. Use it only as a troubleshooting option because some compositors may block during window animations. - Preview macOS arm64 release packages are built and validated in both OpenGL and Metal bridge variants, with
.appmetadata, executable bits, runtime dependency roots, and architecture-matched.dylibgame modules checked before release publication. The client is now a self-contained drag-installable app: openQ4 PK4 data lives inContents/Resources/baseoq4, signed SP/MP game dylibs live flat inContents/Frameworks, andopenQ4.appcan move independently to/Applications; loose client/server diagnostics discover the sibling app runtime without duplicating the large data payload. Credentialed runs add final compressed DMG creation,hdiutilimage verification, inside-out Developer ID signing, and app/DMG notarization/stapling. Release runs without Apple signing/notary credentials publish-unsigned.tar.gzarchives instead, ad-hoc signed only for bundle validity and clearly marked as unsigned/unnotarized. The current release line does not publish Intel Mac or universal2 artifacts; those remain future support-policy decisions rather than implied compatibility. The SDL3 release path links Cocoa/OpenGL/ApplicationServices and keeps the legacy Carbon framework isolated to-Dplatform_backend=native. The Metal bridge keeps the stock-compatible OpenGL renderer path, links Metal/QuartzCore for the SDL3/Cocoa host surface, applies the bridge define consistently across C/C++/Objective-C/Objective-C++ sources, logs failed SDL Metal hint setup, requires valid SDL window IDs before splash/system-console renderer creation, lets those support windows try the Metal/default renderer before falling back to software, and reports failed splash event requeues during startup/error UI draining. The renderer/backend policy is tracked indocs/dev/macos-renderer-backend-policy.md, and native backend containment is tracked indocs/dev/macos-native-backend-containment-policy.md: current-metalpackages are Metal bridge packages, not native Metal renderer packages. - macOS runtime recovery now separates window MSAA from offscreen target viability: game targets retry rejected multisample RGBA8 + depth/stencil FBOs down to single-sample, emit symbolic status/attachment diagnostics, and use the direct-render fallback rather than terminating. Apple GL 2.1 interaction mode
0now routes eligible stock surfaces through neutral GLSL 1.10 lighting and uses a client-memory-safe simple ARB fallback per surface; mode3preserves the previous ambient-only bypass only for emergency recovery. Finder-style app launches bind validatedContents/Resourcestofs_cdpathand load game code only from the trustedContents/Frameworksroot even when retail assets are discovered elsewhere. Hosted push jobs now require an assetless launch for both macOS bridge variants, and release jobs launch the app executable from an unrelated working directory. These checks improve regression coverage but do not replace real-hardware evidence. Community reports now cover stock SP and MP on Apple Silicon under macOS 26 (see the support tiers above); the accepted signoff for the macOS floor and the latest public macOS, plus display, input, audio device-switching, and Gatekeeper evidence, is still pending. - macOS platform-sensitive debugging now has a manual ASan+UBSan workflow for both OpenGL and Metal bridge variants. It disables PCH, instruments the client, dedicated server, and staged SP/MP game modules, verifies the resulting arm64 Mach-O files, runs an assetless fail-fast runtime probe, and retains toolchain/build/runtime diagnostics. This remains opt-in investigation coverage rather than release evidence and does not replace physical gameplay or package signoff.
- Native arm64 commit and push jobs now require asset-free macOS dedicated-server startup through the staged
game-mpmodule for both package bridge configurations. The smoke generates only a test marker PK4, disables official-media validation, proves game initialization plus a live server frame, and requires clean game shutdown; it is a hosted loader/lifecycle gate, not stock-map or real-hardware multiplayer signoff. - macOS release and validation builds now use a checksum-pinned OpenAL Soft 1.25.2 CoreAudio runtime through
-Dmacos_openal_provider=system. Packages embed the signed dylib underopenQ4.app/Contents/Frameworks, use package-relative loading, and include the LGPL notice plus exact corresponding source archive. Apple's buffer-limited OpenAL framework remains a compile-only compatibility diagnostic. Buffer allocation failure also degrades an affected sound instead of aborting a loaded map. The detailed provider and package policy is recorded indocs/dev/macos-openal-provider-policy.md. - macOS release signing uses the Hardened Runtime without custom entitlements by default. Optional entitlement files are validated as plist dictionaries and App Sandbox or
get-task-allowentitlements are rejected until the project has a reviewed sandbox/file-access design for user-selected Quake 4 assets, saves, logs, and staged runtime overlays. - The native macOS Cocoa/OpenGL fallback is experimental and kept crash-resistant for comparison testing: it now stores a valid CGL context pointer, validates pixel-format/context/window setup before use, releases created contexts if final make-current fails, fails cleanly when fullscreen display capture/mode/context setup cannot complete, unwinds partial display captures, treats missing or invalid-display VRAM telemetry as non-fatal, guards mouse capture, scroll-wheel overflow, nil event entry points, display/gamma-table, stack-free extension lookup, verified-current context swap/activation/pause/resume, and shutdown lifetime paths, returns deterministic unsupported status from legacy render-thread and screen-change stubs, uses the engine allocator for clipboard text, owns UTF-8 strings handed back from Cocoa key-name, clipboard, and fatal-error alert paths, keeps obsolete Carbon/Xcode-era macOS sources out of the Meson build manifest, and validates that live macOS backend sources do not reintroduce raw
strcpy/strcat/sprintf/allocastring builders. - Windows arm64 currently uses a custom OpenAL Soft package path during bring-up because the in-repo bundled Windows runtime payload is still x64-only.
macOS Support Matrix
- Current architecture policy:
arm64 onlyfor preview Apple Silicon/arm64 release packages. - Unsupported current macOS release targets: Intel Mac/
x86_64, universal2 packages, and Rosetta as a supported compatibility layer. - Current OS-version policy:
macOS 11is the documented Apple Silicon/arm64 package floor, while the latest public macOS release is the rolling current-version signoff target. - Hosted
macos-15CI builds prove configure, build, package, signing, notarization, and static validation paths; they do not replace real Apple-hardware runtime signoff for the macOS 11 floor or the latest public macOS release. - First-class macOS support requires completed OpenGL and Metal bridge evidence for both the documented floor and latest public macOS, with architecture policy, CPU architecture, OS matrix role, Xcode version, and macOS SDK version recorded in
docs/dev/macos-signoff-evidence.md. - Matrix expansion requirements are tracked in
docs/dev/macos-support-matrix-policy.mdanddocs/dev/plan/2026-06-30-macos-compatibility-support.md. - The bundled OpenAL Soft release provider exposes the backend's existing optional EFX, HRTF, output-mode, resampler, and device-recovery paths when the selected device supports them. Physical Apple-hardware audio has been confirmed audible on 0.13.1 (issue #122); device-switching and long-session signoff remain part of the first-class macOS support gate.
macOS Renderer And Backend Policy
- Current release renderer policy: both macOS package variants use the stock-compatible OpenGL renderer.
- Current package variants:
OpenGLandMetal bridge. The Metal bridge is not a native Metal renderer and must not be described as OpenGL-free. - Current backend policy: release packages use
platform_backend=sdl3;platform_backend=nativeon macOS is retained for comparison-only diagnostics. - Native Metal is not selected for the current release line. If native Metal becomes a target, create a separate design plan covering stock asset parity, shader translation, BSE effects, screenshot/readback behavior, diagnostics, performance counters, and rollback/fallback behavior before implementation.
- Native Cocoa/OpenGL backend results are useful for comparing SDL3 regressions but do not count as release support evidence unless a future support decision adds dedicated CI, packaging, and real Apple-hardware signoff.
- The detailed policy is recorded in
docs/dev/macos-renderer-backend-policy.mdanddocs/dev/macos-native-backend-containment-policy.md. - Current macOS Vulkan policy (added 2026-07-25): openQ4's Vulkan renderer module now also builds and ships for macOS, where it runs through MoltenVK, a Vulkan-on-Metal translation layer bundled in the package. It is opt-in only through
r_renderApi vulkan, applied at the next engine start. OpenGL remains the default and recommended macOS renderer in both package variants, andr_renderApi beststill resolves toglon macOS. renderer-vk_<arch>.dylibandlibMoltenVK.dylibare additions inside the existingOpenGLandMetal bridgepackages, staged inopenQ4.app/Contents/Frameworksand signed as nested code. They do not create a third package variant or a newmacos_graphics_bridgevalue.- MoltenVK is a translation layer. It is not a Metal renderer, not a Vulkan driver, and does not make any macOS package OpenGL-free; the
Metal bridgevariant keeps its existing meaning. MoltenVK is pinned tov1.4.1because that is the newest release compatible with the documentedmacOS 11floor. - macOS Vulkan is experimental, as the Vulkan renderer is on every platform. One player reported that it ran on an M4 Max MacBook Pro with 0.12.0 (issue #98), but nothing has checked that it renders correctly, so no supported-renderer or first-class claim follows from it. The decision-gate plan is recorded in
docs/dev/macos-moltenvk-decision.md, the staged record indocs/dev/plans/2026-07-25-macos-moltenvk.md, and the provider policy indocs/dev/macos-moltenvk-provider-policy.md.
Runtime Baselines
- Windows packaged compatibility floor:
Windows 7or later. - Windows validation focus: current
Windows 11releases first, withWindows 10retained as a practical compatibility target even though Microsoft's general Windows 10 servicing ended onOctober 14, 2025. - Windows 7/8/8.1 are no longer hard-blocked by the current x64 binaries, but they are legacy and outside the actively validated support matrix.
- Preview macOS packaged compatibility floor for the Apple Silicon/arm64 release line:
macOS 11or later. Meson now pins the deployment target to11.0so the binary floor matches the documented floor. That floor is a build target, not tested support: real-hardware reports so far come from macOS 26, hosted CI starts the packages on macOS 15 without game data, and nothing older has been run. Intel Mac and universal2 package floors are not published because those packages are not part of the current release matrix. - Linux packaged compatibility floor: release archives and AppImages are built on pinned
Ubuntu 24.04runners and should be treated as targeting a comparable modern 64-bit desktop userspace with desktop OpenGL plus EGL/Wayland or X11/GLX. AppImages bundle the release dependency closure while deliberately retaining host graphics-driver and desktop integration boundaries; they do not imply compatibility with an older glibc than the release runner. Linux ARM64 currently means 64-bit little-endian AArch64 hardware (theaarch64AppImage spelling) with a desktop-OpenGL-capable driver; GLES-only boards require a translation layer or future renderer work and are not implied by the package label. Hosted ARM64 CI builds the archive and AppImage and launches the final images assetlessly under Weston and Xvfb, but ARM64 packages remain preview; release signoff additionally requires the real-hardware stock-asset, dedicated-server, audio, input, and display evidence tracked in the Linux ARM64 evidence record. - Steam Deck support assumes a SteamOS 3.x style environment. The explicit
openQ4-steamdecklauncher remains the preferred shipping path, while rawopenQ4-client_<arch>launches can auto-select thesteamdeckprofile from Deck/SteamOS host signals unless disabled by environment.
SDL3 Direction
- SDL3 is the default backend path and the portability layer for:
- window lifecycle
- input event handling
- context/window interop glue
- New platform-facing work should prefer SDL3 abstractions first.
- Platform-specific code should be isolated under
src/sys/<platform>/when SDL3 cannot cover a requirement directly. - OpenGL context selection now uses the shared renderer ladder across SDL3, native GLX, and native NSOpenGL paths. macOS remains capped at OpenGL 4.1 core by the platform OpenGL stack, while Linux and Windows can continue down through core and compatibility-profile fallbacks according to
r_glTier. - macOS startup validates both advertised OpenGL extensions and the callable entry points behind the multitexture, ARB2, VBO upload, PBO readback, and GLSL paths. If Apple's OpenGL 2.1 compatibility fallback reports an incomplete loader state, openQ4 now downgrades optional upload/readback paths to CPU-backed fallbacks or fails through the normal missing-feature path instead of continuing into a SIGSEGV.
- Apple OpenGL 2.1 compatibility contexts now disable the legacy VBO vertex cache and use CPU-backed vertex data, keeping the renderer upload bridge and ARB2 startup away from the crash-prone VBO path reported on Apple Silicon. Apple OpenGL 2.1 compatibility also skips the full
interaction.vfpupload and prefersSimpleInteraction.vfp, avoiding the startup crash observed immediately after interaction color-mode detection on the Metal bridge path. - Apple OpenGL 2.1 compatibility now bypasses the ARB2 light-interaction pass on the fragile M4/M5 compatibility path reported in issue #73. This is a degraded-lighting fallback: affected launches log
ARB2 interaction driver bypass, restore the classic post-interaction GL state, texture-unit, and ARB program-binding baseline, force a neutral light-scale state, skip the post-interaction light-scale pass, keep an ambient rescue floor, and avoid the first-frame ARB2 light interaction crash while normal GL paths retain full ARB2 interaction rendering. Post-bypass breadcrumbs record state restoration, light-scale skip, ambient rescue, and frame tail so follow-up reports can identify the next operation reached. - Optional buffer-object users share the same capability contract: renderer upload cleanup tolerates missing delete/bind entry points, HDR exposure readback and light-grid baking use
glConfig.pixelBufferObjectAvailable, and disabled upload bridges report zero ring buffers in diagnostics. - Classic ARB2 interaction draws use explicit
idDrawVertVBO byte offsets instead of deriving member addresses from the vertex-cache offset token, which keeps Apple's OpenGL 2.1 compatibility path away from undefined C++ pointer formation during the first in-game interaction pass.
Meson Direction
- Meson is the canonical build system going forward.
- External dependencies should be consumed via Meson dependency resolution and subprojects/wraps.
- New build logic should be host-aware and architecture-aware, with x64 as the active compatibility baseline.
- Meson configuration defaults to
cpp_std=vc++latest(C++23-targeting mode on MSVC). - Meson currently adds
/Zc:strictStrings-on MSVC to preserve compatibility with legacy string-literal usage while the codebase is modernized. tools/build/meson_setup.ps1prefers VS 2026+ (major 18) when present; strict minimum enforcement can be enabled with-Denforce_msvc_2026=true.
Bring-Up Staging
- Keep Windows x64 stable with SDL3 default backend.
- Keep Linux on the SDL3 backend by default, validate x64 release paths, and complete Linux ARM64 real-hardware Wayland SP/MP, stock-map dedicated-server, audio, input, display, and package signoff beyond hosted assetless startup.
- Windows ARM64 has its first automated launch: push and pull-request CI start the assetless dedicated server on a
windows-11-armrunner, as Linux and macOS already did. It still needs a real-hardware SP/MP report before it can be described as a preview; client startup, runtime audio, and in-game coverage come next. - Complete the macOS Apple Silicon signoff (the
macOS 11floor and the latest public macOS, input devices, audio device switching, display modes, and in-game renderer coverage on real Macs) and publish signed/notarized DMGs before promoting the preview to first-class. - Add an explicit Intel Mac or universal2 release lane only after the project has architecture-specific CI,
lipo/install-name validation, and launch evidence for both packaged architectures.
SDL3 Migration Staging (Linux/macOS)
- Linux and macOS now use the shared SDL3 runtime path when
-Dplatform_backend=sdl3is selected, and that is the default configuration as of March 30, 2026. - macOS SDL3 builds select
src/sys/osx/macosx_sdl3.cppandsrc/sys/osx/macosx_sdl3_main.cppwith the shared SDL3 window, input, controller, and OpenGL context path. - The native Linux X11/GLX backend and experimental macOS Cocoa/OpenGL diagnostic backend remain available through
-Dplatform_backend=nativefor comparison and rollback while SDL3 remains the release path. On macOS, native backend results are comparison-only unless a future support decision adds dedicated validation. On SteamOS, the SDL3 path also watches application lifecycle events so suspend/resume and foreground/background transitions flow through the same input release, rumble stop, config write, and controller reacquire behavior used by the normal event pump.
Definition Of Done For First-Class Platform Support
- Clean configure + build in Meson.
- Engine initializes and reaches map/session startup with stock Quake 4 assets.
- Core input, rendering, audio, and networking paths work without platform-specific content hacks.
- Regressions are tracked in docs and fixed in engine/platform code, not with asset overrides.