Saltar al contenido
PORTSNATIVE.
InicioCatálogo
Juegos WebEmuladoresHerramientasNovedades
PORTSNATIVE.

Un catálogo para descubrir ports y proyectos relacionados. Enlazamos a las fuentes oficiales y no alojamos archivos de los juegos originales.

ExplorarCatálogoMi lista
InformaciónNosotrosProponer un portSoporteApoyo y donacionesAviso legal
© 2026 PortsNative
Volver al catálogo
Pokémon Sword
PORTSNATIVE

Pokémon Sword

PORT NATIVOROL / RPGWINDOWSLINUXMACOSALPHA

Pokémon Sword

TecnologíaPort Nativo C/C++ (Reimplementación de Motor)

Disponible paraWindows, Linux, macOS

Ver proyecto oficial

Sobre el proyecto

Pokémon Sword es un videojuego de rol publicado por Nintendo en 2019.

Información oficial del proyecto

README original del autor (en inglés)Abrir en GitHub ↗

pokesword-decomp

progress verify

<!-- STATUS:BEGIN generated by tools/progress_json.py - do not edit by hand -->
modulematchedtotal%
main2958310400428.44%
sdk64452666224.17%
subsdk01080983810.98%
subsdk116451153014.27%
total3875315206225.48%
<!-- STATUS:END -->

Two percentages, both correct. This project's headline is 25.48% by function count (38,753 / 152,062). decomp.dev reports 0.67%, which is byte-weighted (413316 / 38,172,368 bytes of code). They diverge because everything matched so far is a tiny accessor — the median matched function is 8 bytes (ldr ; ret) while the median unmatched one is 132 bytes and the largest is 239 KB. Byte-weighting is the harsher and more honest measure of how much code is recovered, and it is what comparable projects show, so quote it when comparing against other decompilation projects. Full breakdown in decomp/docs/progress_weighting.md, including why the remaining branch-free bodies are nearly worthless byte-wise.

Decompilation of Pokemon Sword (title 0100ABF008968000, US v0) for Nintendo Switch, laid out as a standard decomp.me / decomp.dev project and structured as a fork of notyourav/pokesword.

This is Game Freak's "orion" engine: native ARM64 C++. There is no IL2CPP metadata in RomFS, so all game code lives in the main NSO module and is recovered by static analysis.

Status

Matching means byte-identical instructions under the project's own toolchain — Clang 5.0.1 plus the ToolchainNX64.cmake flags. Behavioural equivalence does not count, and matching under a different compiler does not either.

The table above is generated by tools/progress_json.py, which parses tools/match_progress.py rather than recomputing the count. That is deliberate: two implementations of a counting rule drift, and the drift is invisible because both numbers look plausible. It already happened here — tools/keepalive.py reported 26,544 where match_progress.py reported 26,536, with a docstring that confidently invented a reason for the gap.

Every function currently emitted re-verifies byte-identically: all four modules verify 100% clean, with no outstanding mismatches and no false-positive results. That is a stronger claim than the percentage and it is checked separately — see Verification.

What remains

<!-- BEGIN readme_classes -->

The remaining 113,137 functions are dominated by real control flow.

classbodiesnature
branchy-calls74,239branches plus calls; genuine decompilation
branchy11,483branches, no call
linear-with-calls15,892branch-free, but makes calls
branch-free7,356branch-free, partially tractable
tailcall3,265argument-setup prefix plus b; the branch IS the return
undecodable902did not disassemble

Largest shapes among the unmatched, by shape_of:

shapebodies
tailcall3,265
diamond2,689
indirect-tailcall1,096
compare298
straight265
guarded251
struct-copy87

Generated by tools/readme_classes.py. The table used to be written by hand, which is how it came to describe 125,500 remaining functions when the figure was 114,209.

<!-- END readme_classes -->

