universal-game-modder 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ACCEPTABLE_USE.md +49 -0
- package/CHANGELOG.md +119 -0
- package/LICENSE +21 -0
- package/LICENSE-EULA.md +62 -0
- package/README.md +162 -0
- package/VERIFICATION.md +132 -0
- package/dist/backends/child-pool.js +91 -0
- package/dist/backends/mcp-child.js +102 -0
- package/dist/backends/mcp-child.js.map +1 -0
- package/dist/core/config.d.ts +10 -0
- package/dist/core/config.js +48 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/engine-detector.d.ts +13 -0
- package/dist/core/engine-detector.js +247 -0
- package/dist/core/engine-detector.js.map +1 -0
- package/dist/core/event-bus.js +18 -0
- package/dist/core/file-classifier.js +394 -0
- package/dist/core/model-db.js +517 -0
- package/dist/core/model-db.js.map +1 -0
- package/dist/core/router.d.ts +6 -0
- package/dist/core/router.js +143 -0
- package/dist/core/router.js.map +1 -0
- package/dist/core/session.js +114 -0
- package/dist/decoders/audio-export.js +57 -0
- package/dist/decoders/mesh-export.d.ts +20 -0
- package/dist/decoders/mesh-export.js +174 -0
- package/dist/decoders/mesh-export.js.map +1 -0
- package/dist/decoders/native/disassembler.js +85 -0
- package/dist/decoders/native/disassembler.js.map +1 -0
- package/dist/decoders/png-encode.d.ts +17 -0
- package/dist/decoders/png-encode.js +33 -0
- package/dist/decoders/texture-decode.js +278 -0
- package/dist/decoders/texture-decode.js.map +1 -0
- package/dist/decoders/unity/audioclip.d.ts +55 -0
- package/dist/decoders/unity/audioclip.js +87 -0
- package/dist/decoders/unity/audioclip.js.map +1 -0
- package/dist/decoders/unity/binary-reader.d.ts +45 -0
- package/dist/decoders/unity/binary-reader.js +141 -0
- package/dist/decoders/unity/binary-reader.js.map +1 -0
- package/dist/decoders/unity/mesh.js +198 -0
- package/dist/decoders/unity/mesh.js.map +1 -0
- package/dist/decoders/unity/ress-reader.d.ts +33 -0
- package/dist/decoders/unity/ress-reader.js +82 -0
- package/dist/decoders/unity/ress-reader.js.map +1 -0
- package/dist/decoders/unity/serialized-file.d.ts +65 -0
- package/dist/decoders/unity/serialized-file.js +144 -0
- package/dist/decoders/unity/texture2d.js +185 -0
- package/dist/decoders/unity/vertex-data.d.ts +54 -0
- package/dist/decoders/unity/vertex-data.js +174 -0
- package/dist/decoders/unity/vertex-data.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +23 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +66 -0
- package/dist/tools/decode-tools.d.ts +29 -0
- package/dist/tools/decode-tools.js +441 -0
- package/dist/tools/delegates/jar-editor.d.ts +2 -0
- package/dist/tools/delegates/jar-editor.js +276 -0
- package/dist/tools/delegates/unity-decompiler.d.ts +2 -0
- package/dist/tools/delegates/unity-decompiler.js +291 -0
- package/dist/tools/delegates/unreal-assets.d.ts +2 -0
- package/dist/tools/delegates/unreal-assets.js +122 -0
- package/dist/tools/detection-tools.d.ts +2 -0
- package/dist/tools/detection-tools.js +164 -0
- package/dist/tools/detection-tools.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.js +30 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/native/index.d.ts +2 -0
- package/dist/tools/native/index.js +1201 -0
- package/dist/tools/native-comprehension-tools.js +298 -0
- package/dist/tools/native-comprehension-tools.js.map +1 -0
- package/dist/tools/unpack-tools.d.ts +2 -0
- package/dist/tools/unpack-tools.js +382 -0
- package/dist/tools/workflow-tools.d.ts +2 -0
- package/dist/tools/workflow-tools.js +434 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.js +49 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/path-utils.d.ts +15 -0
- package/dist/utils/path-utils.js +24 -0
- package/dist/utils/path-utils.js.map +1 -0
- package/dist/utils/steam-finder.d.ts +8 -0
- package/dist/utils/steam-finder.js +32 -0
- package/dist/web/web-server.d.ts +1 -0
- package/dist/web/web-server.js +369 -0
- package/licenses/THIRD-PARTY-NOTICES.md +35 -0
- package/llms-install.md +34 -0
- package/package.json +69 -0
- package/server.json +20 -0
- package/setup.ps1 +34 -0
- package/ugm.config.json +9 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Acceptable Use Policy
|
|
2
|
+
|
|
3
|
+
**Universal Game Modder ("UGM") -- free open-core edition**
|
|
4
|
+
|
|
5
|
+
UGM is a general-purpose, offline binary-analysis and interoperability toolkit. Like a hex
|
|
6
|
+
editor or a disassembler, what it does is neutral; what it is used for is not. This policy
|
|
7
|
+
states the line. If you cannot honor it, do not install UGM.
|
|
8
|
+
|
|
9
|
+
## Permitted
|
|
10
|
+
|
|
11
|
+
- Modding, save editing and configuration changes to **single-player or offline** software
|
|
12
|
+
that **you legally own**, on your own machine.
|
|
13
|
+
- Reverse engineering for **interoperability** -- making programs, mods, tools or file
|
|
14
|
+
formats work together -- in the sense protected by 17 U.S.C. 1201(f) and similar law.
|
|
15
|
+
- **Security research and education** on software you own or are authorized to test,
|
|
16
|
+
including coursework, CTFs, and responsible-disclosure work under a published policy or a
|
|
17
|
+
written engagement.
|
|
18
|
+
- Preservation, accessibility and personal backup work on software you own.
|
|
19
|
+
|
|
20
|
+
## Prohibited
|
|
21
|
+
|
|
22
|
+
- Defeating, removing or bypassing **copy protection, licensing checks or DRM** to obtain
|
|
23
|
+
or distribute software you have not paid for.
|
|
24
|
+
- Tampering with **online, multiplayer or competitive** systems: anti-cheat evasion,
|
|
25
|
+
cheating against other players, manipulating leaderboards, economies or matchmaking, or
|
|
26
|
+
interfering with a service's integrity.
|
|
27
|
+
- **Redistributing** decrypted, extracted or modified proprietary assets, code or data that
|
|
28
|
+
you do not have the right to redistribute.
|
|
29
|
+
- Analyzing or modifying software you **do not own and are not authorized** to analyze.
|
|
30
|
+
- Building malware, exploiting third parties, or any use that breaks the law where you are.
|
|
31
|
+
- Any use that violates the EULA or terms of service of the software or platform involved,
|
|
32
|
+
where that violation would harm other people or the service.
|
|
33
|
+
|
|
34
|
+
## How this is enforced
|
|
35
|
+
|
|
36
|
+
It is not, technically. UGM has no telemetry, no kill switch and no way to know what you
|
|
37
|
+
are doing. This policy is enforced by you. The author disclaims all responsibility for
|
|
38
|
+
prohibited use (see `LICENSE-EULA.md`), and will not provide support, features or guidance
|
|
39
|
+
for it.
|
|
40
|
+
|
|
41
|
+
## Reporting
|
|
42
|
+
|
|
43
|
+
If you believe a UGM feature exists primarily to enable a prohibited use, or you find a
|
|
44
|
+
defect that makes prohibited use easier than intended, open an issue and say so. Features
|
|
45
|
+
that turn out to serve only prohibited ends will be removed or moved behind a re-aim.
|
|
46
|
+
|
|
47
|
+
*Last updated 2026-09-02 (v0.1.3). Rewritten after the original file was lost to a disk
|
|
48
|
+
incident; the substance is unchanged: interoperability, education and personal modding of
|
|
49
|
+
software you own -- nothing that harms other players, services or rights-holders.*
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Universal Game Modder are documented here.
|
|
4
|
+
This project adheres to [Semantic Versioning](https://semver.org).
|
|
5
|
+
|
|
6
|
+
## [0.1.4] - 2026-09-02
|
|
7
|
+
|
|
8
|
+
Packaging release for npm and the official MCP Registry. No tool behavior changes.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- `bin` entry so `npx universal-game-modder` starts the server; `#!/usr/bin/env node` on `dist/index.js`.
|
|
12
|
+
- `mcpName`, `repository`, `homepage`, `bugs`, `keywords` and `files` in `package.json`.
|
|
13
|
+
- `server.json` (MCP Registry manifest, schema 2025-12-11) and `llms-install.md` (agent-facing install steps).
|
|
14
|
+
|
|
15
|
+
## [0.1.3] - 2026-09-02
|
|
16
|
+
|
|
17
|
+
Privacy + recovery release. No tool behavior changes.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- **Machine-specific paths can no longer ship in the config.** The loader now resolves
|
|
21
|
+
`$UGM_CONFIG` (explicit path) -> `ugm.config.local.json` (developer/machine paths,
|
|
22
|
+
git-ignored, never in a release) -> `ugm.config.json` (the tracked file, placeholders
|
|
23
|
+
only) -> built-in defaults, merging each file over the defaults. This closes the
|
|
24
|
+
Gatekeeper privacy finding that had blocked a clean ship since 2026-06-17.
|
|
25
|
+
|
|
26
|
+
### Recovered
|
|
27
|
+
- On 2026-08-31 a TRIM incident zeroed this release's README, CHANGELOG, VERIFICATION,
|
|
28
|
+
LICENSE, EULA, acceptable-use policy, package.json, lock file and gate script, plus
|
|
29
|
+
21 of 39 TypeScript source files. The compiled `dist/` survived byte-intact. Docs and
|
|
30
|
+
the gate were restored from session records; LICENSE, EULA and AUP were rewritten to
|
|
31
|
+
the same terms. The full release gate was re-run on the restored cut (see
|
|
32
|
+
`VERIFICATION.md`). The TypeScript rebuild is a v0.2 task, not a ship blocker.
|
|
33
|
+
|
|
34
|
+
## [0.1.2] - 2026-08-25
|
|
35
|
+
|
|
36
|
+
Engine-detection correctness release. v0.1.1 passed its tool gate but misidentified two of
|
|
37
|
+
the three major engines it advertises; detection is now verified against real engine layouts.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
- **Unreal Engine games were not detected at all.** Detection looked for files literally named
|
|
41
|
+
`UE4-Win64-Shipping.exe` / `UE5-Win64-Shipping.exe`, but shipped Unreal titles name that
|
|
42
|
+
binary `<GameName>-Win64-Shipping.exe` (e.g. `Subnautica2-Win64-Shipping.exe`), so the
|
|
43
|
+
marker never matched a real game. The search was also capped at depth 2 while the binary
|
|
44
|
+
lives at `<Game>/Binaries/Win64/` (depth 3), and the `.pak` fallback required a
|
|
45
|
+
`shipping`-named exe at that same too-shallow depth. A standard Unreal install returned
|
|
46
|
+
`null` — no engine, not even `native`. Detection now globs `*-Win64-Shipping.exe`
|
|
47
|
+
(plus Win32/WinGDK variants) to depth 4 and recognizes the `Content/Paks` layout.
|
|
48
|
+
- **Unity games without `UnityPlayer.dll` were reported as `native`.** All Unity detection
|
|
49
|
+
was gated behind `UnityPlayer.dll`; if it was absent, `Assembly-CSharp.dll`,
|
|
50
|
+
`GameAssembly.dll`, `global-metadata.dat` and the `*_Data` directory were never
|
|
51
|
+
examined. Unity is now identified by any of its definitive markers, and an IL2CPP build
|
|
52
|
+
whose metadata cannot be located is reported as `unity-il2cpp` (inferred) rather than
|
|
53
|
+
falling through.
|
|
54
|
+
|
|
55
|
+
### Verified
|
|
56
|
+
- Engine detection: 4/4 on authentic Unity Mono / Unity IL2CPP / Unreal / Godot layouts
|
|
57
|
+
(was 1/4).
|
|
58
|
+
- Real Steam library sweep: 13/34 directories detected, up from 9/34, with **zero regressions**
|
|
59
|
+
— every previously-detected title resolves identically — and zero crashes. The remaining
|
|
60
|
+
undetected directories are installs stripped of game content (mod scaffolds, empty
|
|
61
|
+
`Paks`), which correctly report uncertainty rather than guessing.
|
|
62
|
+
- Full release gate re-run from a true cold install: 20/20 free-edition tools returning real
|
|
63
|
+
data, 3/3 Pro backends failing cleanly.
|
|
64
|
+
|
|
65
|
+
## [0.1.1] - 2026-07-27
|
|
66
|
+
|
|
67
|
+
Correctness and honesty release. v0.1.0 shipped documentation that did not match the code;
|
|
68
|
+
every documented call is now executed by a release gate before shipping.
|
|
69
|
+
|
|
70
|
+
### Fixed
|
|
71
|
+
- **Every Quickstart example in the README was wrong.** The docs told users to pass `path`,
|
|
72
|
+
but the tools require `file_path` (or `file_path_a`/`file_path_b`, `binary_path`,
|
|
73
|
+
`game_path`). All 9 documented calls failed with
|
|
74
|
+
`The "path" argument must be of type string… Received undefined`. Anyone copying the
|
|
75
|
+
README verbatim hit an immediate error. Documentation now matches the real schemas.
|
|
76
|
+
- **The server announced the wrong version.** It reported `1.0.0` in the MCP handshake while
|
|
77
|
+
the package and changelog said `0.1.0`. The version is now read from `package.json`, so it
|
|
78
|
+
cannot drift again — and the release gate fails the build if it does.
|
|
79
|
+
- **`jar_open` failed opaquely.** Its backend command defaults to `python` (never empty), so
|
|
80
|
+
the configuration check passed, the process spawned, and it died with
|
|
81
|
+
`MCP error -32000: Connection closed`. Unconfigured backends now report a missing script
|
|
82
|
+
path, matching the Unity and Unreal backends.
|
|
83
|
+
|
|
84
|
+
### Added
|
|
85
|
+
- **`verify-release.mjs`** — a pre-ship gate that executes every README-documented
|
|
86
|
+
free-edition tool against a real binary, asserts each returns recognizable data, and
|
|
87
|
+
confirms Pro-tier tools fail cleanly rather than hanging. Non-zero exit blocks a release.
|
|
88
|
+
Run it yourself: `node verify-release.mjs`.
|
|
89
|
+
- **`VERIFICATION.md`** — the recorded result of the latest gate run, including the exact
|
|
90
|
+
binary analyzed and what each tool returned.
|
|
91
|
+
|
|
92
|
+
### Changed
|
|
93
|
+
- The README now states the honest tool inventory: **29 tools run standalone** (19 native +
|
|
94
|
+
10 workflow) out of the **100** the server lists. The other 64 route to Pro-tier backends
|
|
95
|
+
and say so explicitly, rather than appearing to be included.
|
|
96
|
+
- **Native disassembly is documented as included**, not Pro-deferred — `disassemble_function`
|
|
97
|
+
and `disassemble_range` work in-process via capstone 5.0 and are verified. (The
|
|
98
|
+
`capstone-wasm` license is still being confirmed upstream; these may move tiers.)
|
|
99
|
+
|
|
100
|
+
## [0.1.0] - 2026-07-12
|
|
101
|
+
|
|
102
|
+
First public open-core release.
|
|
103
|
+
|
|
104
|
+
### Included (free edition)
|
|
105
|
+
- Stdio MCP server that an AI agent connects to and drives.
|
|
106
|
+
- Game-engine auto-detection (`detect_engine`, `load_game`) — Unity Mono/IL2CPP, Unreal, Godot, Java, native.
|
|
107
|
+
- Native binary analysis + patching toolset (19 in-process tools): PE analysis, hex read/write/search/replace, pattern scanning, string/class extraction, checksums, binary diffing, Godot PCK analysis. *(v0.1.0 said 22; the verified count is 19 — corrected in 0.1.1.)*
|
|
108
|
+
- MIT license + buyer-responsibility EULA + Acceptable Use Policy + third-party attribution.
|
|
109
|
+
- Ships from a scrubbed release set (no personal machine paths; empty-placeholder config).
|
|
110
|
+
|
|
111
|
+
### Deferred to a later release
|
|
112
|
+
- The `game-modder` guided-workflow skill (needs portable template resolution before shipping).
|
|
113
|
+
|
|
114
|
+
### Not included (deferred to Pro tier)
|
|
115
|
+
- Local web dashboard (port 7777).
|
|
116
|
+
- Delegated Unity/Unreal/JAR decompilation backends.
|
|
117
|
+
- Native disassembly (pending `capstone-wasm` license resolution).
|
|
118
|
+
|
|
119
|
+
[0.1.0]: first release
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Justanotherrandomaiguy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/LICENSE-EULA.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# End-User Terms (Buyer Responsibility)
|
|
2
|
+
|
|
3
|
+
**Universal Game Modder ("UGM") -- free open-core edition**
|
|
4
|
+
|
|
5
|
+
The UGM source code is licensed under the MIT License (see `LICENSE`). These terms do not
|
|
6
|
+
narrow that license. They exist to make one thing explicit before you install: **UGM is a
|
|
7
|
+
dual-use binary-analysis tool, and responsibility for how it is used sits with you, the
|
|
8
|
+
user, not with the author.**
|
|
9
|
+
|
|
10
|
+
## 1. What UGM is
|
|
11
|
+
|
|
12
|
+
UGM is a local Model Context Protocol server that gives an AI agent tools for inspecting,
|
|
13
|
+
analyzing and patching software on your own machine: engine detection, PE analysis, hex
|
|
14
|
+
read/write, pattern scanning, string extraction, checksums, binary diffing and native
|
|
15
|
+
disassembly. It runs entirely locally. It sends nothing anywhere.
|
|
16
|
+
|
|
17
|
+
## 2. Intended use
|
|
18
|
+
|
|
19
|
+
UGM is provided for **modding, interoperability, security research and education on
|
|
20
|
+
software you legally own or are expressly authorized to analyze.** Typical intended uses:
|
|
21
|
+
personal single-player mods, save and config editing, learning how a game is built, and
|
|
22
|
+
achieving interoperability between programs in the sense of 17 U.S.C. 1201(f) and
|
|
23
|
+
comparable provisions elsewhere.
|
|
24
|
+
|
|
25
|
+
## 3. Your responsibilities
|
|
26
|
+
|
|
27
|
+
By installing or using UGM you agree that you are solely responsible for:
|
|
28
|
+
|
|
29
|
+
- confirming you own or are authorized to analyze and modify any software you point UGM at;
|
|
30
|
+
- reading and honoring the license, EULA and terms of service of every game, platform and
|
|
31
|
+
store that governs that software (for example the Steam Subscriber Agreement);
|
|
32
|
+
- complying with the laws that apply to you, including anti-circumvention and computer-misuse
|
|
33
|
+
law in your jurisdiction;
|
|
34
|
+
- the consequences of any modification you make, including bans, save corruption, or loss
|
|
35
|
+
of access to online services;
|
|
36
|
+
- not using UGM in any way described in `ACCEPTABLE_USE.md` as prohibited.
|
|
37
|
+
|
|
38
|
+
## 4. What the author does not do
|
|
39
|
+
|
|
40
|
+
The author does not review, approve, or take responsibility for what you do with UGM, does
|
|
41
|
+
not provide legal advice, and makes no representation that any particular use is lawful
|
|
42
|
+
where you live. Nothing in this project's documentation is legal advice; confirm before any
|
|
43
|
+
high-stakes use.
|
|
44
|
+
|
|
45
|
+
## 5. No warranty
|
|
46
|
+
|
|
47
|
+
UGM is provided "AS IS" with no warranty of any kind, as stated in the MIT License. Binary
|
|
48
|
+
patching can damage files irreversibly. Back up anything you point it at.
|
|
49
|
+
|
|
50
|
+
## 6. Third-party components
|
|
51
|
+
|
|
52
|
+
Runtime dependencies and their licenses are listed in `licenses/THIRD-PARTY-NOTICES.md`.
|
|
53
|
+
Each is permissive (MIT / Apache-2.0). Nothing proprietary from any game or engine is
|
|
54
|
+
included in this edition.
|
|
55
|
+
|
|
56
|
+
## 7. Changes to these terms
|
|
57
|
+
|
|
58
|
+
These terms ship with the release they apply to. A later release may ship revised terms;
|
|
59
|
+
the terms in the copy you installed are the ones that apply to that copy.
|
|
60
|
+
|
|
61
|
+
*Last updated 2026-09-02 (v0.1.3). These terms were rewritten after the original file was
|
|
62
|
+
lost to a disk incident; the substance is unchanged.*
|
package/README.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Universal Game Modder
|
|
2
|
+
|
|
3
|
+
**One MCP server to inspect and mod any game — driven by an AI agent.**
|
|
4
|
+
|
|
5
|
+
Universal Game Modder (UGM) is a local [Model Context Protocol](https://modelcontextprotocol.io) server that gives an AI agent (like Claude in Claude Code) hands for game reverse-engineering and modding: it auto-detects a game's engine, then exposes a toolset for analyzing and patching the binaries — all running locally on your own machine, no cloud, no telemetry.
|
|
6
|
+
|
|
7
|
+
This is the **free open-core edition (v0.1.3)**.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## ⚠️ Responsible-use notice
|
|
12
|
+
|
|
13
|
+
UGM is a general-purpose binary-analysis and interoperability tool. It is meant for **modding, interoperability, security research, and education on software you legally own or are authorized to analyze.** You are responsible for how you use it. Before installing, read [`ACCEPTABLE_USE.md`](ACCEPTABLE_USE.md) and [`LICENSE-EULA.md`](LICENSE-EULA.md).
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## What's in the free edition
|
|
18
|
+
|
|
19
|
+
- **One stdio MCP server** that an agent connects to and drives.
|
|
20
|
+
- **Game-engine auto-detection** — point it at a game directory; it identifies Unity (Mono / IL2CPP), Unreal, Godot, Java, and native binaries from file signatures.
|
|
21
|
+
- **Native binary analysis + patching toolset** — PE header analysis, hex read/write/search/replace, IDA-style pattern scanning, string extraction, checksums, and binary diffing, running natively in-process (no external tools required).
|
|
22
|
+
|
|
23
|
+
The guided `game-modder` workflow skill and the delegated decompilation backends land in a later release; this edition is the MCP server + engine detection + the native toolset.
|
|
24
|
+
|
|
25
|
+
### Not in the free edition (Pro tier)
|
|
26
|
+
|
|
27
|
+
The web dashboard, the delegated Unity/Unreal/JAR decompilation backends, and native disassembly are part of the **Pro** tier and are **not** included here. The free edition is fully functional on its own for engine detection and native binary work.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Requirements
|
|
32
|
+
|
|
33
|
+
- **Node.js 18+** (uses ES modules and `better-sqlite3`)
|
|
34
|
+
- **[Claude Code](https://claude.com/claude-code)** or any MCP-capable client
|
|
35
|
+
- Windows / macOS / Linux (native tools are cross-platform; the smallest cut ships no OS-specific binaries)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```powershell
|
|
42
|
+
# from the repo root
|
|
43
|
+
./setup.ps1
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or manually (`dist/` ships prebuilt; there is nothing to compile in this edition):
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Then register the server with your MCP client. For Claude Code, add to your MCP config:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"mcpServers": {
|
|
57
|
+
"universal-game-modder": {
|
|
58
|
+
"command": "node",
|
|
59
|
+
"args": ["dist/index.js"]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
On first run, `ugm.config.json` ships with **empty placeholders** — the free edition needs no external paths. (The Pro delegate backends are where those get filled in.)
|
|
66
|
+
|
|
67
|
+
### Config resolution
|
|
68
|
+
|
|
69
|
+
The server reads the first of these that exists and merges it over built-in defaults:
|
|
70
|
+
|
|
71
|
+
1. the file named by the `UGM_CONFIG` environment variable
|
|
72
|
+
2. `ugm.config.local.json` next to `package.json` — your machine-specific paths; keep it out of version control (the repo's `.gitignore` already does)
|
|
73
|
+
3. `ugm.config.json` — the tracked file, placeholders only
|
|
74
|
+
|
|
75
|
+
So you can fill in backend paths without ever editing a file that could end up in a release or a pull request.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Quickstart
|
|
80
|
+
|
|
81
|
+
Once connected, ask your agent to work through these. **Every example below is executed against a real binary before each release** — see [Verified examples](#verified-examples).
|
|
82
|
+
|
|
83
|
+
> **Parameter naming:** file-level tools take **`file_path`** (and `file_path_a` / `file_path_b` for comparisons). Game-directory tools take **`game_path`**. Disassembly tools take **`binary_path`**.
|
|
84
|
+
|
|
85
|
+
**1. Detect what a game is built with:**
|
|
86
|
+
```
|
|
87
|
+
detect_engine { "game_path": "C:\\Path\\To\\Game" }
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**2. Set it as the active target:**
|
|
91
|
+
```
|
|
92
|
+
load_game { "game_path": "C:\\Path\\To\\Game" }
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**3. Analyze a binary:**
|
|
96
|
+
```
|
|
97
|
+
analyze_file_format { "file_path": "...\\SomeBinary.dll" } # magic bytes, managed vs native
|
|
98
|
+
analyze_pe_full { "file_path": "...\\SomeBinary.exe" } # PE headers, sections, data directories
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**4. Search and inspect:**
|
|
102
|
+
```
|
|
103
|
+
extract_strings { "file_path": "...", "min_length": 8 }
|
|
104
|
+
extract_dll_classes { "file_path": "...", "search_terms": ["Health","Damage"] }
|
|
105
|
+
pattern_scan { "file_path": "...", "pattern": "48 8B ?? ?? ?? ?? ??" }
|
|
106
|
+
search_binary_pattern { "file_path": "...", "patterns": ["maxHealth"] }
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**5. Patch and verify:**
|
|
110
|
+
```
|
|
111
|
+
hex_read { "file_path": "...", "offset": 4096, "length": 64 }
|
|
112
|
+
hex_replace { "file_path": "...", "search_hex": "90 90", "replace_hex": "EB 00" }
|
|
113
|
+
calculate_checksums { "file_path": "..." } # before/after integrity
|
|
114
|
+
compare_binaries_detailed { "file_path_a": "...", "file_path_b": "..." }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**6. Disassemble (native, included):**
|
|
118
|
+
```
|
|
119
|
+
disassemble_function { "binary_path": "...\\SomeBinary.exe", "rva": 4096 }
|
|
120
|
+
disassemble_range { "binary_path": "...\\SomeBinary.exe", "rva": 4096 }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Full free-edition tool list
|
|
124
|
+
|
|
125
|
+
These **29 tools run entirely in-process** and need no external backend.
|
|
126
|
+
|
|
127
|
+
**Native binary tools (19)** — all take `file_path` unless noted:
|
|
128
|
+
Detection / PE: `analyze_pe_full`, `analyze_file_format`, `analyze_dll_structure`, `rva_to_offset` (+`rva`), `offset_to_rva` (+`offset`)
|
|
129
|
+
Hex: `hex_read` (+`offset`), `hex_write` (+`offset`,`hex_data`), `hex_search` (+`hex_pattern`), `hex_replace` (+`replace_hex`)
|
|
130
|
+
Scanning: `pattern_scan` (+`pattern`), `pattern_scan_all` (+`pattern`), `search_binary_pattern` (+`patterns`)
|
|
131
|
+
Strings / classes: `extract_strings`, `extract_strings_advanced`, `extract_dll_classes`
|
|
132
|
+
Integrity / diff: `calculate_checksums`, `compare_binaries_detailed` (`file_path_a`,`file_path_b`)
|
|
133
|
+
Godot: `analyze_godot_pck`
|
|
134
|
+
Disassembly: `disassemble_function` (`binary_path`,`rva`)
|
|
135
|
+
|
|
136
|
+
**Workflow / session tools (10):**
|
|
137
|
+
`detect_engine`, `load_game`, `game_status`, `find_steam_games`, `mod_this_game`, `find_gameplay_values`, `build_and_deploy`, `debug_mod`, `scaffold_mod`, `list_available_tools`
|
|
138
|
+
|
|
139
|
+
### What the server also lists (Pro backends)
|
|
140
|
+
|
|
141
|
+
For transparency: the server advertises **100 tools total**. The other **64** are the Unity (27), Unreal (11), and Java/JAR (26) decompilation suites, which **route to external Pro-tier backend executables**. They appear in the tool list, but calling one without a configured backend returns a clear error:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
ERROR: Backend unity-decompiler not configured (missing executable path)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
That is expected behavior in the free edition, not a defect. Configure their paths in `ugm.config.json` (Pro) to enable them.
|
|
148
|
+
|
|
149
|
+
### Verified examples
|
|
150
|
+
|
|
151
|
+
The Quickstart calls above are not aspirational. Each release is gated on a verification pass that executes them against a real PE binary and requires every one to return real data. The v0.1.3 pass (2026-09-02, on the restored release cut) ran the gate's 20 documented calls plus 3 clean-failure checks; results are recorded in [`VERIFICATION.md`](VERIFICATION.md).
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
|
|
157
|
+
The UGM code is released under the [MIT License](LICENSE). Use of the tool is additionally governed by [`LICENSE-EULA.md`](LICENSE-EULA.md) and [`ACCEPTABLE_USE.md`](ACCEPTABLE_USE.md). Third-party components used by the Pro-tier backends are attributed in [`licenses/`](licenses/).
|
|
158
|
+
|
|
159
|
+
## Changelog
|
|
160
|
+
|
|
161
|
+
See [`CHANGELOG.md`](CHANGELOG.md). Current version: **v0.1.3** — the config can no longer ship machine paths, and the release was
|
|
162
|
+
restored and re-verified after a disk incident. v0.1.2 fixed engine detection; v0.1.1 fixed the docs and added the gate.
|
package/VERIFICATION.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Verification record — v0.1.4
|
|
2
|
+
|
|
3
|
+
Every call documented in [`README.md`](README.md) is executed against a real binary before
|
|
4
|
+
release. This file records the most recent run. If a documented call does not return real
|
|
5
|
+
data, the build does not ship.
|
|
6
|
+
|
|
7
|
+
**Run the gate yourself:**
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
node verify-release.mjs
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
It exits non-zero if any documented tool errors, times out, or returns data it cannot
|
|
14
|
+
recognize. Point it at a different binary with `UGM_VERIFY_TARGET=/path/to/binary`.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Last run
|
|
19
|
+
|
|
20
|
+
- **Date:** 2026-09-02
|
|
21
|
+
- **Version:** 0.1.3
|
|
22
|
+
- **Environment:** the restored release cut, run in place after the 2026-08-31 disk incident. Dependencies resolved from the sibling dev tree's `node_modules` (not a cold install this run; the v0.1.2 cold-install result below still stands for the unchanged tool code).
|
|
23
|
+
- **Config:** shipped `ugm.config.json` -- all backend paths empty, exactly as a buyer receives it. Loader order is new in 0.1.3: `UGM_CONFIG` > `ugm.config.local.json` > `ugm.config.json` > defaults.
|
|
24
|
+
- **Target binary:** `C:\Windows\System32\notepad.exe`
|
|
25
|
+
- **Result:** **PASS** -- 20/20 documented free-edition tools returned real data; 3/3 Pro-backend tools failed cleanly
|
|
26
|
+
|
|
27
|
+
Re-run the same day on the v0.1.4 packaging tree (bin entry, shebang, server.json, llms-install.md; no tool changes): **PASS** 20/20 + 3/3; `npm pack --dry-run` = 92 files, 117 kB packed; `node dist/index.js` announces 0.1.4.
|
|
28
|
+
|
|
29
|
+
Additional checks this run:
|
|
30
|
+
|
|
31
|
+
| Check | Result |
|
|
32
|
+
|---|---|
|
|
33
|
+
| Server boots over stdio | `universal-game-modder` 0.1.3, 100 tools listed |
|
|
34
|
+
| Zero-filled (disk-incident) files in the release tree | 0 remaining; 31 zeroed `.map` / `.d.ts` files purged (not needed to run) |
|
|
35
|
+
| Personal or machine paths anywhere in the release tree | none (scan for username, e-mail, `C:\projects`) |
|
|
36
|
+
| Tracked config files carry machine paths | no (`ugm.config.json` here and in the dev tree) |
|
|
37
|
+
| Docs and gate script | restored from session records; LICENSE, EULA and AUP rewritten to the same terms |
|
|
38
|
+
|
|
39
|
+
## Previous run (v0.1.2, 2026-08-25)
|
|
40
|
+
|
|
41
|
+
- **Date:** 2026-08-25
|
|
42
|
+
- **Version:** 0.1.2
|
|
43
|
+
- **Environment:** clean install (fresh `npm install`, no dev tree on the module path)
|
|
44
|
+
- **Config:** shipped `ugm.config.json` — all backend paths empty, exactly as a buyer receives it
|
|
45
|
+
- **Target binary:** `C:\Windows\System32\notepad.exe` (x64 PE, 200,704 bytes)
|
|
46
|
+
- **Result:** **PASS** — 20/20 documented free-edition tools returned real data; 3/3 Pro-backend tools failed cleanly
|
|
47
|
+
|
|
48
|
+
### Free-edition tools verified (20/20)
|
|
49
|
+
|
|
50
|
+
| Tool | Verified result |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `analyze_file_format` | Identified PE, x64, unmanaged, 7 sections |
|
|
53
|
+
| `analyze_pe_full` | Returned headers, architecture, and data directories |
|
|
54
|
+
| `analyze_dll_structure` | Returned section count and structure |
|
|
55
|
+
| `calculate_checksums` | Real MD5 / SHA1 / SHA256 (sha256 `da5807bb…d7c5b`) |
|
|
56
|
+
| `hex_read` | Returned the `4d 5a` (MZ) header at offset 0 |
|
|
57
|
+
| `hex_search` | Located the MZ pattern |
|
|
58
|
+
| `pattern_scan` | 7 matches for `4D 5A` with byte context |
|
|
59
|
+
| `pattern_scan_all` | Whole-file scan returned matches |
|
|
60
|
+
| `extract_strings` | 645 strings extracted |
|
|
61
|
+
| `extract_strings_advanced` | Filtered extraction returned data |
|
|
62
|
+
| `extract_dll_classes` | Targeted name search returned data |
|
|
63
|
+
| `search_binary_pattern` | Text pattern search returned data |
|
|
64
|
+
| `compare_binaries_detailed` | Byte-level comparison completed |
|
|
65
|
+
| `rva_to_offset` | RVA `0x1000` → file offset `0x400`, section `.text` |
|
|
66
|
+
| `offset_to_rva` | Reverse mapping completed |
|
|
67
|
+
| `disassemble_function` | 34 instructions, terminated on `ret` (capstone 5.0) |
|
|
68
|
+
| `disassemble_range` | 60 instructions from `.text` |
|
|
69
|
+
| `game_status` | Session state returned |
|
|
70
|
+
| `list_available_tools` | Tool inventory returned |
|
|
71
|
+
| `find_steam_games` | Library scan completed |
|
|
72
|
+
|
|
73
|
+
### Pro-backend tools fail cleanly (3/3)
|
|
74
|
+
|
|
75
|
+
With no backend configured, these return a clear, actionable error rather than hanging or
|
|
76
|
+
crashing:
|
|
77
|
+
|
|
78
|
+
| Tool | Result |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `decompile_type` | `ERROR: Backend unity-decompiler not configured (missing executable path)` |
|
|
81
|
+
| `open_game` | `ERROR: Backend unreal-assets not configured (missing executable path)` |
|
|
82
|
+
| `jar_open` | `ERROR: Backend jar-editor not configured (missing script path)` |
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## What this run fixed
|
|
87
|
+
|
|
88
|
+
Three defects were found by building this gate and are corrected in v0.1.1:
|
|
89
|
+
|
|
90
|
+
1. **Every Quickstart example in the v0.1.0 README was wrong.** The docs told buyers to pass
|
|
91
|
+
`path`; every tool requires `file_path` (or `file_path_a`/`file_path_b`, `binary_path`,
|
|
92
|
+
`game_path`). All 9 documented calls failed with
|
|
93
|
+
`The "path" argument must be of type string… Received undefined`. Documentation is now
|
|
94
|
+
generated against the real schemas and executed by this gate.
|
|
95
|
+
|
|
96
|
+
2. **The server reported the wrong version.** It announced `1.0.0` in the MCP handshake while
|
|
97
|
+
the package and changelog said `0.1.0`, making it impossible to tell which build a buyer
|
|
98
|
+
was running. Now consistent.
|
|
99
|
+
|
|
100
|
+
3. **`jar_open` failed opaquely.** Its backend command defaults to `python` (never empty), so
|
|
101
|
+
the "is it configured?" check passed and the process spawned and died with
|
|
102
|
+
`MCP error -32000: Connection closed`. It now reports a missing script path like the other
|
|
103
|
+
backends.
|
|
104
|
+
|
|
105
|
+
## Known limits
|
|
106
|
+
|
|
107
|
+
- Verification runs against a Windows PE binary. Cross-platform ELF/Mach-O paths are
|
|
108
|
+
supported by the code but are not covered by this gate.
|
|
109
|
+
- The Pro-tier Unity, Unreal, and Java backends are not exercised here; this gate proves only
|
|
110
|
+
that they refuse cleanly when absent.
|
|
111
|
+
- `disassemble_function` / `disassemble_range` depend on `capstone-wasm`, whose license is
|
|
112
|
+
still being confirmed upstream. They are verified working but may move tiers.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Engine detection (added v0.1.2)
|
|
117
|
+
|
|
118
|
+
Detection is verified against authentic engine directory layouts, not only against a stock
|
|
119
|
+
PE binary. Prior to v0.1.2 this was never tested and two of the three advertised engines
|
|
120
|
+
were misidentified.
|
|
121
|
+
|
|
122
|
+
| Layout | Expected | v0.1.1 | v0.1.2 |
|
|
123
|
+
|---|---|---|---|
|
|
124
|
+
| Unity Mono (`*_Data/Managed/Assembly-CSharp.dll`) | `unity-mono` | `native` | `unity-mono` (verified) |
|
|
125
|
+
| Unity IL2CPP (`GameAssembly.dll` + `global-metadata.dat`) | `unity-il2cpp` | `native` | `unity-il2cpp` (verified) |
|
|
126
|
+
| Unreal (`<Game>-Win64-Shipping.exe` + `Content/Paks`) | `unreal` | `null` | `unreal` (verified) |
|
|
127
|
+
| Godot (`*.pck`) | `godot` | `godot` | `godot` (verified) |
|
|
128
|
+
|
|
129
|
+
Real-library sweep across 34 installed Steam directories: **13 detected, up from 9, with zero
|
|
130
|
+
regressions and zero crashes.** Directories still reporting uncertainty are installs stripped
|
|
131
|
+
of game content (mod scaffolds with the game uninstalled, empty `Paks`) — the detector
|
|
132
|
+
correctly declines to guess rather than reporting a false engine.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { McpChild } from './mcp-child.js';
|
|
2
|
+
import { loadConfig } from '../core/config.js';
|
|
3
|
+
import { logger } from '../utils/logger.js';
|
|
4
|
+
export class ChildPool {
|
|
5
|
+
children = new Map();
|
|
6
|
+
configs;
|
|
7
|
+
// A backend is only usable if every path it needs is set. jar-editor is the
|
|
8
|
+
// special case: its `command` defaults to "python" (always non-empty), so the
|
|
9
|
+
// command check alone would let it spawn and die with an opaque transport
|
|
10
|
+
// error. Its real requirement is the script path.
|
|
11
|
+
static requiredArgIndex = {
|
|
12
|
+
'jar-editor': 0,
|
|
13
|
+
};
|
|
14
|
+
assertConfigured(backend, cfg) {
|
|
15
|
+
if (!cfg.command) {
|
|
16
|
+
throw new Error(`Backend ${backend} not configured (missing executable path)`);
|
|
17
|
+
}
|
|
18
|
+
const idx = ChildPool.requiredArgIndex[backend];
|
|
19
|
+
if (idx !== undefined && !cfg.args?.[idx]) {
|
|
20
|
+
throw new Error(`Backend ${backend} not configured (missing script path)`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
constructor() {
|
|
24
|
+
const config = loadConfig();
|
|
25
|
+
this.configs = new Map([
|
|
26
|
+
['unity-decompiler', {
|
|
27
|
+
name: 'unity-decompiler',
|
|
28
|
+
command: config.unityDecompilerExe,
|
|
29
|
+
args: [],
|
|
30
|
+
}],
|
|
31
|
+
['unreal-assets', {
|
|
32
|
+
name: 'unreal-assets',
|
|
33
|
+
command: config.unrealAssetExe,
|
|
34
|
+
args: [],
|
|
35
|
+
}],
|
|
36
|
+
['jar-editor', {
|
|
37
|
+
name: 'jar-editor',
|
|
38
|
+
command: config.pythonExe,
|
|
39
|
+
args: [config.jarEditorScript],
|
|
40
|
+
}],
|
|
41
|
+
]);
|
|
42
|
+
}
|
|
43
|
+
async call(backend, toolName, args) {
|
|
44
|
+
let child = this.children.get(backend);
|
|
45
|
+
if (!child) {
|
|
46
|
+
const cfg = this.configs.get(backend);
|
|
47
|
+
if (!cfg)
|
|
48
|
+
throw new Error(`Unknown backend: ${backend}`);
|
|
49
|
+
this.assertConfigured(backend, cfg);
|
|
50
|
+
child = new McpChild(cfg);
|
|
51
|
+
this.children.set(backend, child);
|
|
52
|
+
}
|
|
53
|
+
return child.callTool(toolName, args);
|
|
54
|
+
}
|
|
55
|
+
async listToolsFor(backend) {
|
|
56
|
+
let child = this.children.get(backend);
|
|
57
|
+
if (!child) {
|
|
58
|
+
const cfg = this.configs.get(backend);
|
|
59
|
+
if (!cfg)
|
|
60
|
+
throw new Error(`Unknown backend: ${backend}`);
|
|
61
|
+
this.assertConfigured(backend, cfg);
|
|
62
|
+
child = new McpChild(cfg);
|
|
63
|
+
this.children.set(backend, child);
|
|
64
|
+
}
|
|
65
|
+
return child.listTools();
|
|
66
|
+
}
|
|
67
|
+
getStatus() {
|
|
68
|
+
const status = {};
|
|
69
|
+
for (const [name, cfg] of this.configs) {
|
|
70
|
+
const child = this.children.get(name);
|
|
71
|
+
status[name] = {
|
|
72
|
+
connected: child?.isConnected ?? false,
|
|
73
|
+
configured: !!cfg.command,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return status;
|
|
77
|
+
}
|
|
78
|
+
async closeAll() {
|
|
79
|
+
for (const [name, child] of this.children) {
|
|
80
|
+
try {
|
|
81
|
+
await child.close();
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
logger.error(`Error closing child ${name}`, err);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
this.children.clear();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export const childPool = new ChildPool();
|
|
91
|
+
//# sourceMappingURL=child-pool.js.map
|