diff --git a/Makefile b/Makefile
index b48cd5c..229a766 100644
--- a/Makefile
+++ b/Makefile
@@ -112,6 +112,11 @@ release:
release32:
env ARCH_LABEL=32bit ./scripts/release.sh
+# `make appimage` builds an AppImage, run it after `make dist`
+.PHONY: appimage
+appimage:
+ ./appimage.sh
+
# `make mingw-release` runs a FULL end-to-end release of Linux and Windows
# binaries of the game, zipped and tagged and ready to go.
.PHONY: mingw-release
diff --git a/appimage.sh b/appimage.sh
new file mode 100755
index 0000000..cadd273
--- /dev/null
+++ b/appimage.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+# Script to build an AppImage.
+#
+# Dependencies:
+# * appimage-builder: a Python module, so pip install -r requirements.txt
+
+if ! command -v appimage-builder &> /dev/null;then
+ echo "appimage-builder not found; run pip install -r requirements.txt"
+ exit 1
+fi
+
+if [[ ! -d "./dist/sketchymaze-latest" ]]; then
+ echo "error: run make dist before make appimage"
+ exit 1
+fi
+
+APPDIR="./dist/AppDir"
+LAUNCHER="./scripts/appimage-launcher.sh"
+DESKTOP="./scripts/appimage.desktop"
+ICON_IMG="./etc/icons/256.png"
+ICON_VECTOR="./etc/icons/orange-128.svg"
+
+APP_RUN="$APPDIR/AppRun"
+DIR_ICON="$APPDIR/sketchymaze.svg"
+
+# Clean start
+if [[ -d "$APPDIR" ]]; then
+ echo "Note: Removing previous $APPDIR"
+ rm -rf "$APPDIR"
+fi
+
+echo "Creating $APPDIR"
+mkdir $APPDIR
+
+# Entrypoint script (AppRun)
+cp "./scripts/appimage-launcher.sh" "$APPDIR/AppRun"
+chmod +x "$APPDIR/AppRun"
+
+# .DirIcon PNG for thumbnailers
+cp "./etc/icons/256.png" "$APPDIR/.DirIcon"
+cp "./etc/icons/orange-128.svg" "$APPDIR/sketchymaze.svg"
+
+# .desktop launcher
+cp "./scripts/appimage.desktop" "$APPDIR/sketchymaze.desktop"
+
+# Everything else
+rsync -av "./dist/sketchymaze-latest/" "$APPDIR/"
+
+echo "Making AppImage..."
+cd $APPDIR
+appimagetool $(pwd)
\ No newline at end of file
diff --git a/etc/icons/blue-128.svg b/etc/icons/blue-128.svg
new file mode 100644
index 0000000..f49b901
--- /dev/null
+++ b/etc/icons/blue-128.svg
@@ -0,0 +1,396 @@
+
+
diff --git a/etc/icons/green-128.svg b/etc/icons/green-128.svg
new file mode 100644
index 0000000..13a635a
--- /dev/null
+++ b/etc/icons/green-128.svg
@@ -0,0 +1,396 @@
+
+
diff --git a/etc/icons/orange-128.svg b/etc/icons/orange-128.svg
new file mode 100644
index 0000000..a54212e
--- /dev/null
+++ b/etc/icons/orange-128.svg
@@ -0,0 +1,396 @@
+
+
diff --git a/etc/icons/pink-128.svg b/etc/icons/pink-128.svg
new file mode 100644
index 0000000..399b052
--- /dev/null
+++ b/etc/icons/pink-128.svg
@@ -0,0 +1,396 @@
+
+
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..01351ea
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+appimage-builder
\ No newline at end of file
diff --git a/scripts/appimage-launcher.sh b/scripts/appimage-launcher.sh
new file mode 100644
index 0000000..6ea16b6
--- /dev/null
+++ b/scripts/appimage-launcher.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+cd "$(dirname "$0")"
+echo AppImage Sketchy Maze launcher
+
+if [[ "$1" == "doodad" ]]; then
+ exec $@;
+fi
+
+exec ./sketchymaze $@
diff --git a/scripts/appimage.desktop b/scripts/appimage.desktop
new file mode 100644
index 0000000..d3dda5e
--- /dev/null
+++ b/scripts/appimage.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+Name=sketchy-maze
+GenericName=Maze Game
+X-GNOME-FullName=Sketchy Maze - A drawing-based maze game
+Comment=A drawing-based maze game.
+Icon=sketchymaze
+StartupNotify=true
+Keywords=game;maze;
+Categories=Game;
diff --git a/scripts/release.sh b/scripts/release.sh
index bcf77ef..677d1c3 100755
--- a/scripts/release.sh
+++ b/scripts/release.sh
@@ -15,6 +15,7 @@ export PATH="$PATH:$HOME/.local/share/gem/ruby/3.0.0/bin"
VERSION=`egrep -e 'Version\s+=' ./pkg/branding/branding.go | head -n 1 | cut -d '"' -f 2`
DIST_PATH="$(pwd)/dist/sketchymaze-${VERSION}"
+APPIMAGE_PATH="$(pwd)/dist/AppDir"
RELEASE_PATH="$(pwd)/dist/release/${VERSION}"
STAGE_PATH="$(pwd)/dist/stage/${VERSION}"
@@ -80,6 +81,12 @@ linux() {
../../../../scripts/fpm-bundle.sh
cp *.rpm *.deb "${RELEASE_PATH}/linux/"
+ # Does an AppImage exist?
+ ls -hal $APPIMAGE_PATH/*.AppImage
+ if [[ -d "$APPIMAGE_PATH" ]]; then
+ cp -v $APPIMAGE_PATH/*.AppImage "${RELEASE_PATH}/linux"
+ fi
+
# return
cd -
}