-
-
Notifications
You must be signed in to change notification settings - Fork 3
Installation
SacredSDK lets you mod Sacred Gold (Ascaron, 2004) in Lua without touching a
single original game file. Mods live in custom/, and the game reads them
through a thin DLL injected at startup.
Verified on Sacred Gold Steam, build 2.0.2.28 (2006-10-13).
- How it hangs together
- Installing the proxy DLL
- The mod tree
- Verifying the install
- The overlay
- Rolling back
The SDK ships as a proxy ijl15.dll that the game loads automatically at
launch (Sacred imports the Intel JPEG library ijl15.dll, so a DLL of that
name next to Sacred.exe is loaded before the game's entry point runs). The
proxy forwards every JPEG call to the renamed-original ijl15_real.dll, so the
game behaves identically — the only new code is our DllMain, which boots the
SDK.
Once running, the SDK does two things:
+-- DLL load --+
Steam runs Sacred.exe -------------> | ijl15.dll |
+------+-------+
|
+------------------------------+--------------------------+
| |
v v
+------------------+ +---------------------+
| Embedded Lua | scans custom/lua/**/*.lua, | IAT hook on |
| (5.4) | executes each, writes the | CreateFileA |
| | result to custom/<rel>.bin | |
+------------------+ | Redirects any read |
| of bin/<X> -> |
| custom/bin/<X> |
| (if it exists) |
+---------------------+
|
v
Sacred opens FunkCode.bin etc.
and never knows it was modded.
Two halves:
- A bake (Lua ->
.bin) that runs once at game startup. Each.luamod is executed and its result written to a matching file undercustom/bin/. - A read-time override (
fs_override) that swaps in your custom files when Sacred opens something. The vanillabin/tree is never modified.
See Reverse Engineering for the mechanism in detail.
The proxy is ijl15.dll.
From a release archive: extract it into the game folder and run
install.cmd — it renames the game's own ijl15.dll to ijl15_real.dll and
puts the SDK proxy in its place. uninstall.cmd undoes exactly that.
From a source build, by hand, from the game install root (<Sacred Gold>/):
:: back up the original Intel JPEG library (do this ONCE)
copy ijl15.dll ijl15_real.dll
:: drop the SacredSDK proxy in
copy sdk\Release\ijl15.dll ijl15.dllState afterwards:
| File | What it is |
|---|---|
ijl15.dll |
the SacredSDK proxy |
ijl15_real.dll |
the original Intel JPEG library (renamed) |
That is the whole install. The SDK edits none of the game's data files, and
custom/ and sdk/ are folders Steam does not track. ijl15.dll is a game file,
though: Steam's "Verify integrity of game files" restores the original
ijl15.dll, and the SDK stops loading. Run install.cmd again afterwards (it
finds ijl15_real.dll already in place and only copies the proxy back).
There are two Lua trees and yours wins.
<Sacred Gold>/
|-- ijl15.dll <- SacredSDK proxy (don't edit)
|-- ijl15_real.dll <- original; we forward to it
|-- bin/, scripts/, ... <- vanilla; never touched
|-- sdk/ <- THE FRAMEWORK (ships with the SDK)
| |-- ijl15.dll <- the proxy, before install.cmd copies it out
| +-- custom/lua/
| |-- lib/ <- the standard library: quests, NPCs, dialog, zones...
| +-- examples/ <- copy-paste starters (01_hello.lua ... 15_storyline.lua)
+-- custom/ <- YOURS
|-- lua/
| |-- lib/ <- optional: a patched copy of any framework module
| |-- mods/ <- YOUR runtime mods (return {}; replace no game file)
| +-- bin/ <- YOUR script mods, mirroring the game's bin/
| +-- TYPE_NPC_*/ <- per-class scripts
| |-- QuestCode.lua
| +-- FunkCode.lua
|-- mods/ <- auto-generated by the bake; the game reads none of it
|-- bin/ <- auto-generated by the bake, served via fs_override
+-- scripts/ <- auto-generated (e.g. scripts/us/global.res)
The priority rule, for both mods and library modules: a file under
custom/lua/<path> beats the file at sdk/custom/lua/<path>. So you can
replace any single framework module, or a mod the SDK ships, by putting your
version at the same relative path — the SDK's copy is then skipped, not merged.
require "npcobj" searches your lib/ first and the framework's second.
Baked output always lands in your custom/ tree; the sdk/ tree is only
ever read. custom/bin/ and custom/scripts/ are generated — don't edit them.
A mod's location decides which game file it overrides. A file at
custom/lua/bin/TYPE_NPC_GLADIATOR/QuestCode.lua bakes to
custom/bin/TYPE_NPC_GLADIATOR/QuestCode.bin, which the fs_override hook then
serves whenever Sacred opens bin/TYPE_NPC_GLADIATOR/QuestCode.bin.
That holds for every mod, whatever it returns. A runtime mod (NPCs, dialog
buttons, zones: callbacks that run while the game does) returns {} and bakes to
an empty file, so keep it in custom/lua/mods/, which mirrors no game file. At a
path such as custom/lua/bin/TYPE_NPC_GLADIATOR/FunkCode.lua it would hand the
game an empty FunkCode.bin for that class. The bake skips only the folders
lib/, examples/ and those whose names start with _.
- Launch Sacred (via Steam or directly).
- Look at
sdk/logs/sdk_loaded.log. On a working install you will see aDllMain DLL_PROCESS_ATTACHbanner with the exe path, then bake lines like[lua_bake] baked '...' -> '...'. - The SacredSDK overlay (toggle F11 to interact) shows live bake stats:
baked files,baked records, and the laststatus.
A quick override smoke test, from the game root:
copy scripts\us\global.res custom\scripts\us\global.res
:: launch Sacred, reach the main menuThe overlay's Custom/ overrides panel should then show redirected >= 1 with
last pointing at scripts\us\global.res -> custom\scripts\us\global.res.
The SDK draws its own window over the game.
| Key | Action |
|---|---|
| F12 | Show or hide the overlay, the SDK's messages (sacred.notify) included. |
| F11 | Switch the mouse and keyboard between the overlay and the game. The overlay has them when the game starts, so if the game ignores the mouse, press F11. |
| F7 | Copy the hero's map position to the clipboard as X, Y and write it to the log ([overlay] F7 -> hero map pos). These are the coordinates o:teleport, zones and sacred.hero_pos() use. |
| F8 | Write the quest book to the log. |
| F9 / F10 | Clear the runtime trigger ring / write it to the log. |
Delete the proxy and restore the original:
del ijl15.dll
ren ijl15_real.dll ijl15.dll :: or: copy /y ijl15_real.dll ijl15.dllDeleting an individual override file under custom/ restores that one vanilla
file on the next launch; the SDK is fully reversible.
- Quick Start — three working mods in 15 minutes, the same tutorial as the Steam guide.
- Writing Your First Mod — the three authoring layers and your first quest.
- Quests and Dialog Authoring — the bake-time quest / dialog / text / state system.
-
Lua API Reference — the full
sacred.*runtime API.
Getting started
Authoring
- Quests and Dialog Authoring
- Native Quests
- Runtime NPCs
- Hero Classes
- Dialog Text
- Dialog Nodes (catalogue)
The engine's own verbs
Reference