Halls Of Torment - Cheat Scripting Practice Log

A context providing post for novices who wish to tackle Godot Engine with their custom scripts.

The main forum for Cheat Table database collections.


Moderator: Table Moderator

WanderingNovice
Cheater
Cheater
Posts: 21
Joined: Sat Jul 25, 2026 7:40 am
Answers: 0
x 10

Re: Halls Of Torment - Cheat Scripting Practice Log

Post by WanderingNovice »

Author: A human being.
Co-author: An artificial intelligence.
Proofreader: A human being.
Formatter: A human being.


Documentation for: Volume 02: Halls of Torment — Script for Unified Multiplier


Hestia – Leaving No Trace

The last god to speak is Hestia. She does not appear until [DISABLE], and she never gets the spotlight in disassembly screenshots, but a script that forgets her is a script that dirties the house every time it leaves. Hestia's job is to put everything back where it was: the original bytes, the symbol table, the timers, and the memory.

In concrete terms, Hestia has three obligations:

  1. Restore instructions. For each hook site, she copies the saved bytes from multiplierSite*OriginalBytes back to the AOB address that Ares or Apollo patched on enable. When she is done, the disassembly at each site is exactly what the game shipped with — same call, same cvttss2si, same mov [rdi+168],eax or movss [rdi+168],xmm0.

  2. Tidy the symbol table and timers. Every symbol Hephaestus registered — all 127 of them in the final v1.7 build — is unregistered here. That includes every per-stat parameter, every cache pointer, and the original-byte buffers themselves. Hestia also checks whether multiplierUnifiedCacheTimer still exists and, if so, destroys it and clears the Lua-side reference, so Hermes is not left walking chains for a script that no longer has any hooks.

  3. Release memory. Any regions allocated with alloc — the code caves and parameter tables — are deallocated, returning that memory to Cheat Engine's allocator. From the game's point of view, nothing changed; the hooks were always in CE-side allocated memory, and now even that is gone.

The Learner Edition sets a standard that every Volume 2-grade script has to meet: you should be able to toggle it on and off repeatedly in a live session without accumulating hooks, leaking timers, or leaving stray symbols behind. Hestia is the reason this script passes that test. If Zeus defines the rules, Athena enforces safety, Hephaestus builds the machinery, Demeter lays out the data, Ares and Apollo do the work, and Hermes delivers the pointers, Hestia is the one who makes sure that, when you are done, you can close the table, quit the game, and not wonder what you forgot to put away.

Hestia – Disable & Cleanup

At [DISABLE], Hestia works backward through everyone else's handiwork: she returns Ares' three integer doors and Apollo's float door to their saved instructions, removes the names Hephaestus published, releases Demeter's tables and the code caves, and stops Hermes' cache work. Her standard is stricter than "disabled": after the sequence completes, the game's hook sites and Cheat Engine's working state should carry no trace of the script.

Code: Select all

[DISABLE]

// Hestia: restore Ares' first door from Hephaestus' saved original bytes
multiplierSiteAAob:
readmem(multiplierSiteAOriginalBytes,22)

// Hestia: restore Ares' second door from Hephaestus' saved original bytes
multiplierSiteBAob:
readmem(multiplierSiteBOriginalBytes,15)

// Hestia: restore Ares' third door from Hephaestus' saved original bytes
multiplierSiteCAob:
readmem(multiplierSiteCOriginalBytes,15)

// Hestia: restore Apollo's float door from Hephaestus' saved original bytes
multiplierFloatSiteAAob:
readmem(multiplierFloatSiteAOriginalBytes,17)

// Hestia: unregister Max Health's per-stat symbols Hephaestus registered
unregistersymbol(maxHealthMultiplier)
unregistersymbol(maxHealthSafetyClamp)
unregistersymbol(maxHealthOutputCap)
unregistersymbol(maxHealthSanityMin)
unregistersymbol(maxHealthSanityMax)
unregistersymbol(maxHealthIntendedValue)
unregistersymbol(maxHealthSiteASanityRejectCount)
unregistersymbol(maxHealthSiteBSanityRejectCount)
unregistersymbol(maxHealthSiteCSanityRejectCount)
unregistersymbol(maxHealthContainerCache)

