rpynx v0.1.0pre-release

Building from source

Build targets

What scripts/build.sh builds, in which order, and where the output goes.

Source README.md, scripts/build.sh, runtime/renpy/README.md
On this page

The loader

bash
scripts/build.sh

Output: dist/renpy-loader.nro, built with 0 warnings under -Wall -Wextra. It links LVGL as liblvgl.a, built by third_party/lvgl/Makefile from the source that third_party/lvgl/fetch.sh downloads.

The runtime

Three steps, in this order. The first build of CPython takes about 10 minutes; Ren’Py about 5.

bash
scripts/build.sh python
bash
scripts/build.sh renpy
bash
scripts/build.sh runtime

Output: dist/renpy-runtime.nro, about 55 MB.

TargetWhat it does
pythonStatic CPython 3.12.8 for the Switch: libpython3.12.a and a 511-module stdlib zip of sourceless .pyc. Six small patches, documented in runtime/python/README.md
renpyRuns Cython on Ren’Py’s sources, compiles its 60 native modules into librenpy.a, and stages the engine for RomFS with precompiled .pyc and the SDK’s digest-checked common scripts
runtimeLinks dist/renpy-runtime.nro with no unresolved symbols
clean, othersPassed to make

important

After changing the boot scripts in runtime/renpy/boot/ or the cursor, run scripts/build.sh renpy again before runtime: they are staged into RomFS in that step.

How Ren’Py is built

  1. Generate C. Ren’Py’s own setup.py generate runs Cython. A two-class setuptools stand-in lets it run on the bare host CPython.
  2. Compile the native modules. build_modules.py reads the module list from Ren’Py’s src/Setup, compiles every source with devkitA64, renames each Cython init function to its dotted name, and generates an inittab that registers the 60 modules.
  3. Stage the engine. stage_engine.py copies renpy.py and renpy/, then the overlays (runtime/compatibility, runtime/renpy/boot), writes .pyc files, and adds the SDK’s precompiled common/*.rpyc after checking each one’s digest. Without them, the engine scripts would be recompiled on every launch, because RomFS is read-only.

None of Ren’Py’s own .py files are modified. The upstream changes:

ChangeWhy
libhydrogen uses its getentropy backendNo Switch random source upstream; getentropy is backed by libnx randomGet
renpy.gl2.assimp replacedassimp (C++) has no Switch port; GLTFModel raises a clear error
renpy.gl2.live2dmodel excludedThe Live2D Cubism Core is proprietary; Ren’Py treats it as optional
posix_memalign shimUsed by Ren’Py’s ffmedia.c; newlib does not provide it
CPython posixpath patchsdmc:/… and romfs:/… must count as absolute paths

Loader UI mockups

bash
scripts/mockups.sh

Renders every loader screen on the Mac, at 1280×720, through the same app/ui/ code and lv_conf.h, under ASan and UBSan. Output: build/host/mockups/*.png. It also prints each screen’s render time, which is host time, not Switch time.

Pushing to the Switch

bash
scripts/switch-ftp.sh 192.168.1.20:5000 push-loader
bash
scripts/switch-ftp.sh 192.168.1.20:5000 push-runtime

Each uploads over sphaira’s FTP server, reads the file back and compares it.

↑↓ move↵ openesc close