jevsnes.git / CLAUDE.md

For agents, on top of README.md, which they read first.

For agents

  • Run everything through the devshell (nix develop -c …). A tool missing from it is a line to add to flake.nix, not a nix run nixpkgs#….
  • Never launch the unwrapped Mesen (${pkgs.mesen}/bin/Mesen, or a store path) from outside the devshell. Without the devshell's GPU variables Mesa is on llvmpipe and Mesen's GPU renderer shows a black game surface with working audio, which reads as a broken ROM. Mesen on the devshell PATH is the wrapper, which uses the software renderer and works either way.
  • The GPU is reachable only because the devshell says how. GALLIUM_DRIVER=d3d12 and LD_LIBRARY_PATH=/run/opengl-driver/lib are set in flake.nix; without them GL, EGL and Vulkan all report llvmpipe (measured 2026-09-20). Set GALLIUM_DRIVER alone and GL programs fail to start at all (failed to create drisw screen). Check with vulkaninfo --summary / glxinfo -B before blaming a renderer.
  • ~/.config/Mesen2 is the user's live emulator config — leave it alone. Any experiment (fresh-install behaviour, settings changes, --testRunner runs) gets its own HOME and XDG_CONFIG_HOME under a scratch directory. Incident 2026-09-20: a research agent mv-ed the real directory aside while the user's Mesen was running, and the directory was lost.
  • A new key Mesen must have set goes in the enforce attrset in flake.nix, not into settings.json by hand — Mesen rewrites that file on exit.
  • Rust comes from fenix, never from nixpkgs' rustc/cargo. The emulator core uses float_algebraic, which nixpkgs 26.05's rustc 1.95 does not have (16 E0658 errors, measured 2026-09-20; clean on 1.98.1). stable in flake.nix is the release CHANNEL — the newest released compiler — not a request for an old one. Move it with nix flake update fenix.
  • A crate that links snes-core for the browser needs two things or getrandom refuses to compile: the dependency getrandom = { version = "0.4", features = ["wasm_js"] } under [target.'cfg(target_arch = "wasm32")'.dependencies], and the rustflag --cfg getrandom_backend="wasm_js" for wasm32-unknown-unknown. Same pair jgenesis' own frontend/jgenesis-web carries. Proven 2026-09-20 with a probe crate: native cargo check and a wasm32 release build both clean. No browser build exists in this repository yet; this is for the first one.
  • Flakes see only git-tracked files: git add a new file before nix develop will notice it.
  • The Jev key comes from op-env-run -- <cmd> and only from there. Do not add it to .envrc, export it in a shell, write it to a file, or echo it; to check it arrived, print ${#TYPESAFE_API_KEY}, never the value. Note the $TYPESAFE_API_KEY in a command line must be expanded by the CHILD (op-env-run -- sh -c '…'), not by the calling shell, where it is unset.
  • ROMs never enter git, and no doc names a personal path to them: a reader is told to dump their own cartridge into the gitignored roms/.
  • The folders are a guide, chapter by chapter, in the style of lmjtfy's (the owner, 2026-10-02: "read like the documentation subsite and like a tutorial flow"). Every owned folder's README is # Chapter N: <name>, <subtitle> with an opening that teaches, > **Aside.** detours, a > **Try it.**, then "For the people who maintain it" with a file map, and a last line ← Previous · Up · Next →. The chain is a depth-first preorder of the folders, in the order each parent's file table lists its children; the prologue's table is the whole order. A new folder gets its chapter and a CLAUDE.md, and the chapters after it are renumbered. Playful, never at the expense of a true fact. Agent-only rules stay in CLAUDE.md files.