Something went wrong. Try again.
An IDE for creating Paper Mario DX mods docs.starhaven.dev/develop
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230# SPDX-FileCopyrightText: 2026 Star Haven contributors## SPDX-License-Identifier: AGPL-3.0-or-later
{ description = "Diorama64 - a Theia-based IDE for Paper Mario DX modding";
inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-parts.url = "github:hercules-ci/flake-parts"; treefmt-nix.url = "github:numtide/treefmt-nix"; papermario-dx.url = "github:bates64/papermario-dx"; papermario-dx.inputs.nixpkgs.follows = "nixpkgs"; };
outputs = inputs@{ flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } { systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
imports = [ inputs.treefmt-nix.flakeModule ];
perSystem = { pkgs, lib, system, ... }: let nodejs = pkgs.nodejs_22; yarn = pkgs.yarn.override { inherit nodejs; }; electronRuntimeDeps = with pkgs; [ glib nss nspr atk at-spi2-atk libxcomposite libxdamage libxrandr libxfixes libxcursor libxcb libx11 libxi libxext libxrender libxtst libxscrnsaver libxkbcommon libxkbfile pango cairo cups dbus expat gtk3 gdk-pixbuf mesa libgbm alsa-lib libdrm libGL libGLU ]; electronLibs = lib.optionalString pkgs.stdenv.isLinux (lib.makeLibraryPath electronRuntimeDeps);
aresSupported = lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.ares;
# nixpkgs' ares, patched with a GDB "monitor reload" command (see # nix/ares/0001-gdb-monitor-reload.patch), a headless mode that # streams video/input over a socket instead of opening a window # (nix/ares/0003-headless.patch) and reads and writes memory over it # (nix/ares/0005-headless-memory.patch), a GDB stub that shows # libultra's threads (nix/ares/0004-libultra-threads.patch), and built # with only the Nintendo 64 core, since that's the only system # diorama64 uses. # app/scripts/download-ares.mjs applies the same patches when # building ares from source for macOS and Windows, so all three # platforms ship the same patched, N64-only ares. ares = pkgs.ares.overrideAttrs (old: { src = pkgs.fetchzip { url = "https://github.com/ares-emulator/ares/releases/download/v148/ares-source.tar.gz"; hash = "sha256-LXLt4hYjpnLrzu+0dLfXr4lEF7drZwSRjgaCAaD79+g="; }; patches = (old.patches or [ ]) ++ [ ./nix/ares/0001-gdb-monitor-reload.patch ./nix/ares/0002-n64-only-desktop-ui-sources.patch ./nix/ares/0003-headless.patch ./nix/ares/0004-libultra-threads.patch ./nix/ares/0005-headless-memory.patch ]; cmakeFlags = (old.cmakeFlags or [ ]) ++ [ "-DARES_CORES=n64" ]; });
# Where .tangled/workflows/release.yml uploads AppImages and the # latest-linux.yml that names the current one. releaseBaseUrls = { x86_64-linux = "https://starhaven.fsn1.your-objectstorage.com/diorama64/releases"; }; in { treefmt = { projectRootFile = "flake.nix"; programs.nixfmt.enable = true; programs.prettier = { enable = true; includes = [ "*.ts" "*.tsx" "*.js" "*.jsx" "*.json" "*.css" "*.html" "*.yaml" "*.yml" "*.md" ]; excludes = [ "node_modules/**" ]; }; };
devShells.default = pkgs.mkShell { packages = [ nodejs yarn pkgs.python311 # node-gyp imports distutils, removed from pkgs.python3 in nixpkgs pkgs.pkg-config ] ++ lib.optionals pkgs.stdenv.isLinux [ pkgs.libsecret # for keytar (credential storage) pkgs.libx11 pkgs.libxkbfile ] # A development checkout vendors no emulator, so running and # debugging a mod uses the one on PATH. ++ lib.optionals aresSupported [ ares ];
LD_LIBRARY_PATH = electronLibs; };
packages = # ares publishes no Linux binary, so app/scripts/download-ares.mjs # bundles this one into the packaged app. Exposed here rather than # taken from a registry so flake.lock pins which build that is. lib.optionalAttrs aresSupported { inherit ares; } # The default is a launcher rather than a fixed-output derivation: it # resolves the current release at run time, so no version or hash is # pinned in this repo. // lib.optionalAttrs (releaseBaseUrls ? ${system}) { default = pkgs.symlinkJoin { name = "diorama64"; paths = [ (pkgs.writeShellApplication { name = "diorama64"; runtimeInputs = with pkgs; [ curl yq-go openssl coreutils ]; text = '' base="${releaseBaseUrls.${system}}" cache="''${XDG_CACHE_HOME:-$HOME/.cache}/diorama64" mkdir -p "$cache"
metadata=$(curl -fsSL "$base/latest-linux.yml") file=$(yq -r '.path' <<<"$metadata") expected=$(yq -r '.sha512' <<<"$metadata") appimage="$cache/$file"
if [ ! -e "$appimage" ]; then echo "Downloading $file..." >&2 curl -fSL --progress-bar -o "$appimage.part" "$base/$file"
actual=$(openssl dgst -sha512 -binary "$appimage.part" | base64 -w0) if [ "$actual" != "$expected" ]; then rm -f "$appimage.part" echo "Checksum mismatch for $file" >&2 exit 1 fi
mv "$appimage.part" "$appimage" chmod +x "$appimage"
# Keep only the release we just fetched. find "$cache" -maxdepth 1 -name '*.AppImage' ! -name "$file" -delete fi
# Nix owns updates here, so keep the in-app updater out of it. export DIORAMA64_DISABLE_UPDATER=1 # Run without needing FUSE on the host. export APPIMAGE_EXTRACT_AND_RUN=1 export LD_LIBRARY_PATH="${electronLibs}''${LD_LIBRARY_PATH:+:}''${LD_LIBRARY_PATH:-}" exec "$appimage" "$@" ''; }) (pkgs.makeDesktopItem { name = "diorama64"; exec = "diorama64"; icon = "diorama64"; desktopName = "Diorama64"; genericName = "Paper Mario DX Modding IDE"; categories = [ "Development" ]; startupWMClass = "diorama64"; }) ] ++ lib.optional (lib.pathExists ../app/icons/icon.svg) ( pkgs.runCommand "diorama64-icon" { } '' mkdir -p $out/share/icons/hicolor/scalable/apps cp ${../app/icons/icon.svg} $out/share/icons/hicolor/scalable/apps/diorama64.svg '' ); }; }; }; };}