The review of the packaging guard (b4c21998) found that the docstring line it edited in tools/make_appimage.py ran to
193 characters, where the rest of the docstring is wrapped at 120; the paragraph also held an older 144-character line.
The paragraph is rewrapped at 120 columns with its text unchanged.
Text only; the file still parses, and tools/check_content.py passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
build_xlate.py --id-only wrote an nx2navi_xlate.id for whatever exe sat in the folder, from the sources as they are,
so make_launcher's guard (check_xlate, which compares only the .id) passed an old exe beside a fresh .id. Nothing
calls the option; it is gone, and only a build writes an .id. make_release.check_translator compared build/xlate's .id
with build_xlate.identity(), which hashes the tree the last build prepared there, so a patch or vendor change since
that build passed unseen; make_appimage.py and make_kit.py checked nothing. The fresh-prepare identity moves from
make_launcher into build_xlate as source_identity(), and build_xlate.check_built(folder, exe) refuses a missing exe or
.id and an .id that differs from it. make_launcher, make_release, make_appimage and make_kit stop on its reason, each
before its downloads, builds or deletions: make_launcher's check moves from build_app to the top of main, before the
--out folder is deleted and the toolchain lock is resolved. A translator folder built from the current sources, as the
release scripts pass it (work\xlate_6866a13e), passes as before.
Not reproduced before the change beyond the audit's probes. tests/xlate_package_check.py (new) checks a matching
folder, missing files, another identity and a stale build (refused although identity() over its own tree equals its
.id), that --id-only is refused, and that make_launcher, make_release and make_kit stop on a foreign translator, the
kit before any download; check_built passes on work\xlate_6866a13e.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Linux every driver got shadow storage (copies of guest memory beside it), which exists for amdgpu, where importing guest memory costs the write protection of its pages. NVIDIA's own driver imports without that cost, so there the copies are only the slower path: in Kokiri Forest on 0.7.1 (RTX 4090) imports ran at 51.9 frames a second and the copies at 27.4. Until now only the AppImage's play.sh knew, by setting NX2NAVI_SHADOW=0 when NVIDIA's kernel driver was present at build time, so a game started any other way got the copies, and a PC with that kernel driver whose game ran on another card got imports where it should not. The game now chooses by the driver of the device it runs on, play.sh no longer sets the variable, and NX2NAVI_SHADOW=1 or 0 still decides. The driver is asked when the device is picked, before the storage is chosen.
Windows is unchanged: the device probe here reads "mem: mode mirror" with no shadow storage line, and the shadow line with NX2NAVI_SHADOW=1. The Linux path itself was not run: there is no Linux machine here.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The AppImage tested for zbic with PYTHONPATH and the user's site-packages in view, then ran the build with Python's isolated mode, which sees neither. A player with zbic installed for their own Python of the same minor version passed the test, never got it installed where the build looks, and was told to run the pip command that had put it in the place the build ignores. The test now uses the same isolation and the same search path as the build, so zbic is installed into the AppImage's own folder whenever the build could not import it.
From pull request #436.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
A player's AppImage build of 0.7.1 stopped in its compile step after eight minutes of RomFS work: four
files did not compile, because the kit builds with the system's compiler and headers and theirs were
older than the runtime needs. vk_pipeline.c and vk_device.c name VK_KHR_pipeline_binary,
VK_KHR_dynamic_rendering_local_read and VK_KHR_shader_maximal_reconvergence, which their Vulkan headers
did not declare, and ui/menu.cpp takes its font in with #embed, which clang has from version 19.
- Vulkan headers: tools/vulkan_pin.py holds the release the other builds use (1.4.363, the archive and
hash tools/make_release_linux.py already pinned, which now reads them from there). The AppImage carries
its C headers in toolchain/vulkan-headers and builds against them whatever the system has; a kit or a
source checkout uses the system's when they are at least that release and fetches the pinned ones
otherwise (build_game.py vulkan_include). Their folder goes first on the include path of the runtime's
sources only, so the lifted code's objects keep their keys, and a runtime object compiled before
against the system's headers is taken over instead of compiled again. AppRun no longer asks for the
system's Vulkan headers.
- #embed: tools/build_shaders.py also writes the font's bytes as runtime/ui/roboto_ttf.h (ignored by git,
carried by a kit), and menu.cpp includes that where the compiler has no __has_embed. With #embed
nothing changes.
- Before its long steps a Linux build that will compile now checks every runtime source that needs no
header of the install with the compile step's own command (clang -fsyntax-only) and links an empty
program against the game's libraries (make_game.py preflight): an old compiler, an old header or a
missing development package stops it in the first seconds with the compiler's own errors. A failed
compile names every file that failed, not only the three whose errors it prints.
Checked on Windows: tests/launcher_test.py passes with four new tests (117); the header of bytes and
#embed give the same 162,588 bytes, and both branches of menu.cpp compile; the early check passes on the
Windows file set with clang 23 and stops on files made to fail; the 34 local headers of release 363 are
the upstream tag's files by git blob id. Not run: anything on Linux, the pinned archive's download, a
compiler older than 23.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Started without arguments on a desktop (a double-click), the AppImage showed nothing. It now opens a
window (tools/appimage_gui.py, standard library and Pillow): the dump and the game folder through the
desktop's own file choosers, Install or Update with a progress bar per step, Play, the last run's output,
and an applications-menu entry for play.sh. The window runs AppRun --events, which does what the command
line does and prints make_game.py's progress lines plus its own for the package check and DLSS. Its text
is drawn with Pillow in the desktop's font and sized by the screen's DPI, in English or French by locale.
The command line is unchanged.
Pull request #291 by loteran. The window is taken as it is, with one change: the menu entry's Exec line
quotes the game folder by the desktop entry rules, so a folder name with a quote, a dollar or a percent
sign gives a working entry. The AppRun changes are applied by hand onto the script as it is now.
The script passes bash -n and the window a syntax check; neither was run, on Linux or elsewhere.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
An AppImage made with --no-dlss carries no NVIDIA file, and its builds had no DLSS. After a build its
AppRun now downloads the pinned libnvidia-ngx-dlss.so.<version> from NVIDIA's DLSS SDK repository when
/proc/driver/nvidia exists and the game folder holds no such library, checks its SHA-256 and writes the
notice that names its licence. NX2NAVI_NO_DLSS=1 skips it, and a failed download is a warning.
Pull request #290 by loteran, written again on top of the pin that came with the bundled library:
- the version, file name, checksum and address come from tools/dlss_pin.py when the AppImage is made,
instead of a second copy in the script, and the notice is dlss_pin's own text, carried in the kit;
- it runs only when no library is beside the game, so it adds nothing to a build that placed the kit's
and leaves a player's own version alone;
- the download goes to a name that does not start like the library's: the game takes any file with that
prefix, and an interrupted download would have been one.
The generated AppRun passes bash -n; nothing was run on Linux here.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
On Linux the game looks for libnvidia-ngx-dlss.so.<version> beside the executable, and the driver brings
only NGX's core, so the DLSS modes did nothing in every Linux build. tools/dlss_pin.py pins the Linux
library of the DLSS version it pins for Windows, with its own size and SHA-256; tools/make_appimage.py
puts it in the kit's bin/ with its notice (downloaded from NVIDIA's DLSS SDK repository and checked, or
--dlss; --no-dlss leaves it out), and tools/make_game.py copies it beside the game on Linux as it copies
the DLL on Windows, keeping a library the player put there.
Pull request #297 by mooki000, taken as it is; the builder's description is merged with the button art
option that came with the release workflow. On Windows place_dlss does what it did. No NVIDIA file is in
the repository.
tests/launcher_test.py passes with its two new tests (112 tests, Python 3.12 on Windows); the AppImage
was not built here.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The release is assembled on Windows, and the AppImage needs Linux (the translator's native build and
appimagetool), so releases carried no Linux download. .github/workflows/linux-appimage.yml runs when a
release is published, or by hand for a tag: it builds the translator, takes the button art from the
release's own app zip, runs tools/make_appimage.py, checks that the AppImage starts and uploads it with
its SHA-256 to that release. tools/make_appimage.py takes --prompt-art as make_kit.py does and bundles
pillow, so an AppImage build can draw the Xbox, PlayStation and keyboard prompts.
Pull request #273 by loteran, taken as it is. Added: the workflow installs glslc and spirv-tools, which
make_appimage.py needs since the runtime's shaders are compiled at build time.
The workflow does nothing until this file is on the repository's default branch on GitHub; from then on
every published release starts it, with write access to that release. It was not run here, and
make_appimage.py only passes a syntax check on Windows.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The fifteen headers of SPIR-V words under runtime/ are no longer tracked. tools/build_shaders.py builds all of them:
the GLSL with glslc, the SPIR-V assembly with spirv-as, and the two shaders assembled in Python from their scripts.
build_game.py builds the missing and the stale ones before it compiles the runtime, and the build kit, the launcher
release and the AppImage build them before they copy runtime/, so a player's PC still needs no shader compiler.
git ignores the headers and check_content.py refuses a compiled shader in a commit. The headers built this way are
byte for byte the ones removed here. vk_mvobj_fs.h is now mvobj_fs_spv.h, named like the others.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The Linux build linked libunwind for a frame walk the runtime no longer uses: platform/linux.c walks the stack with
libgcc's unwinder. make_game.py's Linux toolchain imports build_game.vma_include, so the kit carries that file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
make_game.py only knew MSYS2. On Linux it now does what tools/build_game.py's Linux path does:
- clang, clang++ and lld from PATH (checked at start), the system's headers and libraries, vk_mem_alloc.h from the
system or the pinned copy build_game.py fetches into toolchain/vma;
- the runtime's *_sdl.* files and platform/linux.c in place of the Win32 ones; no shim.c (ui/menu_sdl.cpp defines
menu_sdl_event), no windres, no DLLs to copy;
- -fdeclspec for C++, as third_party/ffx_api/ffx_api.h declares __declspec(dllexport) unconditionally;
- build_game.py's Linux link flags (-no-pie, noexecstack, rpath $ORIGIN, libstdc++ static) and libraries, plus
dav1d (the AV1 movies), libatomic and libunwind (the previous commit's plat_frame_capture);
- ocarina and nx2navi_xlate without .exe; the translator from the kit's bin/ or a checkout's build/xlate.
Windows is unchanged: every difference is under os.name.
tools/make_appimage.py packs the kit (tools, recomp, runtime, the built translator, VMA) with a relocatable CPython 3.14
and numpy, lz4, zstandard and fonttools into NX2navi-Linux-<version>-x86_64.AppImage. Its AppRun checks for the
compiler and headers and names the packages for Arch, Fedora and Debian/Ubuntu, installs zbic (GPL-2.0, not bundled)
with pip into ~/.local/share/nx2navi/pydeps on the first run, picks --jobs from the memory, builds and writes play.sh
beside the game. README-BuildKit.md has a Linux section.
Tested on CachyOS (kernel 7.3, clang 23, RTX 3080, NVIDIA 620.70.06, 16 GB): make_game.py --nup ... --jobs 4 builds
ocarina in 9.9 minutes from a 1.1.1 dump, which passes --probe-cfg; a build with the same sources and flags
(compiled by hand before this script could) starts, loads a save and plays. With one compile per thread on 16 GB
the build filled memory and swap and the kernel stopped desktop processes, hence the --jobs advice.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>