Skip to content

Launcher: take the game as an .nx archive - #632

Merged
featureJosh merged 1 commit into
mainfrom
claude/recompia-nx-format-support-e8c102
Nov 13, 2026
Merged

featureJosh merged 1 commit into
mainfrom
claude/recompia-nx-format-support-e8c102

Conversation

@featureJosh

Copy link
Copy Markdown
Collaborator

What it changes

The launcher took the game as a folder of extracted files or as a .nup. An .nx archive (NXFormat) had to be unpacked with another tool first.

Choose a .nup or .nx file (or dropping the file on the page) now unpacks an .nx once into nup_dump, in the layout a dump folder has (base/, updates/<version>/, aoc/<id>/romfs/), and the usual game files check runs on the result.

  • unpack.rs (new): the order of work a package is unpacked in, moved out of nup.rs behind a Package trait: every program's ExeFS and the main build ID check, the free-space check, then the chosen RomFS, each file written to .part and renamed once its size and SHA-256 match. Both formats go through it.
  • nup.rs: keeps what is .nup: its table of contents and the base game layered under an update.
  • nx.rs (new): reads header versions 0.2 and 0.3. The valid header with the highest generation is used (the other one when the newest generation is damaged); the Catalog, the Manifest and the block index are checked against their SHA-256 before anything is written; every table range and block range is bounds checked. A snapshot is a whole version of the game, so nothing is layered. Files are rows of stored or Zstandard blocks.
  • The commands, the event and the page state are named for packages: import_package, cancel_unpack, pick_package, unpack-progress.
  • New and changed messages are translated in the eight launcher languages; the READMEs name .nx next to .nup.

An .nx made straight from an .nsp or .xci holds the NCA packages themselves, which the launcher does not read (it does not read an .nsp or .xci of the game either). It is refused with a message that says to make the .nx from extracted files or from a .nup (nxconvert pack-tree or pack-nup).

Fixes #456

For players

  • CHANGELOG.md ## Unreleased has an entry (Before / Now / Still not), or this change is not player-facing
  • Needs Set up again / Finish update: no
  • Rebuilds shaders: no

Pros

  • One file in, no outside tool: an .nx goes through the same checks as a .nup (version before the big unpack, free space, per-file checksum).
  • One unpack pipeline for both package formats instead of one inside nup.rs.
  • An .nx unpack uses nup_dump too, so picking another package replaces the unpacked one and no second copy of the game is left on disk.

Cons

  • The game still runs from the unpacked files, so an .nx saves no disk space while playing, and the random-read speed NXFormat is built for does not apply. Serving the game straight from an .nx would be runtime work (Zstandard and block-mapped RomFS reads in nxrt) and is not part of this.
  • An .nx made from an .nsp or .xci is refused.
  • The folder keeps the name nup_dump and the marker .nup_done, although an .nx can be in it now.
  • The reader checks what it uses. The Catalog's display metadata (titles, icons, program tables) is not validated, and the per-slice CRC-32C table is not used: the SHA-256 of every whole file covers the same bytes.
  • Debt seen while here: the game's title id is known in three launcher files (saveimport.rs, nsp.rs, and now read by nx.rs from saveimport.rs), and the list of folders the launcher keeps (nup_dump among them) is repeated in repair.rs, update_apply.rs and writecheck.rs.

🤖 Generated with Claude Code

The launcher unpacked a .nup into nup_dump and took nothing else as one
file (#456). An .nx (NXFormat) is now unpacked the same way.

The order of work a package is unpacked in (every program's ExeFS and
the main build ID check, the free-space check, then the chosen RomFS,
each file to .part and renamed once its size and SHA-256 match) moves
out of nup.rs into unpack.rs, behind a Package trait. nup.rs keeps what
is .nup: its table of contents and the base layered under an update.

nx.rs reads the .nx: the valid header with the highest generation, the
Catalog, Manifest and block index against their SHA-256, the snapshots
that hold exefs/ and romfs/, and each file as its row of stored or
Zstandard blocks. A snapshot is a whole version, so nothing is layered.
An archive made straight from an .nsp or .xci holds NCA packages and is
refused with a message that says how to make a usable one.

The commands, the event and the page state are named for packages now
(import_package, cancel_unpack, pick_package, unpack-progress). The
folder stays nup_dump: one unpacked package, whichever format it was.

Co-Authored-By: Claude <noreply@anthropic.com>
@featureJosh
featureJosh merged commit 8a22efb into main Nov 13, 2026
3 checks passed
@featureJosh
featureJosh deleted the claude/recompia-nx-format-support-e8c102 branch November 13, 2026 16:33
@featureJosh featureJosh mentioned this pull request Nov 13, 2026
3 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Requesting support for NX Format

1 participant