khallaandClaude Opus 5.5 db87e276bf Menu screens: rock background, centred frame, logo, 3D hero
- Spielen hero panel shows the selected hero in 3D (cUI_NetGranny,
  game/ui/granny.h).
- All menu screens draw on the options' rock wall; the main menu's 1024
  frame is drawn centred over it, mouse and cursor shifted to match.
- The main menu's and options' own pictures and the main menu's 3D scene
  are left out (textures hidden by surface, scene call redirected).
- Logo top left: FX_SACREDLOGO.TGA, drawn added.
- Game textures by name (game/ui/texture.h), textured and added quads.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 00:05:55 +02:00
2026-10-13 23:55:57 +02:00

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).

.\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 (e.g. the Steam or GOG release), and you tell the launcher its folder once:

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:

[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

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.
S
Description
custom sacred "fork"
Readme
1.1 MiB
0 Stars 1 Watchers 0 Forks
Languages
C++ 93.9%
JavaScript 3%
Java 1.3%
PowerShell 1.3%
CMake 0.5%