// Hestia: unregister the remaining integer-stat symbol families Hephaestus registered
// ... Block Strength, Defense, and the Zweihänder integer stats repeat the same family pattern.

// Hestia: unregister Health Regen's per-stat symbols Hephaestus registered
unregistersymbol(healthRegenMultiplier)
unregistersymbol(healthRegenSafetyClamp)
unregistersymbol(healthRegenOutputCap)
unregistersymbol(healthRegenSanityMin)
unregistersymbol(healthRegenSanityMax)
unregistersymbol(healthRegenIntendedValue)
unregistersymbol(healthRegenSiteASanityRejectCount)
unregistersymbol(healthRegenContainerCache)

// Hestia: unregister the remaining float-stat symbol families Hephaestus registered
// ... Movement Speed, Experience Gain, and the Zweihänder float stats repeat the same family pattern.

// Hestia: unregister Hephaestus' global backup and float-hook symbols
unregistersymbol(multiplierSiteAOriginalBytes)
unregistersymbol(multiplierSiteBOriginalBytes)
unregistersymbol(multiplierSiteCOriginalBytes)
unregistersymbol(multiplierFloatSiteAAob)
unregistersymbol(multiplierFloatSiteAOriginalBytes)

// Hestia: return code caves and Demeter's tables to CE's allocator
dealloc(multiplierSiteANewMem)
dealloc(multiplierSiteBNewMem)
dealloc(multiplierSiteCNewMem)
dealloc(multiplierStatParams)
dealloc(multiplierSiteAOriginalBytes)
dealloc(multiplierSiteBOriginalBytes)
dealloc(multiplierSiteCOriginalBytes)
dealloc(multiplierFloatSiteANewMem)
dealloc(multiplierFloatStatParams)
dealloc(multiplierFloatSiteAOriginalBytes)

// Hestia: destroy Hermes' timer if still alive
{$lua}
if not syntaxcheck then
  if multiplierUnifiedCacheTimer then
    multiplierUnifiedCacheTimer.destroy()
    multiplierUnifiedCacheTimer = nil
  end
  if multiplierIntCacheTimer then
    multiplierIntCacheTimer.destroy()
    multiplierIntCacheTimer = nil
  end
  if multiplierFloatCacheTimer then
    multiplierFloatCacheTimer.destroy()
    multiplierFloatCacheTimer = nil
  end
  showMessage('Unified Multiplier Script disabled cleanly.')
end
{$asm}

A few things to notice in shape:

  • Each readmem restores the exact byte snapshot that Hephaestus saved before Ares or Apollo replaced that site with a jump. The four lengths — 22, 15, 15, and 17 — belong to their respective stolen-instruction regions; they are not interchangeable.
  • The two complete per-stat families show the deliberate difference between the integer path and the float path: Max Health has three site-specific sanity counters, while Health Regen has one. The ellipses omit only repetitive unregistersymbol families; Hestia still removes every one in the full block.
  • The five global unregistersymbol calls are the infrastructure names outside those per-stat families: the three integer backup buffers, the float hook symbol, and the float backup buffer. They are the public names Hephaestus exposed so the rest of Cheat Engine could use them.
  • Only after the symbols are gone does Hestia return all four code caves, both of Demeter's parameter tables, and every byte-backup allocation to Cheat Engine. Deallocating the backup before its readmem replay would leave nothing safe to restore.
  • The excerpt groups the four readmem restores at the top for readability. In the full source, [DISABLE] interleaves each site's restore with the same site's unregistersymbol and dealloc calls; both orderings are semantically equivalent, provided that every readmem runs before its own buffer is deallocated.
  • The Lua tail is guarded by if not syntaxcheck then, so it runs during a real disable rather than Cheat Engine's parse-time pass. It destroys Hermes' live unified timer and also clears the two obsolete v1.4 timer names if an older table left them behind.

License: https://creativecommons.org/publicdomain/zero/1.0/


Tags:

Post Reply