본문으로 건너뛰기
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(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

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 / 1,000자

이 양식은 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의 스킬 모두 보기

이 스킬의 문제 신고