agentsclimarketplace

Batocera ops

Skill t3chnaztea/batocera-skills/skills/batocera-ops

Use when connecting to or operating a Batocera arcade/retro-gaming cabinet over SSH: establishing the connection, understanding its read-only rootfs and /userdata layout, finding config/log/ROM paths, applying changes safely, verifying a display/config change end-to-end without a controller, or diagnosing why a setting reverts to its default on every launch (configgen). Foundation for the other batocera-* skills (roms, display, tuning, maintenance). Covers sshpass, batocera.conf, EmulationStation, the ES HTTP API, and batocera-screenshot. Not for game recommendations.From its SKILL.md

Install
npx -y skills add t3chnaztea/batocera-skills --skill batocera-ops

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

4 things to look at

  • reads credentialsReads from 1 credential source: `BATOCERA_PASS`.
  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
  • runs commandsInstructs the agent to run 8 commands, including `export BATOCERA_HOST=192.168.1.50` and 7 more.
  • fetches URLsInstructs the agent to fetch 2 URLs, including http://127.0.0.1:1234/launch and 1 more.

SKILL.md

8.6 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it

Batocera Ops

Foundation for operating a Batocera cabinet with a coding agent over SSH. Read this first; the sibling skills (batocera-roms, batocera-display, batocera-tuning, batocera-maintenance) assume the connection pattern, path model, and safety doctrine defined here.

Overview

Batocera is an immutable-rootfs Linux distro for retro gaming. The system partition is read-only; everything you can change lives under /userdata. EmulationStation (ES) is the frontend; RetroArch and standalone emulators do the playing. Configuration is layered: a single batocera.conf holds most settings, but launch-time code (configgen) regenerates per-emulator configs on every launch, so hand-edits to the generated files get stomped. Getting these two facts right prevents most wasted sessions.

Connecting

Batocera defaults to password SSH (no key from a fresh client). Parameterize the host so nothing is hardcoded:

export BATOCERA_HOST=192.168.1.50   # your cabinet's LAN IP

Batocera's documented default credentials are root / linux. If yours still uses them, change the password (ES menu → System Settings → Security, or passwd over SSH) — a machine you SSH into as root should not ship with a published password. The examples below read the password from an env var so it never lands in shell history or a committed file:

export BATOCERA_PASS='linux'   # replace with your actual password

# convenience wrapper used throughout these skills
SSHB() { sshpass -p "$BATOCERA_PASS" ssh -o StrictHostKeyChecking=no "root@$BATOCERA_HOST" "$@"; }
SCPB() { sshpass -p "$BATOCERA_PASS" scp -o StrictHostKeyChecking=no "$@"; }

Run a command: SSHB 'cat /usr/share/batocera/batocera.version' Copy down: SCPB "root@$BATOCERA_HOST:/userdata/screenshots/x.png" . Copy up: SCPB ./file "root@$BATOCERA_HOST:/userdata/system/"

If key auth is set up, drop sshpass. Batocera drops idle SSH connections; for long-running work use nohup … & or screen/tmux if installed. Rapid reconnects can trip the SSH daemon's throttle (transient "Permission denied"); wait a few seconds and retry rather than assuming the password is wrong.

The filesystem model

  • Rootfs is read-only. You cannot persist edits to /usr, /etc, or /bin. Anything you write there vanishes on reboot (or fails outright).
  • /userdata is the only writable tree. ROMs, configs, saves, BIOS, decorations, shaders, scripts, logs — all under /userdata.
  • Do work on the box, not over an SMB mount from another machine — the cabinet's own tools (chdman, 7z, python3) are already present and paths line up. Python 3 is available; there is no compiler.

Key paths

PathWhat
/userdata/roms/<system>/ROMs, one dir per system (see batocera-roms)
/userdata/roms/<system>/gamelist.xmlPer-system metadata + <hidden> flags
/userdata/system/batocera.confMain config: one file, key=value
/userdata/system/configs/Per-emulator configs (many are regenerated)
/userdata/system/configs/retroarch/retroarchcustom.cfgRetroArch overrides
/userdata/system/configs/emulationstation/es_settings.cfgES frontend settings
/userdata/system/services/Boot services (v43+; replaced custom.sh)
/userdata/system/logs/Per-launch + component logs (see reference)
/userdata/decorations/Bezel/overlay packs
/userdata/shaders/User shader presets and configs
/userdata/saves/Emulator save states and SRAM
/userdata/bios/BIOS files
/usr/share/emulationstation/es_features.cfgCatalog of valid per-emulator setting keys + values (read-only; see batocera-conf reference)
/userdata/screenshots/Where batocera-screenshot writes

batocera-conf precedence, the configgen regeneration model, and where a setting must live to survive a launch are in references/batocera-conf.md. The log inventory and ES restart mechanics are in references/emulationstation.md.

Safety doctrine

