跳到正文
cccskills
免费在 GitHub 公开

snx-run

Run a recompiled game unattended and judge the result: scripted button input, timed exit, screenshots, reading the log, and repeat runs for intermittent crashes. Use when verifying a runtime change, reproducing a bug, checking a scene renders, measuring a crash rate, or when the user asks to run or test the game.

中文简介正在准备中。当前显示原文说明。

实测评分 未实测

查看安装方法

包含的文件(1)

  • SKILL.md7.8 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Run the game

One command

tools/run_game.py <id> --dump work/<Game>                 # 60 s with the default script
tools/run_game.py <id> --runs 5 --dump work/<Game>        # crash rate
tools/run_game.py <id> --seconds 20 --script "" --out "$SCRATCH/boot"  # boot only, no input

<id> is the game's folder in recompiled/, or in games/ for one an older version made there: its title ID, or the name it was recompiled under (scarletnx -r work/<Game> NAME). work/<Game> is the extracted dump.

$SCRATCH stands for the session's scratchpad directory: keep --out there, never in /tmp or the repo (without --out it makes a new folder in /tmp). It runs the game from its folder, recompiled/<id>/, writes runN.log and runN.png (the last frame, converted from the runtime's .ppm when Pillow is installed, otherwise runN.ppm stays and it says so once) per run, and prints one line per run: the exit code (or timeout), then ok, the crash site (the signal from the *** Crash header and the faulting thread's pc/lr after it, named with --dump) or the svcBreak reason, then the frame count with the average FPS over --seconds. Options it doesn't know (--fps_limit=0, -v...) go to the runtime. Look at the picture with the Read tool: a frame that "rendered" can still be black or garbage, and only the picture shows it.

The runtime options behind it, for a run by hand from recompiled/<id>/ (./<id> --seconds=60 ...):

OptionEffect
--seconds=NExit after N seconds, printing frames=N hash=... (the last frame's hash) and writing --shot. They count from the game's start, after the shader loading screen (prepare_shaders=2), which ends after N seconds itself. The first run after a rebuild translates the game's shaders again there (seconds, or a minute in a big game)
--frames=NExit after N presented frames
--shot=PATHScreenshot to PATH.ppm at exit
--shot_every=NAlso a numbered screenshot every N frames (PATH_0000.ppm, ...), needs --shot
--script=ms:hex,...Press buttons at those times, each held 300 ms (--press_len=ms changes it). Nf:hex presses at the Nth presented frame instead. One press is a script of one entry: --script=5000:1
--swkbd_text=TEXTThe software keyboard answers TEXT instead of opening a dialog
-vLog every IPC call (IPC <interface> cmd N, nn::audio::detail::IAudioOut for an audout): huge, grep it
--fps_limit=0Unlimited frame rate
--game=PATHRun the game PATH names (recompiled/<id>, the folder, runs recompiled/<id>/<id>_code.so) instead of the one the runtime is named after. Its log, caches and captures still go to that game's folders

The timing, screenshot, press and script options are platform/unattended.c's, shared by the SDL3 and headless backends, so a headless build takes --script too. With --seconds or --frames the window doesn't go fullscreen. The SDL3 backend runs on Wayland when the desktop has it. SDL_VIDEO_DRIVER=x11 runs it on X11 instead: test a platform change on both.

Buttons (hex): A 1, B 2, X 4, Y 8, L 40, R 80, ZL 100, ZR 200, Plus 400, Minus 800, Left 1000, Up 2000, Right 4000, Down 8000. Combine by adding. The values are 64-bit, and bits 40 to 47 push the sticks all the way: 40 left stick left (10000000000), 41 up, 42 right, 43 down, then 44 to 47 the same for the right stick (800000000000 is right stick down).

run_game.py's default script was written for one game's boot to its first cutscene: Plus at 15 s, A at 16 s, Plus at 18 s, then A at 21, 31, 36, 40 and 44 s. Any other game needs its own --script. With save data from earlier runs the screens come in a different order, so check the screenshots before trusting a script.

Reading the log

The game's log, recompiled/<id>/<id>.log in a checkout (a data folder keeps it in its state folder, docs/USAGE.md "Folders"), and the run log grow to megabytes. Never print it whole.

  • grep -n "Crash\|svcBreak\|FATAL" run1.log: the failure, then sed -n around it.
  • The log has no FPS line. frames=N at the end of a --seconds run, divided by the seconds, is the average frame rate (run_game.py prints it).
  • grep "vulkan:" run1.log | tail -3: every 600 presents, the draws and skipped draws, compute dispatches and batches with the time spent waiting on them, and skipped dispatches. WARN lines with vulkan: shader ... didn't compile or untranslated instructions are rendering bugs.
  • video: lines: NVDEC and VIC jobs. romfs: lines: files the game opened (movies are .usm).
  • threads.txt, next to the game's log: every guest thread's state and wait, rewritten every 15 s. A hang is read from here.
  • diag=1 in the game's .ini saves the QMD and program of each new compute shader (the first 32) to recompiled/<id>/captures/compute/. F5 writes every game thread's state to the log at any time.
  • RenderDoc (installed by the user): --renderdoc=$SCRATCH/cap --renderdoc_frames=500,800 captures those presents (one guest frame each; 45s is the first frame after 45 s on the --script clock, steadier on a loaded machine) to $SCRATCH/cap_capture*.rdc, and the log says renderdoc: captured present N. Run it with SDL_VIDEO_DRIVER=x11: RenderDoc has no Wayland surface, and on Wayland vkCreateInstance fails with VK_ERROR_EXTENSION_NOT_PRESENT. The capture layer slows the game (to about 20 fps in one test), so pick presents the run reaches, and expect a few hundred MB per capture. Captures hold the game's textures and buffers: they stay local. A capture stops the GPU thread for seconds. A game that waits only 1 s for its frame fences and then goes on can crash a little after a capture (one test game's arena deleter lists were overwritten): that crash is the capture's. Replay from scripts with RenderDoc's Python module (not in the Arch package): build it from the same tag with -DENABLE_QRENDERDOC=OFF -DENABLE_PYRENDERDOC=ON outside the repo and put its lib/ on sys.path. With 1.46 on Arch, -DENABLE_GL=OFF -DENABLE_GLES=OFF -DENABLE_EGL=OFF -DENABLE_WAYLAND=OFF configures and the module builds in about 10 minutes (it fetches its own SWIG). Run scripts with PYTHONPATH and LD_LIBRARY_PATH both set to that lib/. ReplayController lists actions (GetRootActions), saves targets (SaveTexture), reads buffers (GetBufferData), and has PixelHistory, DebugPixel with ContinueDebug, and GetPostVSData: a pixel trace of a pass's samples finds which input is wrong faster than reading its SPIR-V. Under the layer a game runs about 3x slower, so a scene comes later on both the s clock and in presents: capture a few points across a long run.

Crash reports are handled with the snx-crash skill.

Intermittent bugs

  • One clean run proves nothing. Measure the rate before the fix with the same script and run count, then after, and put both in the commit message (for example "crashed 4 of 6 runs before, 0 of 20 after").
  • Save data from earlier runs (recompiled/<id>/<id>_data/save/) changes what the game does at boot. A rate measured with one save state is not comparable with one measured with another. To start fresh, move the save folder aside (outside recompiled/), never delete it without asking.
  • Don't build or run anything heavy while measuring: timing changes the rate.
  • Runs are sequential. Two games at once share the GPU and the saves.

Stopping a game

pgrep -a with the title ID's first 15 characters (Linux keeps 15 of a process name), then kill PID. Never pkill, which matches the shell running it.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Audits uncommitted changes, branches, or PRs for bugs, edge cases, SOLID/DRY/SRP, architecture, security, performance, and CLAUDE.md violations — then automatically fixes ALL issues and re-audits in a loop until clean. Use when: audit, review, code review, review this PR, check code, look over this, inspect code, or any variation.

中文简介正在准备中。当前显示原文说明。

scarletnx/ScarletNX2242026年10月25日 更新

Record what ScarletNX work taught, where the next session will look for it. Use after a bug took more than one attempt to find, when the same mistake happened twice, when a debugging technique worked, or when the user corrects how work is done.

中文简介正在准备中。当前显示原文说明。

scarletnx/ScarletNX2242026年10月25日 更新

snx-build

免费

Build the ScarletNX runtime and recompile games correctly, avoiding the setups that build "successfully" into something that doesn't work. Covers the CPM.cmake dependencies, the Clang-only presets, the deploy into games/, when a game needs recompiling, and the warnings a plain build doesn't show. Use when building, rebuilding, recompiling a game, after pulling or bumping a dependency, or when a build result looks suspicious.

中文简介正在准备中。当前显示原文说明。

scarletnx/ScarletNX2242026年10月25日 更新

RFC #142's C rules: strict ISO C99, no redundant state, indices not pointer chains, one allocation per owner, atomics apart, no stored pointers, one global struct per file. Use when writing or reviewing C in src/.

中文简介正在准备中。当前显示原文说明。

scarletnx/ScarletNX2242026年10月25日 更新

snx-crash

免费

Take a ScarletNX crash report, svcBreak or hang from the log to the mechanism that causes it, using the symbolizer and disassembler on the game's code. Use when the game crashes (signal 11 or 7), calls svcBreak or fatal, hangs, or when a log shows "*** Crash". Also for corrupted data showing up in game structures.

中文简介正在准备中。当前显示原文说明。

scarletnx/ScarletNX2242026年10月25日 更新

Write and optimize ScarletNX's own compute shaders (astc.comp, vic.comp, future ones) for what the GPU actually executes: constant tables, bit twiddling, uniform branches, fewer fetches, workgroup and subgroup structure, exactness proofs, and the GLSL-as-C++ tests and lavapipe timing that check them. Use when writing, reviewing or speeding up a GLSL shader under src/nx/gpu/, or when deciding whether to split one.

中文简介正在准备中。当前显示原文说明。

scarletnx/ScarletNX2242026年10月25日 更新

查看 scarletnx 的全部技能

报告此技能的问题