Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 95 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ python MCP_Server/test_mcp.py

Loading the Lua side in Cheat Engine: `File → Execute Script → open MCP_Server/ce_mcp_bridge.lua → Execute`. Success log: `[MCP v12.0.0] MCP Server Listening on: CE_MCP_Bridge_v99`. Re-executing the script auto-calls `StopMCPBridge` / `cleanupZombieState` first, so reloading is safe.

There is **no build step, no linter, and no unit-test harness**. `test_mcp.py` is a single end-to-end script that talks to the live Named Pipe; running a "single test" means editing the `all_tests` dict in `test_mcp.py:main` or commenting out sections.
There is **no build step** for the bridge itself. `test_mcp.py` is a single end-to-end script that talks to the live Named Pipe; running a "single test" means editing the `all_tests` dict in `test_mcp.py:main` or commenting out sections.

The CT updater has an offline unit-test harness in `ct_updater/tests/`. Run it with:
```bash
python -m unittest discover -s ct_updater/tests -p "test_*.py" -v
```
These tests require no bridge or game connection.

The MCP server is normally spawned by the AI client over stdio, but can be launched directly with `python MCP_Server/mcp_cheatengine.py` for debugging (it blocks waiting for stdio JSON-RPC).

Expand Down Expand Up @@ -92,6 +98,94 @@ New handlers are appended with unit markers (e.g. `-- >>> BEGIN UNIT-NN <Title>
### Pagination
List-returning commands (scan results, memory regions, modules, threads, disassembly, references, BP hits) support `offset` / `limit` params with a standard `{ total, offset, limit, returned, <key>: [...] }` return shape.

## CT Table Auto-Updater (`MCP_Server/ct_updater/`)

A standalone Python tool that checks whether an existing `.CT` cheat table still works after a game update and auto-patches what it can. Also contains feature-discovery tools for building new hooks. Run from `MCP_Server/`:

```bash
python -m ct_updater "path/to/Game.CT" # check + write .updated.CT
python -m ct_updater "path/to/Game.CT" --no-patch # report only
python -m ct_updater "path/to/Game.CT" --lint # pre-flight quality check, no patch
python -m ct_updater "path/to/Game.CT" --preview-only # show unified diff, no write
python -m ct_updater "path/to/Game.CT" --verbose # disassembly for broken patterns
python -m ct_updater "path/to/Game.CT" --apply-postprocess-fix # auto-apply strong postprocess picks
python -m ct_updater "path/to/Game.CT" --write-artifacts # write per-entry JSON/MD/AI bundle reports
python -m ct_updater "path/to/Game.CT" \
--history-store ct_history.json --record-history # track accepted fixes for future runs
```

### Pipeline overview

The updater routes each AOB entry into one of five buckets:

| Bucket | Meaning |
|--------|---------|
| `FAST_PATH_OK` | Pattern still matches — nothing to do |
| `AUTO_FIX` | Safe deterministic repair (range extension or high-confidence byte substitution) |
| `POSTPROCESS_FIX` | Postprocess produced a strong recommendation; patched with `--apply-postprocess-fix` |
| `ESCALATE_POSTPROCESS` | Strong recommendation found but not auto-applied — inspect the decision report |
| `MANUAL_REVIEW` | Confidence too weak; needs human judgment |

Uniqueness is checked before any `AUTO_FIX` is applied — if the pattern matches more than one location in the sampled method memory the fix is blocked and the entry is escalated.

### Module responsibilities

| File / Package | Purpose |
|---|---|
| `bridge.py` | Named pipe client — connects to `CE_MCP_Bridge_v99`, wraps `evaluate_lua`, `read_memory`, `disassemble` |
| `parser.py` | Parses `.CT` XML — extracts `aobscanregion(...)`, `assert(...)`, and pointer entries. Handles bare CE hex (`10C`) vs decimal (`100`). |
| `analyzer.py` | Resolves Mono symbols, reads method memory, scores pattern matches. Returns `OK`, `RANGE_MISS`, `BYTE_CHANGE`, `PARTIAL`, `NOT_FOUND`, `NO_SYMBOL`. |
| `workflow.py` | Decision tree that routes entries through fast-path → preprocess → postprocess → patch/escalate/manual. Classifies each candidate's instruction window with `hook_intent_classifier` for intent consistency scoring. |
| `patcher.py` | Applies fixes to raw `.CT` text; `preview_fixes()` returns a unified diff without writing. |
| `__main__.py` | CLI entry point — orchestrates the pipeline, renders colour report, writes artefacts. |
| `preprocess/` | Samples method memory, scores candidate windows, captures disassembly, builds replacement/wildcard patterns. |
| `postprocess/` | Rescores candidates using 8 signals: byte similarity, confidence, mnemonic shape, structural markers, uniqueness, stability, history alignment, and intent consistency. |
| `uniqueness/` | Counts how many times a candidate pattern appears in sampled memory; classifies as `unique` / `ambiguous` / `unsafe`. |
| `stability/` | Identifies volatile vs stable bytes empirically and via structural heuristics (call offsets, RIP-relative displacements, branch targets, MOV immediates). Produces both empirical and `hardened_pattern` outputs. |
| `history_store/` | Persists accepted fixes to a JSON file; future runs use the stored baseline as a ranking hint. |
| `method_diff/` | Normalized instruction-window diffing; included in escalated decision artifacts. |
| `bundle/` | Combined AI handoff artifact — one JSON/Markdown file per escalated run containing preprocess + decision + flow summary. |
| `preview/` | Preview service; drives `--preview-only` output including risk labels. |
| `lint/` | Pre-flight CT quality checks: zero-wildcard dense patterns, tight scan ranges, duplicate AOBs, unresolvable assert targets. |
| `hook_intent_classifier/` | Classifies an instruction window as `write`, `read`, `read_modify_write`, `branch_gate`, `callsite`, `compare`, or `mixed`. Used by workflow and feature_builder. |
| `feature_builder/` | Reference-driven packet generation for new hooks — runs preprocess + postprocess + method_diff + intent classification + sibling field scan in one call. |
| `sibling_field_finder/` | Discovers nearby struct fields by scanning for same-base-register memory accesses with different offsets. |
| `script_template_generator/` | Generates CE Auto Assembler scaffold (`aobscanregion`, `alloc`, `jmp`, hook body) from a feature packet or direct inputs. |
| `tests/` | Offline unit-test harness (no bridge required). Covers lint, stability heuristics, intent rescoring, and template generation. |

### Auto-fix rules

- **`RANGE_MISS`**: pattern found outside the `aobscanregion` end offset → extends the range. Blocked if uniqueness check finds multiple matches.
- **`BYTE_CHANGE`** (≥85% match, ≥90% for auto-fix without postprocess): a few bytes differ → substitutes the changed bytes and optionally extends range. Blocked if ambiguous.
- **`POSTPROCESS_FIX`** (opt-in): postprocess score ≥ 85% → applies the recommended pattern. Uses the wildcard form when uniqueness is confirmed.
- Everything else requires manual rewrite — the tool flags these with match scores, diff bytes, and optional disassembly.

### Intent consistency scoring

Each candidate's instruction window is classified (`write`, `read`, `branch_gate`, etc.) by `hook_intent_classifier`. The rescorer computes a majority intent across all candidates and penalizes outliers with a 3% weight in the final score. When the top two candidates disagree on intent, `intent_conflict_with_backup` is added to the decision's reason codes to prompt manual review.

### Stability heuristics

`stability/service.py` detects structurally volatile byte positions from raw bytes alone:
- `E8/E9 rel32` — call/jmp relative offsets
- `EB/7x rel8` — short branch offsets
- `0F 8x rel32` — near Jcc offsets
- `[REX] 8B/8D/89 [rip+disp32]` — RIP-relative MOV/LEA displacements
- `FF 15 [rip+disp32]` — indirect call through import table
- `[REX.W] B8+r imm64` — MOV reg, absolute address
- `[REX] C7 /0 imm32` — MOV struct field, immediate

The `hardened_pattern` field wildcards both empirically changed bytes AND structurally volatile positions even if they currently match, producing more durable recommended signatures.

### Key invariants to maintain

- The parser uses `_parse_ce_number()` for all numeric literals — always try hex-with-letter-detection before decimal, since CE auto-assembler uses bare hex (e.g. `10C`) without a `0x` prefix.
- The patcher never modifies the original file; it writes `*.updated.CT` (and backs up any existing `.updated.CT` to `.bak.CT`).
- `bridge.py` must remain compatible with both v11.4.x and v12.x bridges — same pipe name, same `evaluate_lua` method, same `read_memory` response shape (`bytes` list or `data` hex string).
- `workflow.py` checks uniqueness before marking any result `can_auto_fix = True`. Never skip this for new fix paths.
- The postprocess fix threshold (`POSTPROCESS_FIX_THRESHOLD = 0.85`) and high-confidence auto-fix threshold (`HIGH_CONFIDENCE_AUTO_FIX = 0.90`) are defined at the top of `workflow.py` — adjust there, not scattered in caller code.
- The final-score formula weights in `postprocess/rescorer.py` must sum to 1.0. Current weights: byte_score 0.33, confidence 0.19, mnemonic 0.15, structural 0.10, uniqueness 0.10, stability 0.05, history 0.05, intent 0.03.

## Reference material in `AI_Context/`

- `MCP_Bridge_Command_Reference.md` — exhaustive per-command reference with request/response examples. Consult this when working on a specific tool instead of grepping the Lua file.
Expand Down
267 changes: 267 additions & 0 deletions MCP_Server/CT_FEATURE_DISCOVERY_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
# CT Feature Discovery Guide

This document explains how to use the current feature-building tools to create new Cheat Engine hooks from a nearby reference instead of starting from nothing.

The most important idea is:

- use a known working feature as the anchor
- let the tooling narrow and validate candidates
- only then build the final Auto Assembler script

## What Is Built Today

The current feature-building path is:

1. build a feature packet from a known reference hook
2. inspect ranked candidates, intent labels, and sibling-field hints
3. turn the chosen candidate into an Auto Assembler scaffold

The main tools are:

- `python -m ct_updater.feature_builder`
- `python -m ct_updater.script_template_generator`

Supporting helpers used inside the packet flow:

- `hook_intent_classifier/`
- `sibling_field_finder/`
- `method_diff/`
- `preprocess/`
- `postprocess/`
- `uniqueness/`
- `stability/`

## When To Use This Workflow

This workflow is best when:

- you already have one related hook that works
- the new feature is probably in the same method or system
- you want the tooling to reduce the search space before scripting

Examples:

- you know the `Money` hook and want `Gems`
- you know one health/stat write and want a sibling stat
- you know one inventory/resource path and want another field on the same object

This workflow is weaker when:

- the new feature has no nearby reference at all
- the target logic moved into a totally unrelated subsystem
- the final script behavior is highly custom and not a standard hook scaffold

## Step 1: Choose The Closest Reference Hook

Do not start by asking for the final AOB.

Start by asking:

- which known hook is closest in behavior?
- which known hook likely touches the same structure or method?
- which known hook gives me the smallest search area?

A good reference usually shares one or more of:

- same symbol
- same caller
- same structure base register
- same write pattern
- same branch ladder or compare path

## Step 2: Build A Feature Packet

Use the feature builder against a known CT reference.

Example:

```powershell
python -m ct_updater.feature_builder `
--ct-file "C:\path\to\Table.CT" `
--reference "Infinite Item Usage"
```

This writes:

- `<Table>.feature_packet.json`
- `<Table>.feature_packet.md`

You can also choose explicit output paths:

```powershell
python -m ct_updater.feature_builder `
--ct-file "C:\path\to\Table.CT" `
--reference "Money" `
--json-out "C:\work\Money.feature_packet.json" `
--md-out "C:\work\Money.feature_packet.md"
```

### Useful feature-builder options

- `--reference`
Hook name or description from the CT.

- `--target-symbol`
Override the symbol to search when reusing the reference pattern shape against a different method.

- `--target-range`
Override the scan range.

- `--top`
Number of ranked candidates to keep.

- `--disasm-count`
Number of instructions captured per window.

- `--search-multiplier`
How aggressively to sample nearby windows.

- `--no-mono`
Skip Mono initialization if already active.

## Step 3: Read The Feature Packet

The feature packet is the main review artifact for building new features.

It includes:

- the original reference hook
- the reference instruction window
- an intent label for that window
- sibling-field candidates near the reference
- ranked candidate windows
- recommended patterns
- candidate-specific scan ranges
- method diff summaries

### What To Look For

When reviewing candidates, prioritize:

- similar instruction shape
- same structure base register
- nearby field offsets
- a good recommended pattern
- a sensible candidate-specific scan range
- stable uniqueness and stability signals

If the best candidate has:

- low confidence
- bad uniqueness
- very different instruction shape
- no obvious relation to the reference

then do not jump straight to scripting.

## Step 4: Use The Packet To Reduce Human Or AI Work

The packet is designed to replace the old manual workflow of:

- find a hook
- dump nearby disassembly
- run two or three side tools
- manually compare candidates
- then guess a script

Instead, the packet should already answer most of:

- which candidate is most likely related?
- what AOB should I start from?
- what scan range should I use?
- does this look like a write, read, compare gate, or mixed path?
- are there sibling field offsets nearby?

That makes AI prompts much smaller and better.

Good AI question:

- "This packet comes from a working Money hook. Candidate 1 and candidate 2 both look related. Which is more likely to be the sibling resource write for Gems?"

Bad AI question:

- "Find me a Gems cheat from the whole binary."

## Step 5: Generate A Script Scaffold

Once you trust a packet candidate, generate a CE Auto Assembler scaffold.

Example:

```powershell
python -m ct_updater.script_template_generator `
--feature-packet "C:\work\Money.feature_packet.json" `
--candidate-index 0 `
--out "C:\work\Money.generated.aa.txt"
```

This uses the selected packet candidate and emits:

- `aobscanregion(...)`
- `alloc(...)`
- labels
- `registersymbol(...)`
- jump scaffold
- disable section scaffold

The generator now prefers the candidate-specific scan range from the packet, not just the original CT range.

You can also generate directly without a packet:

```powershell
python -m ct_updater.script_template_generator `
--feature-name "MoneyHook" `
--symbol "GameSymbol:Method" `
--pattern "41 89 46 18 85 C0" `
--scan-range 255
```

## Step 6: Finish The Script Logic

The script generator creates the hook scaffold, not the final cheat behavior.

You still need to decide:

- what to overwrite or preserve
- whether to detour, NOP, clamp, or force a value
- what original instructions need to be restored
- what the disable path must undo safely

That part still needs game-specific judgment.

## Practical Example: Money To Another Resource

A strong workflow for "I know Money, now I want another resource" is:

1. build a packet from the known `Money` hook
2. inspect sibling-field candidates and top-ranked windows
3. compare field offsets and instruction shape
4. choose the candidate that looks like the same resource path with a different field or branch
5. generate a scaffold from that candidate
6. write only the game-specific detour logic yourself

This is usually much better than trying to ask an AI to invent the new hook from scratch.

## What Makes A Strong Candidate

A good new-feature candidate usually has:

- a shape similar to the reference window
- the same base register with a different displacement
- the same method or a nearby path in the same routine
- a unique enough signature
- a recommended pattern that is not obviously brittle
- a scan range that makes sense for the found offset

## What This Workflow Does Not Replace

These tools reduce search and validation work, but they do not replace:

- gameplay testing
- script safety review
- enable/disable correctness
- understanding what the code actually does

The tooling helps you trust the hook location.

It does not prove the final cheat semantics for you.
Loading