Skip to content

Fix(core-ruffle): resolve standalone Ruffle path inside .app bundle on macOS#516

Open
mark-henry wants to merge 1 commit into
FlashpointProject:masterfrom
mark-henry:fix/ruffle-standalone-macos-app-bundle-path
Open

Fix(core-ruffle): resolve standalone Ruffle path inside .app bundle on macOS#516
mark-henry wants to merge 1 commit into
FlashpointProject:masterfrom
mark-henry:fix/ruffle-standalone-macos-app-bundle-path

Conversation

@mark-henry

Copy link
Copy Markdown

Problem

On macOS, launching any Flash game via Play ▾ → Run with Ruffle crashes the launcher backend (Flashpoint Helper) with an unhandled promise rejection:

override: ruffle
Error downloading Ruffle version "latest": Error fetching release information:
AxiosError: Request failed with status code 404
[UnhandledPromiseRejection ... ERR_UNHANDLED_REJECTION]

This happens even though a working standalone Ruffle is already bundled at Data/Ruffle/standalone/latest/.

Root cause

In extensions/core-ruffle/src/middleware/standalone.ts, the standalone executable path is resolved as a flat file:

const executable = os.platform() === 'win32' ? 'ruffle.exe' : 'ruffle';
const execPath = path.join(this.ruffleStandaloneRoot, middlewareConfig.version, executable);

On macOS the standalone release (*-macos-universal.tar.gz) extracts to a Ruffle.app bundle, so the actual binary lives at <version>/Ruffle.app/Contents/MacOS/ruffle, not <version>/ruffle. As a result fs.existsSync(execPath) is always false on macOS, which forces the download branch:

const asset = await getGithubReleaseAsset(getPlatformRegex(), middlewareConfig.version); // version = 'latest'

With the default version: 'latest', getGithubReleaseAsset requests https://api.github.com/repos/ruffle-rs/ruffle/releases/tags/latest, which 404s (there is no tag literally named latest). That rejection is thrown out of an async path with no .catch, taking down the backend.

Fix

Resolve execPath inside the .app bundle on darwin. This matches both the bundled Ruffle and a freshly-extracted macos-universal.tar.gz, so existsSync succeeds and the download is correctly skipped. The existing chmod(execPath, 0o775) and gameLaunchInfo.launchInfo.gamePath = execPath work unchanged with this path.

const execPath = os.platform() === 'darwin'
  ? path.join(this.ruffleStandaloneRoot, middlewareConfig.version, 'Ruffle.app', 'Contents', 'MacOS', 'ruffle')
  : path.join(this.ruffleStandaloneRoot, middlewareConfig.version, executable);

Testing

Verified on macOS 15 (Apple Silicon, Flashpoint 14.0.3, build a7b78478) by applying the equivalent change to the built extension (dist/extension.js):

  • Before: Run with Ruffle → 404 crash (above).
  • After: Run with Ruffle launches the bundled standalone Ruffle (Metal backend) and the game runs correctly; no download is attempted.

Windows/Linux paths are unchanged.

Related (out of scope, noted for awareness)

Even when a download is needed, version: 'latest' is passed straight into releases/tags/${version}/releases/tags/latest (404). A literal latest should resolve via /releases/latest (or the releases list). Not fixed here to keep this PR focused on the crash; happy to follow up if desired.

…n macOS

On macOS the Ruffle standalone release ships as a Ruffle.app bundle, so the
binary lives at <version>/Ruffle.app/Contents/MacOS/ruffle. The previous flat
path (<version>/ruffle) never exists on macOS, so existsSync() always failed
and forced a re-download via getGithubReleaseAsset(..., 'latest'), which
requests /releases/tags/latest -> 404 and rejects unhandled, crashing the
launcher backend when using 'Run with Ruffle'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dot-mike

dot-mike commented Jun 29, 2026

Copy link
Copy Markdown
Member

No. If you took the time to read Mac installation guide https://flashpointarchive.org/datahub/Mac_Support#Installing_Flashpoint it tells you to download a static copy of Flashpoint. It's just that Ruffle was NOT included in the release.

So actually, this PR doesn't solve anything.

if the user were to download Ruffle binary and drop it into path/to/extraction/of/Flashpoint/Data/standalone/latest/ issue is resolved.

(Note, apple is not my expertise, just basing of my existing knowledge and I do not have access to a Mac to test with)

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.

2 participants