Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Vendored third-party packages; collapsed in GitHub diffs
defaults/python/externals-aarch64/** linguist-generated=true
24 changes: 23 additions & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,28 @@ jobs:
path: out/moondeck.zip
if-no-files-found: error

check-externals:
name: Check Python externals
strategy:
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.13"

- name: Check arch-specific pins
run: python scripts/check-externals.py

# -S keeps site-packages off sys.path, so only the bundled externals can satisfy imports
- name: Import bundled packages
run: python -S scripts/check-externals.py --smoke

build-cli:
name: Build CLI
strategy:
Expand Down Expand Up @@ -124,7 +146,7 @@ jobs:

release:
name: Nightly release
needs: [build-plugin, build-cli, release-pre-check]
needs: [build-plugin, build-cli, check-externals, release-pre-check]
runs-on: ubuntu-latest
if: ${{ needs.release-pre-check.outputs.do-release == 'true' }}
steps:
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,28 @@ MoonDeck is an automation tool that will simplify launching your Steam games via

It requires an additional lightweight app to be installed on the host PC - [MoonDeck Buddy](https://github.com/FrogTheFrog/moondeck-buddy). Additional one-time setup instructions can be found within the settings page of the plugin itself.

## ARM64 support (experimental)

The same plugin package also runs on aarch64 Linux handhelds with Decky Loader, such as the AYN Odin 2 Portal running [Armada OS](https://github.com/armada-os/armada). No extra configuration is needed. Install the aarch64 build of the Moonlight flatpak; MoonDeck starts the flatpak for the host architecture.

Known limitations:

* Moonlight's flatpak has no working hardware video decoding on Adreno GPUs, so it decodes on the CPU. If the stream stutters, lower the resolution or bitrate, or set **Video codec** to H.264 in MoonDeck -> Moonlight settings -> General.
* Linked-display features don't work, because the ARM Steam client lacks `SteamClient.System.DisplayManager`. The related errors in the frontend log are harmless.

## Building

To build and deploy the plugin package first copy `.env.example` to `.env` and update any relevant settings. Then either:

* Run `pnpm` commands `pnpm run setup` and `pnpm run build:plugin` and `pnpm run deploy`.
* Run VSCode tasks Ctrl+Shift+P or Cmd+Shift+P and run: `Tasks: Run Task` and choose the task to run.

### Python dependencies

Bundled Python packages live in `defaults/python/externals` and are x86_64 builds. All of them except `psutil` fall back to pure Python on other architectures, so `psutil` also has an aarch64 build in `defaults/python/externals-aarch64`, which the plugin loads first on aarch64.

When bumping versions in `defaults/python/requirements.txt`, update `defaults/python/requirements-aarch64.txt` to match and run `scripts/update-arch-externals.sh`. CI checks that the versions match and that every bundled package imports on both x86_64 and aarch64 (`scripts/check-externals.py`).

## Internal data

This plugin stores data in the following directories:
Expand Down
4 changes: 3 additions & 1 deletion defaults/python/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
def add_plugin_to_path():
# Do nothing if it's packaged with Nuitka
if "__compiled__" not in globals():
import platform
import sys
from pathlib import Path
script_dir = Path(__file__).parent.resolve()
directories = [["lib"], ["externals"]]
# Arch-specific externals (e.g. aarch64 psutil) must shadow the default x86_64 ones; the dir only exists where needed
directories = [["lib"], [f"externals-{platform.machine()}"], ["externals"]]

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of this at all :/

Since it's only needed for psutils, I want to play around a little and see what other options are. I'll get back to you on this point later.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed psutil, please rebase.

for dir in directories:
sys.path.append(str(script_dir.joinpath(*dir)))

Expand Down
29 changes: 29 additions & 0 deletions defaults/python/externals-aarch64/psutil-7.0.0.dist-info/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading