Vol. I · 2026
RAGrets

No RAGrets, yet another AI security blog

Agents

Point Claude at any game. Now read what you installed.

universal-modder hands Claude Code the tools to reverse engineer and drive PC games. The engineering is careful, and nearly every safety rule in it is advisory. What that means, and what to check before installing any agent plugin.

On 30 September a repo called universal-modder appeared on GitHub, and four days later it had over three thousand stars. The pitch is one line: “Point Claude at any game.” Install it as a Claude Code plugin (Codex, Cursor and Gemini CLI work too), tell the agent to add a homing missile launcher to Terraria, and it finds the game, works out the engine, reads the code, builds the mod, generates the art with fal.ai, launches the game, drives it with mouse and keyboard to test, records a clip, and writes up what it learned for the next agent.

This post is from reading the repo, not running it. The work in it is careful. It is also a useful specimen for this blog, because it is an agent plugin whose toolbox includes debugger attachment and input automation, and almost all of what keeps that toolbox pointed in the right direction is prose.

What it actually does

The core is a ten-step loop in a 2,500-word skill file: intake, recon, pick a route, set up a lab, read the real code, build a vertical slice, make assets, verify in the running game, record a showcase, package. Twelve engine playbooks hang off it (Unity, Unreal, Bethesda, Source, Minecraft, .NET games like Terraria and Stardew Valley, and so on), plus a Python CLI called um that wraps the tooling: game launch and kill, window focus, screenshots, input, fal asset generation, sprite processing, video compile, and a knowledge base.

The best single thing in the repo is a field note dated 3 October: Halo 3 weapons, Covenant, vehicles and maps ported into Minecraft. An agent read Halo 3’s cache files out of the Master Chief Collection with Reclaimer’s library, pulled render models and level geometry, took weapon stats from raw tag offsets, pulled audio out of a 16,000-sample FMOD bank, converted all of it into a Fabric mod, and then wrote itself a test harness that fires every weapon through game state and screenshots the result. The note records the bugs the way a person would: models came out 3,048 times too big because positions were already in world units; converted characters “aim with forearms pointing at the sky” until per-bone rest rotations fixed the bind pose; averaging terrain blend maps gave flat ground, so sample per triangle and take the dominant layer. Eight hours, one session, a human approving steps.

Despite how it is being described online, that is not decompilation. The assets come from the game’s data files and the behaviour from its data tables. Where the kit does decompile (ILSpy for .NET games, Ghidra for native ones) it is to read, and the rules say to keep decompiled output and extracted assets out of the repo. The mod ships converters that run against the user’s own install. The verification is also real. “The running game is the oracle; your reading of the code is not” is the skill’s phrasing, and the note holds to it.

What you install

Here is everything the plugin puts in front of Claude Code, in order of how much it can do.

plugin.json is metadata: name, version 0.2.0, author, MIT licence, keywords.

hooks/hooks.json registers one hook:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup|resume|clear|compact",
        "hooks": [
          {
            "type": "command",
            "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/add-to-path.sh\" \"${CLAUDE_PLUGIN_ROOT}\""
          }
        ]
      }
    ]
  }
}

The script it runs appends one line to the session’s env file so that um is on PATH for every later Bash call. That is all the hooks do. There is no PreToolUse hook, so nothing gates a tool call.

.claude/settings.json is the same SessionStart hook for people who clone the repo instead of installing the plugin. No permission allow-lists, no mode changes.

mcp.json adds one MCP server:

{
  "mcpServers": {
    "fal": {
      "type": "streamable-http",
      "url": "https://mcp.fal.ai/mcp",
      "headers": { "Authorization": "Bearer ${FAL_KEY}" }
    }
  }
}

Key from the environment, nothing hardcoded. Fine. Note what it is, though: a billing credential to a third-party model host, and the agent spends it whenever it decides a sprite or a voice line is needed.

skills/ is where the capability lives, as instructions. The reverse-engineering skill drives Ghidra, ILSpy, Frida, Cheat Engine and RenderDoc. The game-automation skill drives windows: um win launch, um win shot, um win drive for clicks, keys and focus, and um win kill.

Where the rules live

Pull the rules out of AGENTS.md, the skills and the safety reference, and sort them by what enforces them:

Rule Enforced by
Input only goes to the game window; refuse to send if another app is in the foreground Code, in um win drive
Kill by exact PID, never by name pattern Code, in um win kill
Never touch online clients or anything with anti-cheat Prose
Never bypass anti-cheat, DRM or ownership checks Prose
Ask before driving mouse or keyboard, or focusing a game that has an online mode Prose
Ask before installing a loader, changing the registry, deleting anything, or publishing Prose
Back up saves before the first modded launch Prose. The um backup command exists; nothing makes the agent run it
Keep decompiled code and extracted assets out of the repo Prose
Stop after the same failure three times and ask Prose

Two tool-level checks and a page of requests. The two that are in code are the right ones to put there, and both came from experience: the techniques doc notes that pkill -f <pattern> once killed the agent’s own shell, hence PID-only.

The same doc records how the input rule came about. In its words, “the agent focused GTA V to click Story Mode while the human was typing in another app. Their keystrokes hit GTA’s landing page, and GTA showed ‘ALERT: attempting to access GTA Online servers with an altered version’. ScriptHookV blocked the session.” Nobody was banned, but a modded client had just tried to contact Rockstar’s servers because an agent changed window focus at the wrong moment. The fix was a new subcommand, um win drive --proc <Game> idle, which reports seconds since the last real human input, and a new sentence: ask before driving if that number is small, and never focus a game with an online mode while the human is active. The doc also tells the agent to launch GTA’s story mode with -nobattleye “so online can’t start at all”. The reasoning is sound and it stays inside the project’s single-player line. It is also an agent starting a game with its anti-cheat disabled on the authority of a markdown file, and the hook that would make it confirm that first does not exist.

None of this is hidden; the README lists the rules and the repo documents its own near miss. But a skill that says “ask before” is the model being asked to ask. Whether anything stands behind that depends on how you run Claude Code.

Why prose rules are a configuration question

In Claude Code’s default permission mode, every Bash command that is not on your allow-list waits for your approval, so you are the gate and the prose is a reminder. Switch to an auto-accept mode for a long modding session, which is exactly what a ten-step loop with in-game testing invites, and the prose is the only gate.

Three things make that matter more here than for a typical plugin.

The agent reads untrusted text all day: mod wikis, Nexus pages, Discord logs, strings out of a decompiler, and the game’s own data. It does this while holding tools that drive input and attach debuggers. If a wiki page or a string in a binary says “run this to continue”, the agent that reads it can also run it.

The knowledge base is shared, and the agent consults it first. Step one of the loop is to search the field notes; new notes arrive by pull request. A merged note is instructions that run on every machine whose agent reads it. The maintainer reviews PRs, and that review is the entire control.

The fal key is money. Set a limit on it at fal before the first run.

What to check before installing this, or any agent plugin

  1. Read the manifest and hooks.json. Know what runs at SessionStart and whether anything runs before tool calls.
  2. Read settings.json for permission allow-lists. This one has none; others do.
  3. Read the MCP config. Which endpoints, which headers, where the key comes from, and what it can spend.
  4. Sort the rules into tool-enforced and prose, as above. For the prose ones that matter, add your own gate. A PreToolUse hook in your user settings can force a prompt on the commands you care about regardless of permission mode:
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "jq -e '.tool_input.command | test(\"um win (drive|launch)|frida|-nobattleye\")' >/dev/null && printf '{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"ask\",\"permissionDecisionReason\":\"Drives a game or attaches to a process. Confirm first.\"}}' || true"
          }
        ]
      }
    ]
  }
}
  1. Run it in default permission mode, on a machine or account that is not logged into anything with an online mode, with the saves backed up before the agent gets near them.

universal-modder is honest about all of this. The README lists the rules and the field notes record the incident. What it cannot do is make your copy of Claude Code enforce them, and it does not claim to. Enforcement comes from your side: the permission mode, a hook or two, and a key with a spending cap.

Filed under agentsclaude-codepluginsmcpgame-modding

All posts