Skip to content

Single-player levels abort back to the main menu: CreateOpenALBuffer fails on Apple's OpenAL (macOS arm64, 0.12.0) #122

Description

@DrHowarth

Summary

On the experimental macOS arm64 package, single-player levels load completely
AAS files load, Spawning entities runs — and are then torn down at the end of the
load by an OpenAL buffer allocation failure. The engine catches the error, runs
Game Map Shutdown, and returns to the main menu.

To a player this looks like "the game won't start" or "New Game just bounces me back
to the menu". It is neither a path problem nor a Gatekeeper problem: the map genuinely
loads first.

The macOS packages link Apple's deprecated OpenAL.framework and bundle no OpenAL Soft,
and Apple's implementation refuses to allocate the number of hardware buffers a stock
Quake 4 map needs.

Environment

Field Value
openQ4 version 0.12.0
openq4_commit eab43b9947e0777c19fbba189271e79fe5d423fe
openq4_game_commit e479f914bedd9a324ac06f79ac199c456031746c
Package artifact openq4-0.12.0-macos-arm64-opengl-unsigned.tar.gz (OpenGL package, not Metal bridge)
Launch path /Applications/openQ4.app/Contents/MacOS/openQ4 from Terminal, openQ4.app dragged to /Applications from the unpacked archive
macOS 26.6 (build 25G72)
Hardware MacBook Air Mac14,15, Apple M2, 8 GB RAM
Rosetta Not involved — binary is arm64, lipo -archs reports arm64
Retail assets GOG Quake 4 1.4.3 offline installer, extracted with innoextract; all 25 pak*.pk4, q4cmp_pak001.pk4 and the unsuffixed zpak_english.pk4 present and loading
Renderer OpenGL (default). Vulkan not enabled. Renderer appears unrelated.

Symptom

loading maps/game/airdefense1.aas128
Entering doom_main()
Exiting doom_main()
Spawning entities
OpenAL Error: Invalid Value (0xa003), @ ../src/sound/OpenAL/AL_SoundSample.cpp 565
------------ Game Map Shutdown --------------
---------------------------------------------
********************
ERROR: idSoundSample_OpenAL::CreateOpenALBuffer: error generating OpenAL hardware buffer
********************
------------ Game Map Shutdown --------------
--------------- Game Shutdown ---------------

0xa003 is AL_INVALID_VALUE returned from the buffer generation call at
src/sound/OpenAL/AL_SoundSample.cpp:565.

OpenAL environment

OpenAL ALC version: 1.1
OpenAL vendor: Apple Computer Inc.
OpenAL renderer: Software
OpenAL version: 1.1
OpenAL extensions: AL_EXT_OFFSET AL_EXT_LINEAR_DISTANCE AL_EXT_EXPONENT_DISTANCE
                   AL_EXT_float32 AL_EXT_STATIC_BUFFER AL_EXT_SOURCE_NOTIFICATIONS
                   AL_EXT_SOURCE_SPATIALIZATION
OpenAL HRTF: unavailable
OpenAL output mode: unavailable
OpenAL EFX is not available in this build; reverb wet send disabled.

The package links Apple's system framework and ships no OpenAL Soft:

$ otool -L openQ4.app/Contents/MacOS/openQ4 | grep -i openal
	/System/Library/Frameworks/OpenAL.framework/Versions/A/OpenAL

$ ls openQ4.app/Contents/Frameworks/
game-mp_arm64.dylib   game-sp_arm64.dylib   libMoltenVK.dylib   renderer-vk_arm64.dylib

Apple's OpenAL has been deprecated since macOS 10.15, is software-only here, and exposes
no EFX. The AL_EXT_* list above is notably short compared with OpenAL Soft.

Reproduction matrix

s_maxSoundsPerShader reduces the number of sample variants loaded per sound shader, so
it is a proxy for total buffer count. Every run below is otherwise identical
(+set fs_basepath ... +map <map>), on the built-in speakers:

Map s_maxSoundsPerShader Result
game/airdefense1 0 (default) FailsCreateOpenALBuffer, returns to menu
game/airdefense1 3 Fails — same
game/airdefense1 1 Loads: 17747 msec to load game/airdefense1, clean exit
game/mcc_1 (campaign start) 1 Fails — same error
game/airdefense1 0, plus s_noSound 1 Loads: 15958 msec, Map media phases: ... sound=0

Two things follow:

  1. Audio is the cause. With s_noSound 1 the identical map loads and stays loaded.
  2. s_maxSoundsPerShader is not a workaround. It only moves the threshold. It is
    enough for airdefense1 but not for mcc_1, the first campaign map — so a player
    starting a New Game cannot get in at all.

