Skip to main content

rpycdec

PyPI Python versions License: MIT tests

A tool for decompiling Ren'Py compiled script files (.rpyc and .rpymc) back to readable .rpy source. It reads scripts compiled by Ren'Py 7 and 8, and is tested against 7.6.3, 8.2.3, 8.4.1 and 8.5.3.

Features

What it does Command Notes
Decompile a script, or a whole game rpycdec decompile Ren'Py 7.x and 8.x
Inspect a compiled script, or compare two rpycdec dump what the .rpyc carries, not just the source
Extract an RPA archive, all or part of it rpycdec unrpa filter by path expression or suffix
Build an RPA archive rpycdec rpa files or whole directories
Pull the game out of an Android APK rpycdec extract-game
Write a game's translations out rpycdec extract-translate to tl/<language>/
Take a save file apart and put it back rpycdec save .save to JSON and back, re-signing included

The decompiled source is checked by compiling it again and comparing the two structures, against fixtures and the scripts the Ren'Py SDKs ship: see Testing.

Installation

Needs Python 3.10 or newer.

pip install rpycdec

To work on rpycdec itself, install it from a clone in editable mode, which brings the linter along:

git clone https://github.com/cnfatal/rpycdec.git
cd rpycdec
pip install -e ".[dev]"

The wheel also installs the renpy and store packages the tool uses to rebuild a script's objects, so keep it out of an environment where the real Ren'Py is installed.

Usage

<required>, [optional], ... repeats, -v for verbose output.

# decompile a file, or every .rpyc / .rpymc under a directory
# -o writes somewhere else, -d also prints the pickle disassembly
rpycdec decompile <path>... [-o <dir>] [-d]

# print the structure a compiled script carries, or diff it against another
# file names, line numbers and the like are left out: no decompiler can keep
rpycdec dump <path> [<other>]

# extract an rpa archive, or just the files matching a path
# -e takes a regular expression, -s a suffix; both may be repeated
rpycdec unrpa <archive.rpa> [-o <dir>] [-e <regex>]... [-s <suffix>]...

# build an rpa archive, naming the files inside relative to --base
rpycdec rpa <path>... -o <archive.rpa> [--base <dir>]

# pull the game out of an Android APK
rpycdec extract-game <game.apk> [-o <dir>]

# write a game's translations to tl/<language>/
rpycdec extract-translate <game-dir>... -l <language> [-o <dir>]
rpycdec extract-translate <game-dir> -l Chinese --no-strings --empty

# take a save file apart into JSON, edit it, put it back together
rpycdec save extract <save> [<dir>] [-d] [-V]
rpycdec save restore <dir> [<save>] [-k <security_keys.txt>]
rpycdec save info <save>
rpycdec save genkey [<security_keys.txt>]

# for example
rpycdec decompile /path/to/game/ -o out/
rpycdec dump script.rpyc script.roundtrip.rpyc
rpycdec unrpa archive.rpa -s .rpy .rpyc

Security Warning

This tool processes .rpyc, .rpymc, .rpa, and .save files which use Python's pickle format internally. rpycdec uses restricted unpicklers with whitelist-based class loading to mitigate arbitrary code execution risks, but no pickle safeguard is perfect. Only process files from sources you trust.

Set RPYCDEC_NO_WARNING=1 to suppress the CLI security warning. What the restricted unpicklers allow, and how to report a vulnerability privately, is in SECURITY.md.

See also: Python pickle security warning

Troubleshooting

  • Q: Pickle error ModuleNotFoundError: No module named '...'

    A: This means our fake renpy/store packages don't cover the class your file needs. Please open an issue with the Ren'Py version and the file that failed.

  • Q: A statement came out wrong, or as a comment like # <unrecognized: Foo>

    A: Attach the structure of the file to the issue: rpycdec dump game/script.rpyc. It prints every node with the attributes it carries, including what the decompiled script has no way to show, and an <unrecognized: ...> names the class our fake renpy package is missing.

  • Q: The decompiled script looks right, but compiling it again changes something

    A: rpycdec dump original.rpyc decompiled.rpyc prints what differs between the two, which is how the tests in this repository check a round trip. Paste that, together with the file and the Ren'Py version, into the issue.

Contributing

Contributions are welcome! Please open an issue before submitting major changes so we can discuss the approach.

How the decompiler works, why it ships a fake renpy package, and where a missing node class goes: DEVELOP.md.

Testing

make test runs the unit tests and the end-to-end fixtures: each fixture in tests/fixtures/ is compiled with every Ren'Py SDK found under sdks/, decompiled, compiled again, and both ASTs are compared. Fixtures declare the version range they are written for with # min-renpy: / # max-renpy: headers, and combinations outside that range are skipped.

make test-corpus does the same for every game script the SDKs ship (~300 files, it takes a few minutes). Files that do not survive a round trip yet are listed in tests/corpus_baseline.json, each with the kind of failure and what differs first; a listed file that starts passing fails the test, so the list stays honest. Regenerate it with python3 -m tests.test_corpus --write-baseline.

The entries left there are the ones no decompiler can fix, because the value Ren'Py stored was made at compilation time rather than written in the source:

  • say-identifier — Ren'Py hands out identifiers while generating translations; the script itself has no id clause to write back.
  • init-offset — init offset is not in the AST at all, it is folded into the priorities of the statements around it.

Both need the SDKs, which are not in the repository; tests that need them skip when sdks/ is empty. Set RPYCDEC_SDKS to point at SDK roots elsewhere.

Community & Support

Alternatives

  • unrpyc - The well-established and widely-used Ren'Py script decompiler

Metadata

Release files for rpycdec 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rpycdec 0.2.0
File Size Uploaded
rpycdec-0.2.0.tar.gz 72.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rpycdec 0.2.0
File Interpreter ABI Platform
rpycdec-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 140.3 kB

Release files / rpycdec-0.2.0.tar.gz

Download URL rpycdec-0.2.0.tar.gz
Size 72.2 kB
Tags Source
SHA-256 checksum
How to use checksums
2226ba7ce2f37efe0f27f879cfef12546be9c02e0a92624b64c9eff40c9b9248
BLAKE2b-256 checksum
How to use checksums
865868c5af0fe7f510ea597dc9407328de7a770e19bfb7ff20306ce0623bd057
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.

Transparency log

Release files / rpycdec-0.2.0-py3-none-any.whl

Download URL rpycdec-0.2.0-py3-none-any.whl
Size 68.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5354959b7881c67ed87bcbd29a954bf44df10defd200314379a4cad3b98a89ec
BLAKE2b-256 checksum
How to use checksums
2a2189ec8a5b20a76d601a60cbd8ff7d5f7133461ff93cf09dc087c70032eab1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page