decomp/docs/yield_sweep.md is a per-generator census of which registered generators actually produce anything — the most productive line of work in this project has been fixing generators that were written, reachable, and silently broken, rather than adding new ones.

Verification

Three independent checks are required before any figure is reported, in order:

  1. single function — python tools/verify_one.py main 0x1ce0 body.cpp --asm
  2. batch / linked-image asm-differ — python tools/verify_matches.py --module main
  3. full project build — python tools/build_nx64.py

A number that skipped a step is not reported. The figure that counts is the emitted-body count from tools/match_progress.py, never a generator's MATCH x / y line — that is a hit rate, not a delta, and this project has mistaken it for a delta twice.

The verify job in .github/workflows/progress.yml runs check 2 across all four modules on every push and fails the build on any mismatch. It requires Clang 5.0.1 via the repository secret CLANG5_BIN and will not substitute a system clang, because matching under a different compiler is not matching.

What is recovered

componentcountwhere
native functions (5 NSO modules)152,062prog/, decomp/<mod>/
translated instruction blocks2,328,210linked from exefs/<mod>/src
Pawn event/AI scripts691decomp/script/
RomFS assets inventoried42,693decomp/docs/asset_inventory.md
RTTI class/namespace names1,873data/rtti_classes.csv

Every one of the 152,062 functions has a declaration, a symbol and an entry in data/functions.csv.

What is matched

Recovery is not matching. A function counts as matched only when a C++ body compiles to the same assembly as the original — verified by compiling it for aarch64-none-elf and comparing against data/<module>.elf, then re-checked with asm-differ.

python tools/match_progress.py            # recovery + matching, separately
python tools/match_progress.py --by-shape # where the matches come from

Details, including how a match is established and what is not matched yet, are in decomp/docs/matching.md.

Layout

This mirrors upstream pokesword:

prog/            game source, grouped by subsystem, namespaced C++
  contents/      bag, battle, field, item, pokemon, trainer
  gfx/           render, physics
  system/        audio, net, save
  ui/            manager
  lib/           gflib3
  <module>/      the remaining recovered functions, per NSO module
lib/             NintendoSDK (nnheaders submodule) + gflib3, external deps
data/            the original binaries as ELF, symbol tables, script tables
  main.elf sdk.elf subsdk0.elf subsdk1.elf rtld.elf
  functions.csv  module,addr,name,size,decomp_name
  scripts.csv    per-script Pawn metadata
  rtti_classes.csv
tools/           asm-differ, diff.py, check.py, print_decomp_symbols.py,
                 plus the analysis and code-generation scripts
decomp/          the equivalence-checked decompilation
  <mod>/fn_*.c   named function wrappers over the unmodified instruction blocks
  script/        *.pasm disassembly + *.pseudo.c pseudocode
  docs/          verification and asset documentation
exefs/           the original static translation (source of the blocks)
work/            analysis intermediates (segments, symbols, xrefs, strings)

Building

Host verification build

Compiles the recovered code natively so the decompilation can actually be run and diffed. Needs CMake and MSVC (or clang).

cmake -S . -B build_host -G "Visual Studio 17 2022" -A x64
cmake --build build_host --config Release

This produces one binary per module in build_host/bin/:

decompiled_rtld.exe  decompiled_main.exe  decompiled_sdk.exe
decompiled_subsdk0.exe  decompiled_subsdk1.exe

NX64 matching build

Cross-compiles for Switch the way a matching decomp project builds. Needs devkitA64 and Clang 5.0.1 (see ToolchainNX64.cmake and the Dockerfile).

git submodule update --init --recursive
cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo \
      -DCMAKE_TOOLCHAIN_FILE=ToolchainNX64.cmake -B build
ninja -C build

How equivalence is established

