diff --git a/.github/workflows/appimage-build.yml b/.github/workflows/appimage-build.yml
new file mode 100644
index 0000000..1d032df
--- /dev/null
+++ b/.github/workflows/appimage-build.yml
@@ -0,0 +1,54 @@
+name: AppImage Build
+
+on:
+ workflow_dispatch:
+ # Ensure the build works on main
+ push:
+ branches: [main]
+ # Ensure the build works on each pull request
+ pull_request:
+ # Build and publish on release
+ release:
+ types: [published]
+
+jobs:
+ build:
+ runs-on: ubuntu-22.04
+ timeout-minutes: 30
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: extractions/setup-just@v1
+
+ - name: Load dotenv
+ run: just ci-load-dotenv
+
+ - name: Load dotenv
+ run: just bump-version
+
+ # Install FUSE (https://github.com/AppImage/AppImageKit/wiki/FUSE)
+ - name: Install pkg2image dependencies
+ run: |
+ sudo add-apt-repository universe
+ sudo apt install libfuse2
+
+ # Install pkg2appimage and build the game (https://github.com/AppImageCommunity/pkg2appimage)
+ - name: Build AppImage
+ run: |
+ wget -c $(wget -q https://api.github.com/repos/AppImageCommunity/pkg2appimage/releases -O - | grep "pkg2appimage-.*-x86_64.AppImage" | grep browser_download_url | head -n 1 | cut -d '"' -f 4)
+ chmod +x ./pkg2appimage-*.AppImage
+ ./pkg2appimage-*.AppImage public/packaging/appimage/recipe.yml
+
+ - name: Rename the AppImage
+ run: mv ./out/*.AppImage ${{ env.game_name }}-${{ env.game_version }}.AppImage
+
+ - uses: actions/upload-artifact@v4
+ with:
+ name: ${{ env.game_name }}-${{ env.game_version }}.AppImage
+ path: ./
+
+ # Publish, on each release
+ - name: Publish AppImage
+ if: ${{ env.GITHUB_EVENT_NAME == 'release' || (env.GITHUB_EVENT_NAME == 'workflow_dispatch' && startsWith(github.ref, 'refs/tags/')) }}
+ run: |
+ gh release upload ${{ env.game_version }} ./${{ env.game_name }}-${{ env.game_version }}.AppImage
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0199632..d753710 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
## [Unreleased]
### Added
+- Add AppImage packaging support ([#53](https://github.com/MechanicalFlower/Marble/pull/53))
### Changed
### Deprecated
### Removed
diff --git a/Justfile b/Justfile
index ff76415..544f047 100644
--- a/Justfile
+++ b/Justfile
@@ -188,10 +188,14 @@ butler *ARGS: check-butler
sed -i "s,config/version=.*$,config/version=\"{{ game_version }}\",g" ./project.godot
echo "Update version in public/packaging"
+ # Snap
sed -i "s,version:\ '.*'$,version:\ '{{ game_version }}',g" ./public/packaging/snap/snapcraft.yaml
sed -i "s,archive/refs/tags/.*\.tar\.gz$,archive/refs/tags/{{ game_version }}\.tar\.gz,g" ./public/packaging/snap/snapcraft.yaml
sed -i "s,releases/download/.*/Marble-linux-v.*\.zip$,releases/download/{{ game_version }}/Marble-linux-v{{ game_version }}\.zip,g" ./public/packaging/snap/snapcraft.yaml
- sed -i "s,Version=.*$,Version={{ game_version }},g" ./public/packaging/org.mechanicalflower.Marble.desktop
+ # AppImage
+ sed -i "s,releases/download/.*/Marble-linux-v.*\.zip,releases/download/{{ game_version }}/Marble-linux-v{{ game_version }}\.zip,g" ./public/packaging/appimage/recipe.yml
+ sed -i "s,MechanicalFlower/Marble/.*/public/packaging/org.mechanicalflower.Marble.desktop,MechanicalFlower/Marble/{{ game_version }}/public/packaging/org.mechanicalflower.Marble.desktop,g" ./public/packaging/appimage/recipe.yml
+ sed -i "s,MechanicalFlower/Marble/.*/assets/icon.png,MechanicalFlower/Marble/{{ game_version }}/assets/icon.png,g" ./public/packaging/appimage/recipe.yml
[private]
pre-export: clean-addons makedirs bump-version install-addons import-resources
diff --git a/README.md b/README.md
index 8f1ea74..e6af3e5 100644
--- a/README.md
+++ b/README.md
@@ -9,9 +9,10 @@
A marble race minigame, made with [Godot Engine](https://godotengine.org/).
-
-
+
+
+
diff --git a/public/packaging/appimage/AppRun b/public/packaging/appimage/AppRun
deleted file mode 100644
index d42f2db..0000000
--- a/public/packaging/appimage/AppRun
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-
-path="$APPIMAGE"
-cd "$(dirname "$0")"
-ExExist="$(grep -i Exec "$HOME"/.local/share/applications/org.mechanicalflower.Marble.desktop)"
-
-if [ ! -f "$HOME"/.local/share/applications/org.mechanicalflower.Marble.desktop ] || [ "$ExExist" != "Exec=\"""$path""\"" ]
-then
- cp ./Marble.png $HOME/.icons/
- cp ./org.mechanicalflower.Marble.desktop $HOME/.local/share/applications/org.mechanicalflower.Marble.desktop
- sed -i -e "s|RepCurrent|$path|g" "$HOME"/.local/share/applications/org.mechanicalflower.Marble.desktop
- sed -i -e "s|MyHome|$HOME|g" "$HOME"/.local/share/applications/org.mechanicalflower.Marble.desktop
-fi
-
-exec ./Marble.x86_64
diff --git a/public/packaging/appimage/recipe.yml b/public/packaging/appimage/recipe.yml
new file mode 100644
index 0000000..21747cb
--- /dev/null
+++ b/public/packaging/appimage/recipe.yml
@@ -0,0 +1,46 @@
+app: Marble
+
+ingredients:
+ dist: trusty
+ sources:
+ - deb http://us.archive.ubuntu.com/ubuntu/ trusty main universe
+ packages:
+ - libx11-6
+ - libxinerama1
+ - libxcursor1
+ - libxrandr2
+ - libfreetype6
+ - libpng12-0
+ - libasound2
+ - libpulse0
+ - libgl1-mesa-glx
+ - zlib1g
+ - libgcc1
+ - libc6
+ script:
+ # Download released builds
+ - wget -c "https://github.com/MechanicalFlower/Marble/releases/download/1.6.0/Marble-linux-v1.6.0.zip"
+ - unzip *.zip
+ # Download the icon and the .desktop file
+ - wget -c "https://raw.githubusercontent.com/MechanicalFlower/Marble/1.6.0/public/packaging/org.mechanicalflower.Marble.desktop"
+ - wget -c "https://raw.githubusercontent.com/MechanicalFlower/Marble/1.6.0/assets/icon.png"
+
+script:
+ - sed -i.bak -e "s,Version=.*$,,g" ../org.mechanicalflower.Marble.desktop
+ # Replace the icon path in the desktop file
+ - sed -i.bak -e "s,Icon=org.mechanicalflower.Marble$,Icon=/usr/share/icons/hicolor/apps/marble.png,g" ../org.mechanicalflower.Marble.desktop
+ # Replace the exec command in the desktop file
+ - sed -i.bak -e "s,Exec=marble-wrapper$,Exec=bin/Marble.x86_64 --main-pack bin/Marble.pck --rendering-driver opengl3,g" ../org.mechanicalflower.Marble.desktop
+ # Copy the desktop file
+ - mkdir -p usr/share/applications/
+ - cp ../org.mechanicalflower.Marble.desktop .
+ - cp ../org.mechanicalflower.Marble.desktop usr/share/applications/org.mechanicalflower.Marble.desktop
+ # Copy the icon
+ - mkdir -p usr/share/icons/hicolor/apps/
+ - cp ../icon.png usr/share/icons/hicolor/apps/marble.png
+ # Copy game files
+ - mkdir -p usr/bin/
+ - cp ../Marble.x86_64 usr/bin/Marble.x86_64
+ - cp ../Marble.pck usr/bin/Marble.pck
+ # Ensure the game is an executable
+ - chmod +x usr/bin/Marble.x86_64
diff --git a/public/packaging/org.mechanicalflower.Marble.desktop b/public/packaging/org.mechanicalflower.Marble.desktop
index 44a2fc6..7902543 100644
--- a/public/packaging/org.mechanicalflower.Marble.desktop
+++ b/public/packaging/org.mechanicalflower.Marble.desktop
@@ -1,6 +1,5 @@
[Desktop Entry]
-Version=1.6.0
Type=Application
Name=Marble
diff --git a/public/packaging/snap/snap-xvfb-launch.sh b/public/packaging/snap/snap-xvfb-launch.sh
deleted file mode 100644
index ebff70d..0000000
--- a/public/packaging/snap/snap-xvfb-launch.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-
-
-LIBGL_DEBUG=verbose glxinfo
-
-ps auxx | grep 'Xvfb' | grep -v grep
-
-echo = Launching marble =
-
-export SDL_VIDEODRIVER=x11
-
-LIBGL_DEBUG=verbose marble &
-FOPID=$!
-sleep 10
-kill ${FOPID}
-wait ${FOPID}
-echo Marble return code $?
-cat ~/.local/share/marble/marble.log || echo No log file