I promised it a few months ago, and here it is: ARM support for the Resonite Headless Server Software is now generally available.
So, what took so long in doing the port? FrooxEngine itself runs perfectly on ARM CPUs, the issue arising when trying to hit native libraries.
Resonite itself relies on about 250 external dependencies, most of which being Open-Source, some of them even shipping ARM support natively.
The issue remained in the 12 libraries left not shipping or supporting ARM, namely, FreeImage, Opus, crunch, Assimp, MSDFGen, Rnnoise, Brotli, Compressonator, SoundPipe, FreeType, SteamAudio and SteamWorks.NET.
Most of those libraries were trivial to build to ARM, and with a streak of luck, GitHub made ARM runners available right about the time I started working on this issue.
Before that, you needed to cross-compile everything or spin up some kind of QEMU VM for it. With the new runners, it became as easy as defining an OS array and using it like so (partial snippets):
# Define matrix of OS versions to use
strategy:
matrix:
osver: [ubuntu-latest, ubuntu-24.04-arm]
# Use it
runs-on: ${{ matrix.osver }}
# Set artifact name depending on platform
- name: Set dist name
run: |
if ${{ matrix.osver == 'ubuntu-24.04-arm' }}; then
echo "distname=arm-dist" >> "$GITHUB_ENV"
else
echo "distname=linux-dist" >> "$GITHUB_ENV"
fi
# Upload artifact with right name
- uses: actions/upload-artifact@v4
with:
path: Dist/
name: ${{ env.distname }}Code language: PHP (php)
Yup, it’s that easy. Most of the libraries were trivial, building a C or C++ program for ARM on GitHub Actions basically equates to running the same commands on the ARM runner.
All this work was also the opportunity to clean up some files shipped in the FrooxEngine repository by bundling libraries directly into NuGet packages instead. Usually, those native libraries end up in runtimes/linux-arm64/native.
Now, why did it take so long to put this together, since it sounds so trivial? Well, that question can be answered with a single name: Steamworks.
We use Steam integrations (as Resonite is published on Steam), so of course, we do need to ship the Steam library, which at the time had no support for ARM64, completely crashing the type computing mechanism in FrooxEngine.
Fast-forward to November, Valve announces their headset, the Steam Frame. I didn’t care much for the headless itself, only that with it being ARM, it meant that we would finally get official ARM support for a bunch of stuff from Valve. A week or two later, they finally delivered, updating the Steamworks API library to support officially ARM.
At first updating the library itself proved difficult as for some reason, Steamworks.NET builds every single architecture separately. Luckily, a PR opened on the official repository made quick work of it, and provided proper ARM builds.
Early testing of the headless was done on the Oracle Cloud Free tier ARM machine. With Steamworks patched, I finally watched the headless run flawlessly on that machine, the only error remaining being the Discord social SDK complaining about the architecture. Luckily, Discord isn’t as critical and can be ignored.
All in all, this was a fun issue to tackle, and it opens the door for more ARM stuff in the future. Maybe a native ARM build for the Steam Frame, or a mobile build? Who knows?
In any case, time for you all to finally put that Raspberry Pi you’ve had on your shelf for the past 5 years to good use again.
A small reminder that you need at least the Discoverer plan to get access to the Headless Server Software; however, any support of Resonite is greatly appreciated.
If you wish to support us, you can subscribe within the account website.
Special thanks to the people & creatures that made this possible through research, direct contributions, or testing:
- Cyro
- AdamK2003
- Orion Moonclaw
- Gamethecupdog





