04. Reverse-Engineering The Game¶
STS2 does not currently expose a separate, versioned mod SDK. Reverse engineering is therefore ordinary compatibility work: inspect the release that will execute the mod, identify the narrowest supported integration point, and record the evidence behind the decision.
Evidence Sources¶
Use each source for the question it can answer:
| Source | Best for |
|---|---|
release_info.json |
exact release and commit |
sts2.runtimeconfig.json |
target framework and bundled runtime |
sts2.dll |
types, signatures, call order, hooks, and loader behavior |
SlayTheSpire2.pck |
scenes, localization, images, and exact res:// paths |
| runtime logs | what the executable actually attempted |
| clean installation test | whether all layers work together |
A decompiler can produce awkward names for compiler-generated arrays and state machines. Treat those artifacts as presentation noise; focus on public signatures, control flow, path construction, and method calls.
Start From The Domain Object¶
Search by the object the player interacts with, not by a guessed patch site:
- cards:
CardModel, a simple vanilla card, its pool, andCardPileCmd - potions:
PotionModel, a simple potion, its pool, and use commands - relics:
RelicModel, a simple hook-based relic, and its pool - events:
EventModel,EventOption, the targetActModel, andEventRoom - UI: the concrete native screen, its stack, host, tooltip layer, and focus context
The nearest simple vanilla implementation is usually the best executable specification. For example, Backflip, SwiftPotion, Anchor, and ThisOrThat demonstrate the current constructor, dynamic-variable, async command, and event-option patterns without large amounts of unrelated logic.
Assembly Workflow¶
With ILSpy command-line tooling, a focused query has the form:
ilspycmd --disable-updatecheck `
-t 'MegaCrit.Sts2.Core.Models.Cards.Backflip' `
'<STS2>\data_sts2_windows_x86_64\sts2.dll'
Repeat the query for the base model and the pool. Do not copy a concrete implementation before checking which members are inherited and which paths are computed by the base class.
High-value current types include:
MegaCrit.Sts2.Core.Modding.ModManagerMegaCrit.Sts2.Core.Modding.ModManifestMegaCrit.Sts2.Core.Modding.ModHelperMegaCrit.Sts2.Core.Helpers.ReflectionHelperMegaCrit.Sts2.Core.Models.ModelDbMegaCrit.Sts2.Core.Hooks.Hook
The current loader's directory scan and initializer methods are private implementation details. Inspect them when validating behavior, but do not build mod code that calls them directly.
PCK Workflow¶
The game-shipped PCK tool can list or extract selected files:
godotpcktool.exe `
--pack '<STS2>\SlayTheSpire2.pck' `
--action list `
--include-regex-filter '^localization/eng/(cards|potions|relics|events)\.json$'
Prefer selective extraction. The main pack is large, while most questions concern one table, scene, or image family.
Use the PCK to verify:
- whether localization is a flat key/value table or a nested object
- whether a model expects a PNG, imported texture, atlas resource, or scene
- the exact slug and case used in paths
- the native scene hierarchy before reusing a UI screen
Trace The Full Contract¶
For new content, answer these questions before implementation:
- How does
ModelDbdiscover the type? - Which pool or list allows generation to select it?
- Which localization table and keys does the base class construct?
- Which resource paths are fixed, virtual, or derived from the pool?
- Which unlock or catalog filters can hide it?
- Which mutable owner state is required when the effect runs?
- Which save representation stores its model ID or fields?
This prevents partial integrations. A type can exist in ModelDb but never be generated; it can be generated but fail in hover UI; it can render in combat but disappear from the library; it can work until a save is loaded.
Update Maintenance¶
After every STS2 update:
- compare
release_info.jsonand the assembly hash - rebuild against the new shipped DLLs
- re-decompile every patched method and every inherited base model used by the mod
- re-list PCK paths used by custom resources
- test a clean new run and a save created by the previous release
Compilation is only the first compatibility check. Harmony targets, reflection names, resource paths, and lifecycle order can change without producing compile errors.