The decompiled binaries are not a reimplementation in the "we rewrote it by hand" sense, and the project does not claim they are. Each recovered function is a named C++ function that drives the original, unmodified per-instruction instruction blocks from exefs/ through a PC-range dispatch loop. Semantics are therefore identical to the shipped translation by construction, and the project proves it empirically:

  • Block coverage — every one of the 2,328,210 instruction blocks lies inside exactly one recovered function, in every module.
  • Differential tracing — stock translated.exe vs decompiled_<mod>.exe, run headless from a clean state and their stderr compared byte for byte. See decomp/docs/verification.md for the measured line counts.
  • Assembly differ — data/<mod>.elf is a real AArch64 ELF rebuilt from the NSO, with a full symbol table, so asm-differ disassembles and compares against it.

What this decompilation adds over the flat translation: real function boundaries (from the compiler's own unwind tables), names, a call graph, string references, RTTI-derived class hierarchy, and a source tree organised the way a normal software project would be.

Diffing against the original

python tools/diff.py --module main <function-name>

tools/diff_settings.py selects the module (default main) and resolves the ELF and the built binary for it. On Windows it uses LLVM's llvm-objdump; override with OBJDUMP=/path/to/objdump.

Regenerating

Everything machine-generated can be rebuilt from work/:

python tools/nso_to_elf.py --all     # data/<mod>.elf from the decompressed NSO
python tools/auto_match.py --module main --all-shapes \
       --report data/matched_main.json   # synthesise + verify matching bodies
python tools/decomp_project.py --all # data/functions.csv + prog/ tree
python tools/prog_cmake.py           # prog/**/CMakeLists.txt
python tools/pawn_emit.py            # data/scripts.csv + data/scripts.json
python tools/rtti_names.py --write   # data/rtti_classes.csv
python tools/ghidra_run.py --all     # Ghidra decompilation of the rest

Checking the work

python tools/audit.py            # 40 checks, re-derived from the files on disk
python tools/progress.py         # recovery coverage
python tools/match_progress.py   # matching coverage
python tools/verify_matches.py   # independently recompile + re-verify every match
python tools/verify_all.py       # the whole pipeline in dependency order
python tools/audit.py --quick    # skip the slow cross-compile sweep

Reverse engineering with Ghidra

The functions that auto_match.py cannot solve mechanically - 114,055 of them, by the registry census above (114,209 by match_progress.py, which also counts 154 bodies the harness verified but the emitter declines as unlinkable) - containing calls, branches, loops and vtable dispatch - need to be understood, not just transcribed. tools/ghidra_run.py drives Ghidra's decompiler headlessly over exactly those functions:

python tools/ghidra_run.py --module main
python tools/ghidra_run.py --all --sec-per-fn 25

Output lands in work/ghidra_out/<module>.c.txt as one C-like body per function, with the address, name, size and signature in the header. Runs are resumable.

It imports data/<module>.elf, which already carries the recovered function boundaries and 11,507 real names as ELF symbols, then disassembles each body and wires direct branches to the functions they land on before decompiling. That preparation matters: without it the decompiler emits indirect calls through data instead of named calls, which loses the call graph — the single most useful thing the output provides.

Ghidra's output is a starting point for a person, not matching code, and this project does not claim otherwise. It supplies the body, a signature and the call graph; turning that into C++ that assembles identically is the per-function work CONTRIBUTING.md describes.

Notes

  • The ROM's NCA containers are card-descriptor form and do not decrypt with standard keycrypto, so decrypted artifacts already produced by an external exporter are reused. See decomp/docs/keys_and_rom.md.
  • Deep .prmb data-table formats are left to the community swordshield-data project; the headers are identified and documented.
Ver proyecto oficial
CALIFICACIÓN
—
Cargando votos…
Publicidad

FICHA DEL PROYECTO

Tipo de proyecto
PORT NATIVO
Género
Rol / RPG
Estado
alpha
Plataforma de origen
—
Tecnología
Port Nativo C/C++ (Reimplementación de Motor)
Versión
—
Actualización
—

Plataformas de destino 3

Windows
Linux
macOS
Ver en GitHub
Publicidad