Skip to content

build: document a faster development build and keep the lift when switching it - #2518

Merged
hckrman101 merged 3 commits into
NotRexed:mainfrom
hckrman101:build/fast-dev-build
Nov 11, 2026
Merged

hckrman101 merged 3 commits into
NotRexed:mainfrom
hckrman101:build/fast-dev-build

Conversation

@hckrman101

@hckrman101 hckrman101 commented Nov 11, 2026 •

Copy link
Copy Markdown
Collaborator

A development build that only checks whether something works (the game starts, a menu, a screenshot, a log) still waits for the eight hot pieces, which are compiled at -O2 with the play profile and take about a third of the game's compile time. Their level can already be lowered with RX_HOT_OPT=O1, but that is not written down anywhere, and through make_game.py it also makes the next build translate the whole game again.

What changed

  • docs/development.md, Building: an RX_HOT_OPT row in the switches table and a short section, A faster build for development: what to set (RX_HOT_OPT=O1 with nx2/build.py, which then uses no profile; through make_game.py the shipped profile is still passed), when switching keeps the lift and the objects (the checkout's own work/ or HOOKSHOT_KEEP_BUILD_FILES=1; elsewhere make_game.py's clean-up keeps only the last build's, so a switch lifts again and recompiles the hot pieces), what it saves, and a clear warning that it is never for fps, frame times, build timings, hitch checks, profiles, or a release or player build.
  • CONTRIBUTING.md, Building: a one-line pointer to that section.
  • nx2/make_game.py: lift_key leaves RX_HOT_OPT and RX_PGO out (COMPILE_ONLY_ENV). Only nx2/build.py reads them, after the lift, so they never change the lifted C. Before this, setting RX_HOT_OPT for one build, or unsetting it again, changed the key and translated the game again (minutes). Any other A64_/OOT_/RX_ variable still changes the key.
  • tests/test_lift_cache.py: both variables, given to lift_key or in the environment, leave the key as it was; and no file of make_game.lift_sources() (the translator's files, which the key hashes) names them, so a translator change that starts reading one fails the check instead of reusing a stale lift.

The objects need no change: their keys include the flags, so -O1 and -O2 hot objects are cached side by side. make_game.py is not one of lift_sources(), so this edit costs no new lift. The direct build.py --standalone example runs without make_game.py's environment (RX_RELEASE, A64_HOT_CHUNK), so its runtime objects differ from a make_game.py build's; the docs say so.

Measured

These numbers come from existing builds, not from a new -O1 build: the per-file compile times in the build_times.json of six earlier full builds on one Linux desktop (Ryzen 9 7900X, 24 threads, 30 GB, other work running), plus peak memory measured during earlier build work.

Hot pieces (-O2, profile) The 72 other lifted files (-O1)
Compile time, all of them 1,270-1,810 s 2,820-3,750 s
Per MB of C 16-22 s 2.2-2.9 s
Longest single file 300-800 s ~360 s (code_021_1.c)
Peak memory per compiler 0.8-1.7 GB 1.4-1.6 GB (24 MB file)

The hot pieces are 81 MB of the 1.4 GB of lifted C. At the other files' rate they would take about 200 s instead of about 1,500 s, so the game's compile needs about a quarter less time in total, and the longest single file becomes an ordinary one, so a build after a new lift can finish several minutes sooner on a CPU with many threads. Peak memory barely moves, because the ordinary files already set it. The docs give these as estimates and say where they come from.

The game still plays with the hot pieces at -O1: the profile-counting build (RX_PGO=gen) already compiles them at -O1 and is played through to record the profile. Its frame rate was not measured for this PR, and the docs ask readers to check that it is fast enough for their test.

Tested

hckrman101 and others added 3 commits November 11, 2026 16:35
…tching it

RX_HOT_OPT=O1 compiles the eight hot pieces like every other lifted file
(no -O2, and no play profile when build.py runs on its own). They are
about a third of the game's compile time and its longest single files.
docs/development.md now describes it, with numbers from earlier builds'
build_times.json and a warning never to use it for fps, timings, hitch
checks or a release; CONTRIBUTING.md points to it.

make_game.py's lift key no longer includes RX_HOT_OPT and RX_PGO: only
nx2/build.py reads them, after the lift, so switching them translated
the game again for nothing. tests/test_lift_cache.py checks that they
leave the key as it was and that nothing the key covers reads them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tests/test_lift_cache.py: main's side (check_lift_sources), with the
compile-only checks added; they now scan make_game.lift_sources(), the
files the lift key hashes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e objects

Outside the checkout's own work/ folder (and without
HOOKSHOT_KEEP_BUILD_FILES=1), make_game.py's clean-up keeps only the
last build's objects and a translation that fits them, so each switch
translates the game again and recompiles the hot pieces. Also note that
build.py run on its own lacks make_game.py's environment (RX_RELEASE,
A64_HOT_CHUNK).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hckrman101
hckrman101 marked this pull request as ready for review November 11, 2026 22:14
@hckrman101
hckrman101 merged commit 692922d into NotRexed:main Nov 11, 2026
11 of 12 checks passed
@hckrman101
hckrman101 deleted the build/fast-dev-build branch November 11, 2026 22:16
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.

1 participant