Why a Patcher, not an Auto-Updater?
In a perfect world, an auto-updater would be the obvious choice: efficient, simple, less work, and fewer moving parts for users. But reality comes with one very non-technical constraint: the Patreon model behind the table ecosystem.
I don't want to put my supporters through a constant "prove you paid" gate just to use the table. No extra friction, no annoying verification steps, no "show receipt to press enable".
But without any kind of entitlement check, an auto-updater would effectively become: free update delivery for everyone, including people without a subscription. That's not "neutral". It actively undermines the support model and can be harmful long-term.
So the simplest solution is not "more DRM" or "more verification". The simplest solution is: table-specific patches.
They act as a hotfix system for release hiccups: fix broken scripts, wrong offsets, missing options, dropdown mistakes, without forcing the user to download a whole new cheat table.
In other words: the Patcher is not trying to replace full releases. It's deliberately designed as a small, targeted hotfix layer that improves stability after release, while keeping everything fair and keeping supporters free of unnecessary verification friction.
Manifold.Patcher exists for one reason: Cheat Tables break. Sometimes quietly. Sometimes catastrophically. And sometimes in ways that only happen for "half of the users".
The Patcher is my answer to maintenance reality: instead of shipping a whole new table for every tiny change, it can apply small, targeted updates to existing records (scripts, options, offsets, dropdowns, flags…) while keeping the process transparent and reversible.
"A patch system isn't about being fancy. It's about making fixes fast, safe, and diagnosable."
— the maintainer who got tired of repeating the same hotfix 20 times
What the module actually does
In simple terms, the Patcher does a few core things:
- Identifies your current table build via a stable fingerprint/hash
- Requests patch data from a remote endpoint (optional)
- Resolves the patch target record reliably (Index » ID » Description)
- Applies controlled changes (schema-based, type-coerced)
- Snapshots everything it touches so changes can be reverted
- Allows disabling the system entirely via config toggles
The Patcher is designed to be boring: predictable behavior, explicit scope, reversible changes, and as little "magic" as possible.
Fingerprinting: "Which table build is this?"
If you want to deliver patches safely, you must know what you're patching. The Patcher generates a table fingerprint and hashes it (MD5) to get a stable ID.
The important part: the fingerprint is built from record properties that actually matter: ID, Description, Type, Options, Script, Offsets and DropDownList.
The module explicitly avoids hashing a memrec's Address,
because addresses are dynamic.
Hashing that would create false "new builds" for no real change.
Patch delivery: Request » Decode » Apply
When enabled, the Patcher can call a remote endpoint and POST a small payload:
your table version and the fingerprint.
The server can then respond with patch instructions for exactly that build.
patch-request.lua-- Manifold.Patcher.lua: RequestPatches(url) local internet = getInternet() if not internet then logger:Warning("[Patcher] Internet unavailable. Cannot check for patches.") return nil end local payload = { version = self.Version, fingerprint = self:GenerateTableHash() } local response = internet.postURL(url, json:encode(payload)) local ok, decoded = pcall(function() return json:decode(response) end) if not ok then return nil end return decoded
If CE's internet object is unavailable, it logs a warning and does nothing. No connection = no patching.
Target resolution: Index » ID » Description
Applying patches is only safe if the correct target record is found. That's why resolution happens in a strict order:
- Index (fastest, most direct when consistent)
- ID (stable if you keep memrec IDs consistent)
- Description as last resort
And because descriptions can be ambiguous, there's a strict mode: if enabled, the found record must match the description exactly, not "closest match".
If StrictTargetResolution is on, the patcher refuses to apply a patch
when the description lookup returns a record whose Description doesn't match
the requested string exactly. This prevents "wrong target" surprises in big tables.
Scope control: the SCHEMA whitelist
The biggest trap with patch systems is turning them into a "remote control" for anything. That's a security and maintenance nightmare.
Manifold.Patcher avoids that by using a whitelisted field schema.
A patch must specify a Path, and that path is resolved against SCHEMA.
Each entry has a kind like:
string,number,booloptions(normalized)offsets(written as OffsetCount + Offset[i])dropdown(normalized list)script(special handling)
That means patches are not "arbitrary code". They're structured edits to specific, expected record fields.
Snapshots: every change is reversible
Before a patch touches a field, the Patcher creates a snapshot for exactly that path. This is used for two things:
- Patch generation (diffing what changed)
- Reverting applied patches later if needed
Without snapshots, patch systems become "apply and pray". With snapshots, a patch can be rolled back cleanly when a build mismatch, a user edge case, or a bad patch happens.
Script patching without turning into regex hell
Scripts are the most common thing that needs hotfixes. The Patcher supports two script patch modes:
- Replace entire script (value is a string)
- Replace a segment via
{ replace, with }
Segment replace defaults to plain mode (safe), meaning the search string is escaped so it's not treated like a Lua pattern. You can opt into pattern mode explicitly if you really need it.
patch.payload.json{ "ID": "HOTFIX_0001", "Target": { "Description": "Some Script Record" }, "Path": "Script", "Value": { "replace": "old snippet", "with": "new snippet", "mode": "plain", "count": 1 } }
Config: disable the whole system when needed
Patching should always be optional. That's why the module includes a config file system with defaults like:
ShouldCheckForPatches(master switch)StrictTargetResolutionConfigFileName
If you want to run fully offline or don't trust live patching for a specific release, you can simply turn it off.
In short
Manifold.Patcher is a maintenance tool: a controlled, reversible patch system for Cheat Engine tables. It fingerprints the table, requests matching patches, applies only whitelisted changes, snapshots everything, and supports strict target resolution to avoid mispatching.
It's not meant to be clever. It's meant to keep tables alive when reality happens.
Leunsel