Files
sacred_k/docs/todo.md
T
khallaandClaude Opus 5.5 7d8089c299 Quests: escorts stay on the follower list, quest givers come back
Escorts lost their place on the hero's follower list after a load, so
quest checks like the one in "Furchtbares Verbrechen" failed; they are
added back once after loading (town NPCs that tag along briefly are left
out). Restarted quests stay available (flag 1), which their giver's dialog
and accepting them need. Quest givers are read from the quest scripts:
when a running quest's giver dies, the quest restarts and the giver is
spawned again at her start; an accepted quest without its giver is repaired
on load. Notes on the script format and opcodes in docs/quests.md.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 02:30:41 +01:00

14 KiB
Raw Blame History

To do

Fixed: aura visuals missing after loading (2026-10-15)

Saving marks effect objects (cObjectFX) dead; loading keeps the buff but drops the aura effect (type 842) that follows the hero. src/mods/aura_restore.cpp recreates it after a load for Heldenmut (0x3f7) and Klingenblick (0x3f8). Spell auras (Steinhaut, Lichtschild, ...) use other effects; the user confirmed on 2026-10-17 that their visuals are back after loading too.

Data-driven arts instead of hardcoded art ids

Asked 2026-10-15: naming single arts as constants (kArtHeldenmut, kArtFlammenwerfer, ... in src/game/engine/arts.h) does not scale. Mods should decide by an art's properties, read from the game's own data:

  • the definition tables g_spellDefs (0x950a38, 71 x 0x94) and g_combatMoveDefs (0x94ddb0, 95 x 0x78): id, icon name, launch type, usable mounted, ... (tools/arttable.mjs dumps them; most fields unnamed);
  • map the remaining fields (regeneration group, lasting effect / aura, duration, ...) and expose them as an ArtInfo lookup in src/game/;
  • where the game itself hardcodes ids (e.g. the arts that always count as magic in cCreatureArts::AddGroupRegen, the "already active" switch in IsValidArtTarget), keep one table of those ids with the reason, instead of named constants spread over the mods;
  • optionally an own data file (JSON next to the DLL) for mod-side settings per art, if we need values the game does not have.

Art ranges: scaling and indicators

Asked 2026-10-15 (after making periodic aura hits strike everything in range, docs/aura-hits.md):

  • art ranges should scale with the art's level, and possibly with new attributes;
  • possibly show a range indicator (e.g. a ring around the hero for auras, or at the cursor for aimed arts).

Known so far: the periodic-hit aura (effect kind 0x12) uses (cCreatureArts +0x56 + 20) * 10 world units, measured from the owner with cCreature::DistanceTo (0x536f20); what +0x56 is (level? a stat?) is not mapped yet. Other arts' ranges are not mapped. Fits the data-driven arts item above (range as a property of an art, one place to compute it).

Mörsergranate impact indicator (asked 2026-10-25, while reworking the dwarf's Kanonenschuss / Mörsergranate): show exactly where the grenade will land and its explosion radius, a red circle with low alpha on the ground. The landing point seems to be decided at launch (cCreature combat move code 0x5145d0, case 0x43e: the target point, changed by a random offset when closer than 200; passed as the position of the grenade's cEventFX 0x96), so the circle could be drawn from the launch until the explosion; to be confirmed with the diagnostic log. To be built after the radius-per-level change.

Rename life leech to "omnivamp"

