Repository navigation
Add adaptive 60 fps support for Pokémon Legends: Z-A 2.0.2 - #918
Open
thehobbit85 wants to merge 4 commits into
Open
thehobbit85 wants to merge 4 commits into
thehobbit85 wants to merge 4 commits into
Conversation
thehobbit85
force-pushed
the
codex/za-dynamic-60fps
branch
from
November 2, 2026 06:00
176ca3e to
a7be739
Compare
thehobbit85
marked this pull request as ready for review
November 2, 2026 08:31
thehobbit85
force-pushed
the
codex/za-dynamic-60fps
branch
5 times, most recently
from
November 2, 2026 17:44
e4d94a0 to
f0895cc
Compare
thehobbit85
force-pushed
the
codex/za-dynamic-60fps
branch
from
November 3, 2026 02:57
f0895cc to
d56cb76
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
Z-A 2.0.2's native interval selector caps rendering at 30 fps. This adds a build-gated 60 fps option that feeds the existing host frame-step controller into the game's graphics interval and native clock dispatch, so ordinary frame drops advance game time by the corresponding whole-vsync duration. The launcher defaults to 60 fps and retains 30 fps;
DM_FPS_TARGET=0restores the original selector.Independent verification requested before merging. At the 30 fps cap, an earlier headless station comparison measured p99 frame time rising from 37.6 to 52.3 ms (+39.1%). Both runs had competing shader compilation. The cause remains unresolved. The new series produced two qualified main runs and zero qualified PR runs before further benchmarking was waived for review.
The hook is restricted to main build
b1f12fd919eae86ab8a978317677e64b, asserts the original instructions, and preserves the game's paused-clock behavior. It uses the original graphics setter, duration table, and all three clock adapters. The shared rewriter also reserves the state page before emitting appended patch-area branches: this build's key page ends at a 64 KB alignment boundary, where the previous layout overlapped state with code. Layouts that already have room, front patch areas, and modules without a frame step stay unchanged.Adds ARM64 hook execution tests, state-layout tests, station benchmark/smoke routes, and the 60 fps launcher/gallery documentation. No host or shader-chain implementation changes.
Details: game note, state allocation finding.
Revision
d56cb76ccd36f9b39fea1d69e960e3ea33d7a228includes main6136418bcd564f086cf57cb0a59e8f997d36445e. The upstream gallery now includes Pokémon Pokopia. The generated table retains both its entry and the Z-A caption. Upstream still lacks the build-specific Z-A frame-step and its shared state allocation.Local validation on
d56cb76ccd36.python3 -m unittest dm.tools.tests.test_docs dm.tools.tests.test_za_fps dm.tools.tests.test_patches— 29 passed and 5 optional Unicorn cases were skipped.The gallery generator verified the published README. The historical station p99 regression still needs independent testing. These checks produced no new timing sample.
GitHub checks for this revision
Station comparison and pre-merge handoff
The 2.0.2 Mac assets were rebuilt from the NSPs on the M2 Max. All 28,603 Mac shader libraries built, and the
applegpu_g14sarchive contains 26,029 bases. Both revisions were set up to use the same archive with the matching chain, depth mode and shader pairs. This Mac used Metal 32023.921. The repository pins 32023.922.The local
saves/stationfixture was copied from the original player save and checked byte-for-byte. Each trial got a fresh copy. A screenshot confirmed the starting scene and camera on the Lumiose Station platform. The headless route ran for 100 seconds atDM_FPS_TARGET=30in docked mode with audio disabled. Measurements use seconds 40–90.99330eb8, run 199330eb8, run 2An earlier setup run of main measured 29.9 fps and 34.18 ms p99. The new PR attempts on
a7be7395were excluded for contention. None supplied a qualified candidate measurement. Both the original performance finding and the sustained-60-fps caveat remain open.For an independent tester: run the full station route twice per revision on an idle Apple-silicon Mac with the same verified save, graphics settings and prewarmed archive. Check for competing work throughout each run and post the individual p99 values, FPS and screenshot comparisons here. If the increase repeats, investigate the per-frame CPU, GPU and present timings before merging.
Historical author validation
372a8d8a0404; unrelated controller work is excluded. The hook and state-layout logic are unchanged from the initial gameplay tests.python3 -m unittest discover -s dm/tools/tests: 861 tests, 21 optional skips, passed on the rebased tree. The native Mac packaging tests required running outside the filesystem sandbox.python -m unittest dm.tools.tests.test_za_fps dm.tools.tests.test_patches: 23 passed, including the five new hook tests under Unicorn/x86 Python. Covers both caps, varying steps, startup, disabled mode, registers/flags, original-byte/build gates, and state allocation.make -C dm/gfx/tests GAME=0100F43008C44000 -j6 run: complete Metal graphics suite passed, including the shared frame-step controller tests.dm/tools/lint_python.py: 391 baseline findings, zero new findings. Generated docs and diff whitespace checks passed.0100F43008C44000, 2.0.2, on Apple M2 Max / macOS 26.6 / Xcode 27.0. Earlier windowed gameplay covered the station, camera movement, and timed two-second walks. Native clock counters measured 59.70 game seconds / 59.73 real seconds (1.000) and 45.57 / 45.52 (1.001) through natural frame drops; a probe saw all 11 clocks receive 33,333,334 ns once per presented frame at hold 2.372a8d8a0404versus feature commit68d75dfab2f9, 100 seconds each, target 30. Both reached gameplay with matching screenshot dHashes, unchanged 28,603 shaders, and no new red-line kinds. The overall result isREGRESSIONdue to p99 frame time, not a clean performance pass; exact report below.--recordcorrectly did not write a greenvalidated.tsv.Caveats and remaining validation
regress.py impactbroadly flags the rewriter for every game (the available manifests list Hades, Breath of the Wild, Pokémon Scarlet, and Tears of the Kingdom; 122 profiles have no manifest); this PR limits the shared change to registered frame-step mains and tests every key-page alignment, SDK/unregistered modules, and front layouts. Other games remain unchecked.DM_WINDOW/DM_WINDOW_TOP/DM_METAL_HUDand recordsDM_TEST_HEADLESS=1. Headless runs establish execution/rendering, not display-link or fullscreen pacing.--wait-idle 0); both runs are marked busy. The run uses the preserved pipeline archive stamped for chainb7cd656abd7c, rather than the shared build directory whose stamp changed during PR preparation. Its timings are non-isolated. The p99 increase could reflect load, patch behavior, or both; an idle-machine rerun is required before merge.game_speedresult; the measured normal-speed evidence comes from the separate windowed clock run.SetRenderEnableConditional(the host draws anyway) and retry-success memory-pool red lines occurred in the earlier tests. No new red-line kinds were introduced in the recorded comparison. This PR does not resolve those existing limitations.<NSP folder>/saves/stationfixture. The rebuilt Mac assets and restored fixture are local test inputs. The package, game files, save and screenshots are excluded from the PR.Earlier headless benchmark samples
station-walk, 40–140 seconds, one run per variant; these pre-rebase measurements are retained with the load caveat above. The hook and frame-state layout logic did not change during the rebase.Regression report: full check — REGRESSION
Baseline
origin/main372a8d8, candidateHEAD68d75df; Apple M2 Max, macOS 26.6, Xcode 27.0; 237.4 s0100F43008C44000LegendsZA
0100F43008C44000: REGRESSIONDocs