This is a shared physical device, often the family/party arcade cabinet. Treat it accordingly.

  1. Non-destructive first. Read before you write. Prefer hiding to deleting, moving to removing, appending to overwriting. /userdata is the only thing standing between you and a re-image.
  2. Back up before you touch a config or gamelist. One line, every time: SSHB 'cp /userdata/system/batocera.conf /userdata/system/batocera.conf.bak-$(date +%Y%m%d-%H%M%S)' Same for any gamelist.xml before editing it.
  3. Never inject synthetic input. Do not use uinput virtual keyboards, xdotool, evemu, or virtual gamepads to "drive" the cabinet. Someone may be physically holding the controller; injected keypresses land in their open menu and silently change settings. If a test needs button/stick input, describe the exact steps and ask the human to drive. (The ES HTTP API launch below is not synthetic input — it is a documented control endpoint — but it does commandeer the screen, so skip it if someone is playing.)
  4. Verify against ground truth, not assumption. After a change, re-read the file or launch the game and look. "It should work" is not evidence. See the verify loop below.

Remote verify loop (no controller needed)

The signature agent-native capability: change a display/config setting and confirm it end-to-end without touching the cabinet, using the ES HTTP API to launch and batocera-screenshot to see the result.

# 1. Launch a specific ROM via the ES HTTP API (runs ON the box, port 1234).
#    Works even for files ES doesn't list in its menu.
SSHB "curl -s -m3 -X POST http://127.0.0.1:1234/launch -d '/userdata/roms/<system>/<rom>'"

# 2. Wait 20-45s. Title/attract screens can be slow; if the shot is black,
#    take a second one a few seconds later before concluding anything.

# 3. Capture the framebuffer (this exact command; there is no swissknife
#    --screenshot). Writes a PNG into /userdata/screenshots/.
SSHB "batocera-screenshot"

# 4. Kill the running emulator, copy the newest screenshot down, and look at it.
SSHB "batocera-es-swissknife --emukill"
SCPB "root@$BATOCERA_HOST:/userdata/screenshots/$(SSHB 'ls -t /userdata/screenshots | head -1')" /tmp/verify.png
# then Read /tmp/verify.png

Config assertions after a libretro launch: the actual values RetroArch ran with are in /userdata/system/configs/retroarch/retroarchcustom.cfg and .../cores/retroarch-core-options.cfg, reflecting the last launch. Read those to confirm a key landed, rather than trusting that your batocera.conf edit took effect.

Gotchas that waste a verify session:

  • Piping RetroArch's output swallows it. retroarch … | grep / | tail discards core errors silently. To see why a core failed, launch with --log-file /tmp/ra.log and read the file.
  • A stray manually-run retroarch blocks ES launches — the ES launch exits instantly (~24ms, empty stderr, status 1). SSHB 'killall -9 retroarch' first.
  • Gamelist edits need ES stopped. ES rewrites gamelist.xml on exit and clobbers live edits. Stop it (/etc/init.d/S31emulationstation stop) or use the SIGKILL-restart pattern in the emulationstation reference. Config edits to batocera.conf do not need this; gamelist XML edits do.
  • Check what ES actually lists via the API: SSHB "curl -s http://127.0.0.1:1234/systems/<system>/games" (returns name/path/hidden per entry).

Provenance and freshness

Batocera changes across releases (path renames, custom.sh → services, new systems). These skills were distilled on v41-v43; commands are read-only unless noted. Before trusting a version-specific claim, confirm the build: SSHB 'cat /usr/share/batocera/batocera.version'. The canonical manual is the Batocera wiki; these skills capture operational lessons the wiki doesn't, not a replacement for it.

What ships with it: 2 files

11.1 KB alongside SKILL.md

Gives 0 of the 12 instructions most ship operate skills give in ~2.1k tokens

Counted across 1,077 of the 1,713 authors here whose files we hold, read 2026-09-06

  • Create GitHub releasein 44 of 1077, across 43 files
  • Run the test suitein 30 of 1077, across 25 files
  • Create and push git tagin 27 of 1077, across 26 files
  • Push commits and tagsin 27 of 1077
  • Create annotated tagin 25 of 1077, across 22 files
  • Ensure working tree is cleanin 24 of 1077
  • Check for product marketing context firstin 23 of 1077, across 6 files
  • Commit version bump changesin 22 of 1077, across 21 files
  • Update CHANGELOG.mdin 21 of 1077, across 20 files
  • Structure launch marketing across three channel typesin 20 of 1077, across 5 files
  • Commit and tag the releasein 20 of 1077, across 18 files
  • Update the CHANGELOG for new releasesin 19 of 1077

Said here and by no other author read

  • Treat rootfs as read-only.
  • Perform all work on the box.
  • Back up configuration before editing.
  • Never inject synthetic input.
  • Verify changes against ground truth.
  • Kill conflicting retroarch processes first.

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.