Ruled out

  • Audio device. Fails identically on a Bluetooth headset and on the built-in
    speakers. The device is not the variable.
  • Missing or modified retail assets. All paks load with matching checksums; the
    fatal "media pk4 files are missing" path is a different failure that occurs only
    when fs_basepath is absent.
  • Renderer. Occurs on the OpenGL package with the default renderer.
  • Rosetta / architecture. Native arm64 throughout.
  • Issue Crash on launch: SIGSEGV (11) in Renderer Upload Manager on macOS Tahoe (Apple Silicon M5) #73. That is a SIGSEGV in the renderer upload manager before the main
    menu. This is a caught idException after a successful map load, and this build
    logs Renderer upload manager: disabled legacy bridge.

Possible relationship to #94 and #104

This may be a packaging/build-provider question rather than a new engine bug.

The published 0.12.0 arm64 artifact nevertheless links Apple's framework at runtime:

$ otool -L openQ4.app/Contents/MacOS/openQ4 | grep -i openal
	/System/Library/Frameworks/OpenAL.framework/Versions/A/OpenAL

and reports OpenAL vendor: Apple Computer Inc. with no EFX and no HRTF, with no
OpenAL Soft dylib present in Contents/Frameworks/.

So: are the published macOS packages built with the OpenAL Soft provider? If the
release pipeline still resolves to the Apple framework, then the runtime symptom above
is the user-visible consequence of exactly the problem #94/#104 addressed at build time,
and the shipped artifact would need rebuilding with OpenAL Soft linked and bundled.

Suggested fix

Link and bundle OpenAL Soft in the macOS packages. Beyond this crash it should also
restore EFX/reverb and HRTF, both currently reported unavailable.

Separately, and regardless of provider: a failed sound-buffer allocation currently
raises a fatal idException that tears down a fully-loaded map. Degrading gracefully —
a bounded buffer pool with reuse, or simply dropping the sample — would keep a level
playable instead of bouncing the player to the main menu with no on-screen explanation.

Log

Full openq4.log from a reproducing game/mcc_1 run and the
collect_macos_support_info.sh archive are available on request — happy to attach both
(redacted) if useful. Key sections inline:

Filesystem, renderer and OpenAL init
openQ4 0.12.0 (macos-arm64, Aug 18 2026 21:47:22)
Filesystem paths: fs_basepath='<retail root>' fs_game='baseoq4'
Setup OpenAL device and context... OpenAL output mode '5.1 surround' requested,
  but this build does not expose ALC_SOFT_output_mode; using the runtime default.
OpenAL ALC version: 1.1
OpenAL vendor: Apple Computer Inc.
OpenAL renderer: Software
OpenAL version: 1.1
OpenAL requested device: system default
OpenAL active device: MacBook Air Speakers
OpenAL HRTF: unavailable
OpenAL output mode: unavailable
OpenAL EFX is not available in this build; reverb wet send disabled.
sound system initialized.
Renderer bootstrap: selected=LegacyGL2Compat requested=auto bridge=ARB2
  caps={GL 2.1 unknown, VBO:0 PBO:1 UBO:0 VAO:0 MRT:1 FBO:1 ...}
Selected game module: logical='game_sp' binary='game-sp_arm64'
Map load completes, then the abort
loading maps/game/airdefense1.aas128
Entering doom_main()
Exiting doom_main()
Spawning entities
OpenAL Error: Invalid Value (0xa003), @ ../src/sound/OpenAL/AL_SoundSample.cpp 565
------------ Game Map Shutdown --------------
---------------------------------------------
********************
ERROR: idSoundSample_OpenAL::CreateOpenALBuffer: error generating OpenAL hardware buffer
********************
------------ Game Map Shutdown --------------
--------------- Game Shutdown ---------------
Same map with s_noSound 1 — loads and stays loaded
 15958 msec to load game/airdefense1
Map load phases: renderWorld=540 gameInit=3424 playerSpawn=407
                 mediaFinish=11565 settle=22 total=15958 msec
Map media phases: render=11565 sound=0 decl=0 bse=0 loadSize=0 ui=0 total=11565 msec

Unrelated note for other macOS reporters: collect_macos_support_info.sh prints a
review reminder, which is worth heeding — its system/hardware.txt includes the machine
serial number, Hardware UUID and Provisioning UDID, and system/uname.txt includes
the hostname. Easy to miss before attaching to a public issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions