Files
nxnative-easy/dm/games/0100A3501946E000/game.tsv
T
seedds 16f4889192 OCTOPATH TRAVELER II (0100A3501946E000, update 1.1.1 = v131072, Unreal Engine 4.27 on SDK 12.3.2): game profile, inline Unreal shaders in version 11 paks, and five general host fixes. Plays on the iPhone (IPA 5.9 GB, user; that IPA predates the geometry and allocator changes below). On the Mac: the boot, the title, a new game, the traveler selection, Hikari's opening into his first battle (won) and the scene after it, and Castti's opening (the flashback, the ship, free play on the deck), at 60 fps (frame time p50 16.7 ms, p95 about 17 ms) with CRIWARE sound, about 2.8 GB resident. Shaders: the project ships no shader code archives (bShareMaterialShaderCode off), so each material's shaders are inline in its .uexp and the global ones in Engine/GlobalShaderCache-SF_GLSL_SWITCH.bin, each an entry of FShaderMapResourceCode (an LZ4 block, its raw size, its frequency): uepak.py inline_shaders sends a version 11 pak with cooked packages and no .ushaderbytecode to shader_split.py's inline reader (ue_legacy_jobs; Zlib and LZ4 pak blocks decoded in Python, Pak.read), ue_inline_shaders finds each LZ4 block by its first literals (LSLG), and profile_guess.py / the NSP script tell the two kinds apart; 13,980 shaders in 13 s. Profile: Unreal's FMallocBinned3 cut with an OBS_UE_MALLOC gate as DRAGON QUEST VII Reimagined's (GCreateMalloc main+0xbecbf0, a 20-slot vtable, hle_uemalloc.c), a 2 GB engine region (game_args) with the node-area cut on this SDK 12.3.2 build (sdk_patches.py, sdk+0x346190 / +0x34622c), fps_target 60 through t.MaxFPS / rhi.SyncInterval (hle_fpslock.c; the same route at 30 and 60 fps reaches the same scenes at the same times), pad_layout full (the battle menu picks weapons with the D-pad), a prewarm list of 843 lines. General fixes: (1) a shader may bind 96 resources instead of 64 (NVN_REFL_MAXB: the traveler selection's 3D map shader binds 66, and the map was black); (2) the parallel precompile look-ahead (pso_predict_rest) restores the scissor, which state_op keeps in R, not S: with pipelines built on demand the picture went bright green and white from Castti's flashback and Hikari's battlefield on (bisected with simultaneous runs; DM_NVN_PREDICT=0 turns the look-ahead off); (3) a geometry draw above the 256 MiB capture scratch bound is drawn in runs instead of skipped (nvn_geometry.inc geo_split: one instance at a time, then runs of at most 4,096 list primitives whose index range fits 64 MB, one read of the indices, one GPU wait), the index compaction after the geometry kernel runs as count / offset / write dispatches instead of one thread (each frame drawing Unreal's 129,032-triangle point light shadow took about 300 ms with it), and scratch arenas above 32 MB are released after 600 idle submissions (arena_new takes the smallest that fits); (4) MapMemory takes a thread stack from the host's Unreal heap (dm_ue_heap_owns: a range outside the guest block the host maps read-write, vm_region_64): with cae5ec2's stricter source check every Unreal game on the host heap aborted in MapAliasStack at nnMain (checked: this game and Pikmin 4 boot); (5) the host Makefile rebuilds on a change to dm/gfx/nvn/*.inc. Scripted input takes partly tilted sticks (L<x>/<y>): the traveler selection opens a card only while its quill cursor rests on a traveler, and full-tilt presses swept past them. Open: 2 of 87 Mac boots crashed at the title in the game's CRI cue sheet loader (main+0x1d8054, a record copied while one of its TArrays held count 1 and no data); the writer is not found yet (the game note). Checked: 57 tool tests, the gfx run list (t_geometry 95 checks) and the docs check pass; the NSP script packs the IPA from the NSPs (Mac and iOS). README (games gallery, a Mac picture of Hikari's first battle), the game note, the games table, docs/reference shaders / memory, docs/agents/04 and the symptom index say so
2026-10-25 15:43:48 +08:00

3.6 KiB

1# OCTOPATH TRAVELER II: Square Enix / Acquire, Unreal Engine 4.27 (one pak with the shaders inline in the cooked packages, MallocBinned3), SDK 12.3.2, NVN, CRIWARE sound and movies;
2# update 1.1.1 (v131072).
3# Started from the NSP script's provisional profile (dm/games/profile_guess.py) and brought up on the Mac (docs/agents)
4# Format: see dm/games/README.md
5# ---- Identity ----
6title_id0100A3501946E000
7program_id0100A3501946E000
8# ---- App ----
9# Game name: only a label for profile listings and the Mac window title; the iOS app name is the game name in the base NSP, and the bundle ID comes from the base game title ID (build_ipa.sh / NSP script)
10nameOCTOPATH TRAVELER II
11ipaOctopathTravelerII.ipa
12app_categorypublic.app-category.games
13# ---- Versions ----
14buildv1310721.1.1main=0d9649011312f62e93f6a5673a09d7e9subsdk0=dade22cfe6f24efe62d76409522c850bsdk=5bcf525f24eb28658a8d67ac27800d9b
15packagev131072
16shader_versionsv131072
17# ---- Files ----
18# load order as on Horizon: main, subsdk*, sdk (subsdk0 = NintendoSDK_movie)
19modulesmain subsdk0 sdk
20romfs_markerMajesty/Content/Paks/Majesty-Switch.pak
21zip_store.awb:.pak:.usm:.metallib
22# ---- Graphics ----
23# 60 fps (30 on the Switch): the game's Switch device profile caps Unreal at 30 (t.MaxFPS=30, and rhi.syncinterval=2, the present interval 2 it asks for while BaseSwitchEngine.ini's
24# r.VSync=1 locks presents to vsync; its Windows, PS4 and PS5 profiles set t.MaxFPS=60); the host writes t.MaxFPS 60 and rhi.SyncInterval 1 into its console variables (hle_fpslock.c),
25# so the game asks for present interval 1 itself. DM_FPS_TARGET=30 (Documents/env.txt on the iPhone) keeps the game's 30 and saves power
26fps_target60
27# ---- Memory ----
28# Unreal Engine 4.27: nninitStartup (main+0xbebd44) needs virtual address memory, sets a 6 MB heap for the C library's malloc and reserves one address region for the engine
29# (-SwitchVirtualAddressSpaceSize= in MB, game_args below; 62 GB by default). Its allocator, an FMallocBinned3 made on the first allocation, cuts its pools out of that region; the
30# constructor call is cut and the host runs Unreal's heap on a malloc zone outside the guest block (patches.py, hle_uemalloc.c layout UE4_27), and the SDK's node area is cut to 62 MB
31# (dm/tools/sdk_patches.py, the SDK 12.3.2 build), as for DRAGON QUEST VII Reimagined. Alias region = node area + up to 1 GB of alignment (regions of 1 GB and more are 1 GB aligned)
32# + the 2 GB region; 256 MB stacks, 384 MB heap region
33game_args-SwitchVirtualAddressSpaceSize=2048
34mem_reserve0xF0000000
35mem_alias0xC8000000
36mem_stack0x10000000
37app_pool0xCD500000
38# the NPDM declares 80 MB of system resource
39sys_resource0x5000000
40# ---- Input ----
41# docked (1920x1080). On the traveler selection, L / R step from traveler to traveler (moving the cursor onto one with the stick opened the card in one Mac run only)
42pad_layoutfull
43# ---- Shader split ----
44# Unreal Engine 4.27 with no shader code archives: each material's shaders inline in its cooked package (.uexp) and the engine's global shaders in Engine/GlobalShaderCache-SF_GLSL_SWITCH.bin,
45# every one an LZ4 block (shader_split.py ue_inline_shaders, uepak.py inline_shaders). Unreal combines vertex and pixel shaders per draw from its pipeline state, so every vertex shader is
46# made to link with any pixel shader (shader_split.py separable_pairs)
47shader_groupsGlobalShaderCache=global #Engine/=engine #Majesty/=game
48shader_noteOCTOPATH TRAVELER II shaders