Files
khallaandClaude Opus 5.5 5df7efc198 Docs: local Sacred Gold install required, no hard-coded game path
README explains --game-dir and the stored GameDir; the VS Code launch
uses the stored path and builds through build.ps1.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 00:14:36 +02:00

106 lines
3.9 KiB
Markdown

# sacredK
An incremental reimplementation of **Sacred Gold 2.28** (`sacred.exe`, 2006).
`sacredK.dll` is injected into the original game at startup and replaces game
functions with rewritten C++ one by one. Everything not yet rewritten keeps
running as original machine code, so the game stays playable at every step and
each rewrite can be tested in-game immediately. Once enough is rewritten, the
original executable can be dropped.
No game assets or original code are included; you need your own installed copy
of Sacred Gold.
## Supported build
Only this executable is supported (all hook addresses are specific to it):
| | |
|---|---|
| File | `sacred.exe`, 12,103,680 bytes |
| SHA-256 | `fe774c6f985b02c9ce03103c2e55e5d853258c0cc3c737ccd211219c74460cb9` |
| PE timestamp | `0x451BBE74` (2006-09-28) |
The DLL checks the timestamp and image size at startup and leaves any other
build unpatched.
## Building
Requirements: Visual Studio 2022 Build Tools ("Desktop development with C++",
MSVC x86 + Windows SDK), CMake ≥ 3.24, Ninja, git (Detours is fetched at
configure time).
```powershell
.\build.ps1 # x86-debug -> build\x86-debug\
.\build.ps1 x86-release # x86-release -> build\x86-release\
```
Everything is 32-bit x86: the code runs inside the 32-bit game process. In an
IDE (CLion, VS Code), select an MSVC toolchain with **x86** architecture and use
the CMake presets.
## Running
The game is not part of this repository. You need a local installation of
Sacred Gold 2.28 with the `sacred.exe` listed under [Supported build](#supported-build)
(e.g. the Steam or GOG release), and you tell the launcher its folder once:
```powershell
build\x86-debug\sacredK.exe --game-dir "<Sacred Gold folder>" # first run; remembered in sacredK.ini
build\x86-debug\sacredK.exe log # later runs; extra args go to the game
```
The folder is stored as `[paths] GameDir` in `sacredK.ini` next to the
launcher (one per build preset, not tracked by git). Without it, the launcher
looks for `sacred.exe` in its own folder and otherwise asks for `--game-dir`.
The VS Code launch configuration relies on this stored path too.
Save games and the game's `Settings.cfg` live in `Documents\Sacred\save` and
`Documents\Sacred\config`; on the first start they are copied there from the
game folder (see `docs/user-folders.md`).
`sacredK.log` (next to the DLL) records what was hooked plus every message the
game sends to its internal logger, even when the game's own logging is off.
Hooks can be switched off individually in `sacredK.ini` (next to the DLL)
to compare a rewrite against the original:
```ini
[hooks]
CmdLineHasFlag=0
```
## Layout
```
src/re/ hook framework, injection-side startup, logging, config
src/launcher/ sacredK.exe — starts sacred.exe with the DLL injected
src/game/ rewritten game code and original-layout structs, by subsystem
src/mods/ behaviour changes on top of the original (e.g. borderless.cpp)
docs/ reverse-engineering notes; function-map.md tracks progress
```
## Adding a rewritten function
```cpp
namespace game {
bool __cdecl CmdLineHasFlag(const char* cmdline, const char* flag, bool quiet);
RE_HOOK(0x00813140, CmdLineHasFlag); // also defines CmdLineHasFlag_original
bool __cdecl CmdLineHasFlag(const char* cmdline, const char* flag, bool quiet) { ... }
}
```
The signature and calling convention must match the original exactly. Add the
file to `CMakeLists.txt` and a row to `docs/function-map.md`.
## Portability rules (for an eventual 64-bit build)
The game is 32-bit and must stay so while we hook into it, but new code should
not make that permanent:
- use fixed-width types (`uint32_t`, not `long`/`DWORD`) for anything with a
fixed layout;
- never store pointers in, or cast pointers to, 32-bit integers;
- keep file and network formats behind explicit serialization code instead of
`fwrite`-ing structs.