Asked 2026-10-15: life leech (property 0x349, "Lebensentzug") becomes "omnivamp". To do: the in-game texts (item property, tooltips, character window). The leech code is the game's (0x5707a4.., property 0x349, in the damage code 0x56aff0); it credits the hit's attacker (order +0x1c). Omnivamp usually means healing from all damage, not only weapon hits: aura hits (docs/aura-hits.md) now name their attacker so the game applies it; other damage sources (spells, combat arts' extra hits, damage over time) may follow.

Map and map zoom in widened views

Reported 2026-10-15: the map (and zooming it) does not support the widened render sizes yet. 2026-10-16: TAB map fixed (viewport shifted), M map spans the render width (docs/hud.md, "Large map"), zoomed view and its markers included. Confirmed in-game 2026-10-16.

Quest dialog glitches in widened views

Reported 2026-10-15: accepting a quest, the dialog window "kept glitching" and button clicks were not detected correctly. Probably the HUD layer (src/mods/hud.cpp: windows shifted while they render / handle events): the dialog may not be covered, or shifted twice. Details asked from the user.

WASD walks around walls (caves)

Reported 2026-10-15: in caves WASD movement behaves "as if the player tries to find another way to the target location if a wall comes up". WASD sends a walk order to a point 300 world units ahead (docs/wasd.md); when that point is behind a wall the pathfinder plans a detour. Idea: find the game's straight line / walkability check and shorten the target when the line is blocked (or stop / slide along the wall). Related to the pathfinder item above.

Esc closes an open dialog first

Asked 2026-10-15: with any dialog open (quest, trader, inventory, ...), Esc should close that dialog instead of opening the game menu (ESC menu, cUI_EscMenu). Esc is handled in the engine / UI manager hotkeys (docs/wasd.md: engine 0x618130, UI manager 0x757120).

In-DLL smoke tests (later)

A test mode inside the mod DLL, started by an ini setting or command-line flag, so builds can be checked without play-testing and without driving the real mouse/keyboard like tools/autotest-load.ps1:

  1. load a fixed test save;
  2. play scripted input through the existing hooks (keys, casting arts, weapon set switches, save + reload);
  3. take back-buffer screenshots at checkpoints and log checks to sacredK.log (aura effect present after reload, slot 6-7 inventories survive a save, ...);
  4. exit the game.

Better pathfinder (mouse clicks and monsters)

Replace the game's pathfinding with a more reliable and efficient one, for click-to-move and for monster AI. What we know so far:

  • Walk orders are cEvent_creature command 4 with a ground target (+0x18/+0x1c), sent through cEngine::SendCreatureOrder (0x6170d0), which snaps the target to a walkable point (0x616b70) and hands it to cCreature::ReceiveOrder (0x52e400, vf18, ~6400 decompiled lines).
  • Far targets (~2000 world units) are rejected or followed badly.
  • Still to map: the path search itself, the sector/tile collision data it reads, and how monster AI issues its moves.

Key bindings moved for WASD movement (temporary)

W, A and S were game hotkeys. With WASD movement (src/mods/wasd.cpp) their actions moved to other keys for now; choose final bindings (and update the in-game texts/tooltips that name the old keys):

Key Action Temporary key (sacredK.ini)
W potion kind 3 (cEngine::UseActionSlot, like Q/E/R/B/Space) game potion keys switched off; [keys] Potion1-5 (docs/options.md)
A pick up items nearby (creature event 0x113) Q ([keys] PickUp, 2026-10-17; was V)
S save game window (UI_WND_SAVEGAME) K ([keys] SaveGame)
D unbound -

Hard-coded game keys left (2026-10-19)

Noted after the key bindings page (docs/options.md): these game keys are still hard-coded, not on the page. Each would go the way M / Tab / Alt went: switch the game's key off at its source (switch index byte or compare), add a binding that calls the same game code.

Key Where What (as read, not all measured)
I / F / C UI manager letter switch (0x757120, cases at index bytes 0x75868c + char − 'C') inventory window with tab 1 / 2 / 3 (cCommand_onInvOpen; again: close)
L same quest book UI_WND_QUESTBOOK toggle
H same toggles UI manager flag 0x200 (unmeasured)
T same toggles UI manager flag 0x1000 (unmeasured)
N same network info UI_WND_NETINFO (multiplayer only)
O same, only while the options window is open closes options (applies them)
S same (0x757775) save game window; works only while S is not bound (it is: Nach unten). Spiel speichern already calls this code.
A engine cEngine::ReceiveEvent (0x618130, compare at 0x6188e7) pick up items nearby; same situation as S (A is Nach links); Gegenstände aufheben calls the code
P engine (compare at 0x6188f0) pause, single player only
` / ^ / \ (key codes 0x60, 0x5e, 0xdc) engine (0x6188cf), UI manager (0x75758c, 0x75759c) console
Esc engine, UI manager HandleEsc closes windows / ESC menu (escape.cpp builds on it)
Shift + Space engine potion table (off with the potion keys) -

Digits 0-9 are taken by the skill keys (input.cpp Reserved). Bound keys are swallowed before the game sees them, so a game key only acts while it is not bound to something else: rebinding Nach links away from A brings back the game's A (pickup), same for S. Individual windows may have more keys of their own (not surveyed).

Potion stacks

Asked 2026-10-17 (after the potion counts on the bottom bar, src/mods/potioncounts.cpp): potions of the same type (e.g. minor healing) stack in one inventory cell, up to 20 per stack (a full stack starts a new one). Drag, sell and drop move the whole stack, as with any other item. The counts on the potion slots then add up the stacks. In progress, see docs/item-stacks.md (open: sale price per stack, splitting on the ground).

Walking animation after loading (2026-10-17)

The hero sometimes plays a walking animation after a save game load while standing still. Not reproduced yet: a load log (hero mode, action, animation fields, orders) showed nothing unusual; right after a load the game itself sends one walk order (0x4) while the hero is idle. Measure again when it shows.

Multiplayer with characters (2026-10-19)

Characters became one file each with a world per difficulty (docs/characters.md); vanilla multiplayer picks exported Heronn.pax heroes, which no longer exist. Later: give multiplayer the shared hero of a character file (the session's hero file +0x3a3c, as SelectHeroSlot does), and decide what a multiplayer game does to the character's progress.

Characters: open parts of the rework (2026-10-20)

From the characters rework (docs/characters.md, request of 2026-10-19):

  • Unlock difficulties by story completion. Bronze and Silber stay open; difficulty d >= 2 opens when the story on d - 1 is completed. The counters are one byte per difficulty in cStatsManager +0x5704 (read 0x424be0) and travel in the save header (+0x88..+0x98) and the hero file. Done 2026-10-20 (docs/characters.md).
  • Autosave interval in the options window. Done 2026-10-20: Allgemein page, "Spielstände" frame (docs/options.md).
  • Quickload (row 0, GAME00.PAK) does not know characters; not needed (user, 2026-10-20).

Two saves in a row (2026-10-20, not reproduced)

Once two real saves ("saved", not "autosaved") went into the same character 1.8 s apart, about 77 s after loading, with the timed autosave off. Save flag 0x40 is set in cEngine::ReceiveEvent at 0x618876 (quicksave), 0x618f08 and 0x6190c5 (save event 0xf: +0xc row, +0x18 autosave flag). A log of the event that sets the flag (dwords 0..9) did not catch it again; add it back if it shows.

Once (2026-10-20, not reproduced) an autosave seemed to fire right after a new world started through the hero chain (Character08: hero world loaded, then the new world). The log of that run had no save at all; the timed autosave counts from the game start (OnGameStart).

Savegames screen redesign ("Spielen")

Asked 2026-10-20: redesign the load window (cUI_Savegame, the "Spielen" screen, characters.cpp): show a render of the selected character, use the space far better. No 16:9 artwork exists for the game (user, 2026-10-20): we design our own UIs, using the width beyond the 1024 frame (now drawn in a centred 1024x768 viewport with black sides, hud.cpp FrameScope). Design for 16:9 (1920x1080, 1365x768 UI units), not ultrawide (user). Screen done 2026-10-20 (docs/characters.md, "Spielen screen"; docs/screens.md). Hero in 3D done 2026-10-20. Open: list scrolling beyond 9 characters, larger heading font.

Fine-tuning the Spielen and options screens (2026-10-21)

The user is very satisfied with the menu rework for now (rock background on all menu screens, centred menu frame, logo, Spielen screen with the 3D hero), but both the Spielen screen and the options window still need a lot of fine-tuning. Details to be collected when we get to it; known so far: list scrolling beyond 9 characters, larger heading font, the options window's layout in the width beyond its 1024 frame.

Quest NPCs after the quest (2026-10-25)

Request: NPCs related to a quest are drawn white on the minimaps and always turn towards the player; once their quest is finished they should stop turning and be drawn blue (like other NPCs). Done 2026-10-25 (docs/quests.md, "Quest NPCs after the quest").

Audit how every quest can fail (2026-10-26)

Request: "at some point we need to check ALL the quests and how they possibly can fail". Context: "Jagd auf die Wilderer" (1501) - the giver's death label ex1501 sets the quest variable and runs tot1501, which ends the quest as solved without the reward once the poachers are dead; her survival is not needed for the quest itself. src/mods/questgiver.cpp currently skips a dead giver's label, restarts the quest and respawns the giver. Plan: from FunkCode.bin (label table in Vectoren.bin, 0x54-byte records: name, +0x40 code offset, +0x44 size, +0x48 quest; instructions {u16 op, u16 size, args}) list per quest: death labels given to NPCs (spawn / follow instructions with a 0x05 label), the labels that end it (opcode 0x0f) or lose it, and which NPCs must survive (escorts). Then decide per kind: respawn the giver only, or restart the quest.

Quest giver death rule untested (2026-10-26)

src/mods/questgiver.cpp restarts a running quest whose giver died and spawns the giver again at her start (docs/quests.md, "Quest givers come back"). Built and checked against the scripts, not yet seen in the game: test with an escort whose giver dies (e.g. "Jagd auf die Wilderer" on the Gladiator, or "Hetzjagd"). Borf's case (the quest ended without the reward) was repaired once by hand.

Inventory drawn without its dark backgrounds (2026-10-25, intermittent)

Reported twice: on opening the inventory the item list had no dark background behind the grid, and the tab texts had an odd background colour. Looks like render state (texture / blend / colour) left behind by an earlier draw; not reproduced yet. To find out: what was open or shown just before.

Possibly related (2026-10-25, once): right after a game start the main menu texts were drawn as solid gold blocks (the gold text texture without the font's letter mask). Gone after a restart; Alt+Tab does not cause it. The log showed nothing unusual (all hooks and patches applied).