Skip to content

macOS support: fix launch signing, restart/update, release CI - #171

Open
notryanfraser wants to merge 7 commits into
Rhythia:indevfrom
notryanfraser:macos-build
Open

notryanfraser wants to merge 7 commits into
Rhythia:indevfrom
notryanfraser:macos-build

Conversation

@notryanfraser

Copy link
Copy Markdown

Hey! Some context first: I put this together to help someone who was frustrated with how Rhythia runs on their ARM Mac. While looking into it I found the 0.2.0 macOS.zip doesn't actually launch on current macOS (it gets killed right away), so this grew into getting macOS builds working properly. No pressure to merge any of it. If you'd rather take only some pieces, or redo them your own way, go for it.

Why the macOS build doesn't launch

Godot's built-in ad-hoc signer (codesign/codesign=1 in the macOS preset) produces a signature that current macOS rejects: the binary is SIGKILLed at exec (exit 137, launchd error 163). Re-signing the same app with Apple's codesign fixes it, so the preset now uses the Xcode codesign option (3). That also means macOS builds have to be exported on a Mac.

Changes

  • macOS preset: bundle id wiki.rhythia.net (same as the 0.2.0 release), version 0.2.0, Apple codesign
  • Restart fix (macOS + Linux): restartGame() passed the relaunch script to /bin/sh without -c, so sh treated it as a filename and the game never came back. macOS also resolved Rhythia.app/Contents instead of the .app. Paths are quoted now.
  • macOS self-update: Updatum finds the .app through AppContext.BaseDirectory, which Godot points at Contents/Resources, so it would sync the update inside the running bundle. On macOS the app is now swapped by a small script instead (the old app is restored if the copy fails). Windows/Linux still go through Updatum unchanged.
  • macOS keys: Cmd+O toggles settings (Ctrl+O elsewhere), and the search box ignores Cmd shortcuts. Ctrl+M mute is unchanged since Cmd+M is minimize on macOS.
  • Release workflow (.github/workflows/release.yml): on release publish, exports Windows/Linux on Ubuntu and macOS on a macOS runner, then uploads Windows.zip / Linux.zip / macOS.zip with the same layout as the current releases. The macOS job launches the app so a bad signature fails CI. Godot version comes from .github/godot_version.txt.
  • OpenGL compatibility scripts: added to the repo and fixed. The .sh passed "--rendering-driver opengl3" as a single argument, so Godot ignored it, and the .bat only worked from inside the game folder.
  • README: macOS install steps (including the Gatekeeper "Open Anyway" step, since builds are ad-hoc signed), the user folder path, and contributor notes
  • Removed the unused Constants.ROOT_FOLDER and stopped ignoring export_presets.cfg (it's tracked and CI needs it)

Testing

  • Apple Silicon (M1 Pro), macOS 27: the CI-built macOS.zip launches on Metal Forward+. Imported 76 .sspm maps (0 corrupt), played a full map with Autoplay (100%, no errors), and checked that the song timer runs at real speed.
  • Release workflow ran on my fork, and the zip contents match the 0.2.0 assets: https://github.com/notryanfraser/Client/releases/tag/0.2.0-macos.1
  • dotnet format --verify-no-changes and dotnet csharpier check . pass
  • Not tested: an Intel Mac, and the Windows/Linux builds on real hardware (CI exports them, but I didn't run them)

Notes

  • Some CJK/symbol characters in map titles show up as boxes on macOS (e.g. 打, ∀). I didn't look into this and don't know whether Windows has the same issue.
  • This is several changes in one PR. Happy to split it up if that's easier to review.

AI usage

This was done with Claude Code (Anthropic). I reviewed the changes and tested the build on my Mac as described above.

🤖 Generated with Claude Code

notryanfraser and others added 7 commits October 14, 2026 09:43
- Set bundle identifier, version, and export path for the macOS preset
- Sign with Xcode codesign instead of Godot's built-in signer; the
  built-in ad-hoc signature gets the binary SIGKILLed at exec on
  current macOS (exit 137, launchd error 163)
- Ignore local build/ output

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The published 0.2.0 macOS.zip ships as wiki.rhythia.net; match it so
local and CI exports are the same app to macOS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- restartGame passed the relaunch script to /bin/sh without -c, so sh
  treated it as a filename and the game never came back on macOS/Linux
- macOS relaunch resolved Rhythia.app/Contents instead of the .app
- Quote paths passed to the shell
- Updatum detects .app bundles via AppContext.BaseDirectory, which Godot
  points at Contents/Resources, so it would sync updates inside the
  running bundle; swap the .app ourselves on macOS instead

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Settings toggle uses Cmd+O on macOS (Ctrl+O elsewhere)
- Search box no longer captures keypresses held with Cmd
- Drop unused Constants.ROOT_FOLDER (cwd is / when launched from Finder)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Exports all three presets from the committed export_presets.cfg on
release publish (or manual dispatch) and uploads Windows.zip,
Linux.zip, and macOS.zip with the same layout as current releases.

- macOS exports on a macOS runner since the preset signs with Xcode
  codesign; the job launches the app to catch signing regressions
- Godot version comes from .github/godot_version.txt, same as CI
- Fix the opengl3 compatibility launchers: the .sh passed the flag as
  one quoted argument, the .bat only worked from the game folder
- Stop ignoring export_presets.cfg, it is tracked and CI needs it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Builds are ad-hoc signed (no Developer ID), so document Open Anyway and
the xattr command for the first launch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant