diff --git a/AppImage-build-debian-inner.sh b/AppImage-build-debian-inner.sh
new file mode 100755
index 000000000..34aa7252a
--- /dev/null
+++ b/AppImage-build-debian-inner.sh
@@ -0,0 +1,83 @@
+#! /bin/bash
+set -e
+
+# Make sure script is called from inside our container
+test -e /tmp/torzu-src-ro || (echo "Script MUST NOT be called directly!" ; exit 1)
+
+# Set up environment
+export LANG=C.UTF-8
+export LC_ALL=C.UTF-8
+unset LC_ADDRESS LC_NAME LC_MONETARY LC_PAPER LC_TELEPHONE LC_MEASUREMENT LC_TIME
+
+# Raise max open files count
+ulimit -n 50000
+
+# Install dependencies
+apt -y install cmake ninja-build build-essential autoconf pkg-config locales wget git file mold libtool lsb-release wget software-properties-common gnupg \
+ qtbase5-dev qtmultimedia5-dev qtbase5-private-dev glslang-tools libssl-dev libavcodec-dev libavfilter-dev libavutil-dev libswscale-dev libpulse-dev libasound2-dev
+if [ ! "$BUILD_USE_CPM" = 1 ]; then
+ apt -y install libfmt-dev libenet-dev liblz4-dev nlohmann-json3-dev zlib1g-dev libopus-dev libsimpleini-dev libstb-dev libzstd-dev libusb-1.0-0-dev libcubeb-dev libcpp-jwt-dev libvulkan-dev gamemode-dev libasound2-dev libglu1-mesa-dev libxext-dev mesa-common-dev libva-dev
+
+ if [ ! -f /usr/local/lib/cmake/Boost-1.88.0/BoostConfigVersion.cmake ]; then
+ # Install Boost
+ wget https://archives.boost.io/release/1.88.0/source/boost_1_88_0.tar.bz2
+ echo "Extracting Boost sources..."
+ tar xf boost_1_88_0.tar.bz2
+ cd boost_1_88_0
+ ./bootstrap.sh
+ ./b2 install --with-{headers,context,system,fiber,atomic,filesystem} link=static
+ cd ..
+ rm -rf boost_1_88_0 boost_1_88_0.tar.bz2
+ fi
+fi
+
+# Install Clang
+if ([ "$BUILD_USE_CLANG" = 1 ] && ! clang-19 --version); then
+ cd /tmp
+ wget https://apt.llvm.org/llvm.sh
+ chmod +x llvm.sh
+ ./llvm.sh 19
+ rm llvm.sh
+fi
+
+# Mount Torzu sources with temporary overlay
+cd /tmp
+mkdir torzu-src-upper torzu-src-work torzu-src
+mount -t overlay overlay -olowerdir=torzu-src-ro,upperdir=torzu-src-upper,workdir=torzu-src-work torzu-src
+
+# Get extra configuration/compilation options
+EXTRA_COMPILE_FLAGS=""
+EXTRA_CMAKE_FLAGS=""
+if [ "$BUILD_USE_CLANG" = 1 ]; then
+ EXTRA_CMAKE_FLAGS="-DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19"
+ FATLTO_FLAG="-flto=full"
+else
+ FATLTO_FLAG="-flto"
+fi
+if [ "$BUILD_USE_THIN_LTO" = 1 ]; then
+ EXTRA_COMPILE_FLAGS="-flto=thin"
+fi
+if [ "$BUILD_USE_FAT_LTO" = 1 ]; then
+ EXTRA_COMPILE_FLAGS="$FATLTO_FLAG"
+fi
+if [ "$BUILD_USE_CPM" = 1 ]; then
+ EXTRA_CMAKE_FLAGS="$EXTRA_CMAKE_FLAGS -DYUZU_USE_CPM=ON"
+fi
+
+# Build Torzu
+cd /tmp
+mkdir torzu-build
+cd torzu-build
+cmake /tmp/torzu-src -GNinja -DCMAKE_BUILD_TYPE=Release -DYUZU_TESTS=OFF -DENABLE_QT_TRANSLATION=OFF -DSPIRV_WERROR=OFF -DCMAKE_FIND_LIBRARY_SUFFIXES=".a;.so" -DSPIRV-Headers_SOURCE_DIR=/tmp/torzu-src/externals/SPIRV-Headers -DCMAKE_{C,CXX}_FLAGS="$EXTRA_COMPILE_FLAGS -fdata-sections -ffunction-sections" -DCMAKE_{EXE,SHARED}_LINKER_FLAGS="-Wl,--gc-sections" $EXTRA_CMAKE_FLAGS
+ninja || (
+ echo "Compilation has failed. Dropping you into a shell so you can inspect the situation. Run 'ninja' to retry and exit shell once compilation has finished successfully."
+ echo "Note that any changes made here will not be reflected to the host environment, but changes made from the host environment will be reflected here."
+ bash
+)
+
+# Generate AppImage
+cp -rv /tmp/torzu-src/AppImageBuilder /tmp/AppImageBuilder
+cd /tmp/AppImageBuilder
+./build.sh /tmp/torzu-build /tmp/torzu.AppImage || echo "This error is known. Using workaround..."
+cp /lib/$(uname -m)-linux-gnu/libICE.so.6 build/
+mv build /tmp/hosttmp/torzu-debian-appimage-rootfs
diff --git a/AppImage-build-debian.sh b/AppImage-build-debian.sh
new file mode 100755
index 000000000..3a8836e04
--- /dev/null
+++ b/AppImage-build-debian.sh
@@ -0,0 +1,73 @@
+#! /bin/bash
+set -e
+
+# Parse options
+for i in "$@"
+do
+case $i in
+ -l|--clang)
+ export BUILD_USE_CLANG=1
+ echo "-> Using Clang for compilation."
+ ;;
+ -o|--thin-lto)
+ export BUILD_USE_THIN_LTO=1
+ echo "-> Thin link time optimization enabled."
+ ;;
+ -O|--fat-lto)
+ export BUILD_USE_FAT_LTO=1
+ echo "-> Fat link time optimization enabled."
+ ;;
+ -p|--use-cpm)
+ export BUILD_USE_CPM=1
+ echo "-> Using CPM to download most dependencies."
+ ;;
+ -k|--keep-rootfs)
+ BUILD_KEEP_ROOTFS=1
+ echo "-> Not deleting rootfs after successful build."
+ ;;
+ *)
+ echo "Usage: $0 [--clang/-l] [--thin-lto/-o] [--fat-lto/-O] [--use-cpm/-p] [--keep-rootfs/-k]"
+ exit 1
+ ;;
+esac
+done
+
+# Make sure options are valid
+if [ "$BUILD_USE_THIN_LTO" = 1 ] && [ "$BUILD_USE_CLANG" != 1 ]; then
+ echo "Thin LTO can't be used without Clang!"
+ exit 2
+fi
+if [ "$BUILD_USE_THIN_LTO" = 1 ] && [ "$BUILD_USE_FAT_LTO" = 1 ]; then
+ echo "Only either thin or fat LTO can be used!"
+ exit 2
+fi
+
+# Get citron source dir
+citron_SOURCE_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
+echo "-> Source dir is $citron_SOURCE_DIR"
+rm -rf "$citron_SOURCE_DIR/AppImageBuilder/build"
+
+# Generate debian rootfs
+cd /tmp
+echo "Cleaning up before build..."
+rm -rf citron-debian-appimage-rootfs
+[ -d rootfs-citron-appimage-build ] ||
+ debootstrap stable rootfs-citron-appimage-build http://deb.debian.org/debian/
+bwrap --bind rootfs-citron-appimage-build / \
+ --unshare-pid \
+ --dev-bind /dev /dev --proc /proc --tmpfs /tmp --ro-bind /sys /sys --dev-bind /run /run \
+ --tmpfs /var/tmp \
+ --chmod 1777 /tmp \
+ --ro-bind /etc/resolv.conf /etc/resolv.conf \
+ --ro-bind "$citron_SOURCE_DIR" /tmp/citron-src-ro \
+ --chdir / \
+ --tmpfs /home \
+ --setenv HOME /home \
+ --bind /tmp /tmp/hosttmp \
+ /tmp/citron-src-ro/AppImage-build-debian-inner.sh
+appimagetool citron-debian-appimage-rootfs citron.AppImage
+echo "AppImage generated at /tmp/citron.AppImage! Cleaning up..."
+rm -rf citron-debian-appimage-rootfs
+if [ ! "$BUILD_KEEP_ROOTFS" = 1 ]; then
+ rm -rf rootfs-citron-appimage-build
+fi
diff --git a/AppImage-build-local.sh b/AppImage-build-local.sh
new file mode 100755
index 000000000..81eda3feb
--- /dev/null
+++ b/AppImage-build-local.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+FILE=build/bin/citron
+if test -f "$FILE"; then
+ # remove any previously made AppImage in the base citron git folder
+ rm ./citron.AppImage
+
+ # enter AppImage utility folder
+ cd AppImageBuilder
+
+ # run the build script to create the AppImage
+ # (usage) ./build.sh [source citron build folder] [destination .AppImage file]
+ ./build.sh ../build ./citron.AppImage
+
+ FILE=./citron.AppImage
+ if test -f "$FILE"; then
+ # move the AppImage to the main citron folder
+ mv citron.AppImage ..
+ # return to main citron folder
+ cd ..
+ # show contents of current folder
+ echo
+ ls
+ # show AppImages specifically
+ echo
+ ls *.AppImage
+ echo
+ echo "'citron.AppImage' is now located in the current folder."
+ echo
+ else
+ cd ..
+ echo "AppImage was not built."
+ fi
+else
+ echo
+ echo "$FILE does not exist."
+ echo
+ echo "No citron executable found in the /citron/build/bin folder!"
+ echo
+ echo "You must first build a native linux version of citron before running this script!"
+ echo
+fi
diff --git a/AppImageBuilder/assets/AppRun b/AppImageBuilder/assets/AppRun
new file mode 100755
index 000000000..37dbb8a30
--- /dev/null
+++ b/AppImageBuilder/assets/AppRun
@@ -0,0 +1,11 @@
+#! /bin/bash
+
+cd "$APPDIR"
+
+if [ -d /usr/lib/$(uname -m)-linux-gnu/qt5 ] || [ -d /usr/lib/qt ]; then
+ # System-wide Qt5
+ exec ./citron.sh "$@"
+else
+ # Bundled Qt5
+ exec ./citron-bqt.sh "$@"
+fi
diff --git a/AppImageBuilder/assets/citron-bqt.sh b/AppImageBuilder/assets/citron-bqt.sh
new file mode 100755
index 000000000..3234529cb
--- /dev/null
+++ b/AppImageBuilder/assets/citron-bqt.sh
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+LD_LIBRARY_PATH=./qt5:/usr/lib/$(uname -m)-linux-gnu:/usr/lib:. QT_PLUGIN_PATH=./qt5 exec ./citron "$@"
diff --git a/AppImageBuilder/assets/citron.desktop b/AppImageBuilder/assets/citron.desktop
new file mode 100644
index 000000000..1822831df
--- /dev/null
+++ b/AppImageBuilder/assets/citron.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Application
+Name=citron
+Icon=citron
+Exec=AppRun
+Categories=Game;
diff --git a/AppImageBuilder/assets/citron.sh b/AppImageBuilder/assets/citron.sh
new file mode 100755
index 000000000..93a605792
--- /dev/null
+++ b/AppImageBuilder/assets/citron.sh
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+LD_LIBRARY_PATH=/usr/lib/$(uname -m)-linux-gnu:/usr/lib:. exec ./citron "$@"
diff --git a/AppImageBuilder/assets/citron.svg b/AppImageBuilder/assets/citron.svg
new file mode 100644
index 000000000..3db81d5d7
--- /dev/null
+++ b/AppImageBuilder/assets/citron.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/AppImageBuilder/assets_aarch64/.gitkeep b/AppImageBuilder/assets_aarch64/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/AppImageBuilder/assets_aarch64/bwrap b/AppImageBuilder/assets_aarch64/bwrap
new file mode 100644
index 000000000..782d76601
Binary files /dev/null and b/AppImageBuilder/assets_aarch64/bwrap differ
diff --git a/AppImageBuilder/assets_aarch64/bwrap-info.txt b/AppImageBuilder/assets_aarch64/bwrap-info.txt
new file mode 100644
index 000000000..0178b387d
--- /dev/null
+++ b/AppImageBuilder/assets_aarch64/bwrap-info.txt
@@ -0,0 +1 @@
+This is a statically compiled bubblewrap 0.9.0 executable.
diff --git a/AppImageBuilder/assets_x86_64/bwrap b/AppImageBuilder/assets_x86_64/bwrap
new file mode 100755
index 000000000..a5dd85cc1
Binary files /dev/null and b/AppImageBuilder/assets_x86_64/bwrap differ
diff --git a/AppImageBuilder/assets_x86_64/bwrap-info.txt b/AppImageBuilder/assets_x86_64/bwrap-info.txt
new file mode 100644
index 000000000..0178b387d
--- /dev/null
+++ b/AppImageBuilder/assets_x86_64/bwrap-info.txt
@@ -0,0 +1 @@
+This is a statically compiled bubblewrap 0.9.0 executable.
diff --git a/AppImageBuilder/build.sh b/AppImageBuilder/build.sh
new file mode 100755
index 000000000..13f1c45ce
--- /dev/null
+++ b/AppImageBuilder/build.sh
@@ -0,0 +1,170 @@
+#! /bin/bash
+set -e
+
+# Check arguments
+if [[ $# != 2 ]]; then
+ >&2 echo "Bad usage!"
+ echo "Usage: $0