Files
khallaandClaude Opus 5.5 e13b82f040 Quests: restart resets variables, respawns giver and NPCs; final failures
Quest audit (docs/quest-audit.md, tools/questscript.mjs), fixes 2-8.
New mods/questscript.cpp scans the script code once (giver, own variables,
needed NPCs, QIS_OnEnter creations, story-ending failure labels).
questfail: generic, giverless, story-ending and NPC-gone failures stay
final; a restart restores the variables snapshot taken at Quest_Trigger,
deletes OnEnter leftovers, respawns the giver and needed NPCs and gives the
accept dialog back. questgiver slimmed on top of questscript.

Not yet tested in game.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 02:03:20 +01:00

279 lines
31 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Quest audit: how quests fail or get stuck (2026-10-30)
Request (2026-10-26, started 2026-10-30): "iterate through all quests in the
game, and check their conditions for potential failing or stuck up points
given the current implementation and our attempted reset". Done one quest at
a time from the compiled scripts with `tools/questscript.mjs` (full dump:
`<dir> <id>`; compact: `<dir> --facts <id>`).
Scripts: Ancaria per hero class `bin\TYPE_NPC_<class>\` (the game writes the
one in use to `bin\sgf.bin`; this audit reads `TYPE_NPC_GLADIATOR`, the class
variants differ in a few class quests), Underworld `bin\Addon\NetScriptCamp\`.
Ancaria: 603 quests in the table (87 + 13 side quests, ~37 main quests, 352
generic `DQ_` quests from 16 templates, multiplayer / unnamed sets);
Underworld: 190.
## What our mods do (the "reset")
- **M1 failure restart** (`questfail.cpp`, `Quest_End` hook): after
`LoseQuest` ran the quest's failure script (`QIS_OnLose<id>`), the flags go
back to available (1), the book entry stays failed with its compass on the
giver. Quest variables and NPC states are left as they are.
- **M2 giver death** (`questgiver.cpp`): a label of a running quest run for
its dead giver (the giver: the NPC spawned with a dialog that has the accept
button) is skipped, unless the giver is hostile to the hero (2026-10-30);
the quest restarts (M1 plus the variables only this quest writes: 0, the
one named after the quest: 1) and the giver's spawn instruction runs again
once the body is gone.
- **M3 load repair** (`questgiver.cpp`): a running quest whose giver is not
alive after loading gets M2, unless the quest morphs its giver.
- **M4 followers** (`followers.cpp`): escorts back on the hero's follower
list after loading; followers more than 40 cells away are teleported to the
hero.
## General findings
- **G1 M1 keeps the quest variables.** Givers' dialogs choose their branch by
bits of the quest variable (`IF 49(bit, "<id>")`); bits set while the quest
ran stay set after a failure, so the giver shows a "still running" branch
without the accept button and the quest can never be taken again. Example
702: the girl's death runs `lose702`; variable 702 keeps bit 1, the giver
answers "Qoffen01" with `ok702`. Fix: M1 resets the quest's own variables
like M2.
- **G2 generic quests (2600..3599)** are the game's random quest pool;
`Quest_End` already copies them under a new id. M1 should leave them (and
their runtime copies) to the game.
- **G3 one-time world progress.** Many targets are spawned once by the start
script or `Region<N>Init`, not by the quest. When M2/M3 reset the quest's
variables after such a target died, the progress is lost and the target
never comes back: stuck. Either keep the variables on M2/M3 or respawn the
quest's one-time NPCs (see G6).
- **G4 duplicates on re-accept.** `QIS_OnEnter` creates the quest's NPCs and
objects again; after a failure the old ones may still be alive.
- **G5 givers deleted by the script** (`DelNPC` on the giver): M3 restarts a
quest whose giver is gone on purpose.
- **G6 restart without the NPCs.** The restart is pointless when the NPCs the
quest needs are one-time spawns and dead or deleted. Idea: respawn them from
their spawn instructions like the giver.
- **G7 quests without a giver** (trigger areas): M1 "restarts" them and erases
the failed book entry.
- **G8 givers turned hostile by `SetNPCState ... 08 12`** instead of `Morph`
are not in `g_giverTurns`; M3 restarts those quests wrongly, M1 points the
book at an enemy.
- **G9 shared variables.** M2 doesn't reset quest variables another quest's
label also writes, so the respawned giver shows a running branch.
- **G10 giver killed after the quest ended** (by its own script): M2 doesn't
act, the giver stays dead.
- **G11 failure continues a chain.** Some failures are part of a quest chain
(`LoseQuest` together with `SetUpQuest` of the next quest, giver's dialog
moved on); M1 must not restart those.
- **G12 state in dialogs (Underworld).** Underworld quests keep their state
in the NPCs' dialogs; a failure sets a "done/lost" dialog (or none), and M1
doesn't put the accept dialog back (7614, 10260).
- **G13 named ids.** Spawns with named ids (`res:AUFTRAGGEBER_10254`,
`res:Sam1_Knappe`) or the id after the type argument aren't read by
`InstructionScriptId`; those givers aren't in `g_givers`.
- **V1/V2 vanilla bugs:** 1101's time-out never ends the quest; Res:17163 is
used by both 602 and 1202, and 602 deletes 1202's patient.
## Per quest
Columns: how it can fail (vanilla), what happens with our mods, verdict
(ok / G<n> / finding).
| Quest | Fails by | With our mods | Verdict |
|---|---|---|---|
| 151 Tierischer Wilddieb | never (no LoseQuest); wolf Res:17081 (start script, death `stirb151`: bit 2, triggers the quest) | M2/M3 on giver death: variable 151 reset to 1; if the wolf is already dead, bit 2 is lost and the wolf never respawns: stuck | G3 |
| 152 Botendienst | time limit (`SetTimer` 4320 -> `zeit152`: bit 4, `LoseQuest`) | M1: bits 1 + 4 stay, the giver answers "Qfail" / "Qpostfail" without the accept button: stuck. With G1 reset: offered again; re-accept spawns the parcel (Res:6027) and later the recipient Res:17077 again (the old recipient stays, dialog off) | G1, G4 |
| 154 verschwundener Schmied | never | the script deletes the giver Res:17626 (`talkedbride154`, `take154`): after the next load M3 restarts the running quest and spawns the giver again | G5 |
| 201 Vermisste Tochter nach Ausritt | daughter Res:18006 dies (`Tochtertot201`: bit 8, `LoseQuest`); she is spawned once (`Region2Init`) | M1: bit 8 stays, giver answers `okt201` then `ok201`: stuck. With G1: offered again, but the daughter stays dead: cannot be finished | G1, G6 |
| 202 Eskorte für Händler | merchant Res:18012 (the giver) and bodyguard Res:18013 both dead, or the bodyguard alone at the bridge | the merchant's death is M2 (restart, respawn; his dialog has no bit tests); the bodyguard is not needed | ok |
| 203 Schatzkarte | never | giver death -> M2; re-accept creates map + chest again (old chest stays) | ok (G4) |
| 204 Die Bücher der Gelehrigkeit | never | giver death -> M2; the boss and the book come from `QIS_OnEnter204`, so a restart can be redone | ok |
| 301 Orks auf Bauernhof | time limit (`SetTimer` 1440 -> `lose301`); farmer Res:17033 and daughter Res:17032 both dead | no giver (trigger area, deleted on start); `QIS_OnLose301` deletes both NPCs. M1 makes it available but nothing can start it again, and with no known giver its failed book entry is erased | G7 |
| 302 Von Räubern und Rindern | six cattle dead (`302a` = 6, `LoseQuest`); the giver Res:17029 (escorted) dies (`tot1_302`) | giver death -> M2 (but `302a` is also set by `startcode`, so it is not "only this quest's" and keeps its count). Cattle failure -> M1: the dialog's `48(6,"302a")` branch sets bit 3 -> "ok" forever: stuck, also with G1 unless G1 counts start-script initialisation as the quest's own. Re-accept spawns the six cattle again | G1 (start-script variables), G4 |
| 303 Bodycount Orks | never; ogre Res:17031 is a one-time spawn (`Region3Init`, death `tot303`: bit 2) | as 151: giver death resets bit 2, a dead ogre never returns: stuck | G3 |
| 401 Jagd auf wildernde Wölfe | never; wolves one-time (`Region4Init`, death `stirb401`: bit 2) | as 151 | G3 |
| 402 Kräuter für Kräuterhexe | never | herbs from a permanent `MouseEvent` (`Region4Init`), can be picked again after M2 | ok |
| 403 Kühe vor Wölfen retten | all cows dead (bit 4), then the giver's answer runs `lose403` | M1: bits 4 + 5 stay, giver "ok403" forever: stuck. With G1: offered again, but the cows (`Region4Init`) are gone | G1, G6 |
| 501 Geister auf Landsitz | never by `LoseQuest`; choice `change501` / `nochange501` | `postchange501` turns giver Res:17071 and Res:17070 hostile with `SetNPCState ... 08 12` (not Morph): M2 sees the hostility at death, but M3 after a load would restart the quest (only Morph is known as "turns") | G8 |
| 502 Verstecktes Waffenlager | never | enemies and boss from `QIS_OnEnter502` (variant by `Globalchange1`): redoable after M2 | ok |
| 503 Botschaft an Geliebte | never | giver Res:17105's death label `weg503` belongs to no quest (M2 does not react); not needed: the quest ends at the lover Res:17104 | ok |
| 601 Kunstraub von Händler | never | thief Res:17135 gives the item by dialog; redoable after M2 | ok |
| 602 Wegelagerer | never | the knight Res:17136 is beaten, not killed (`ritter602` sets his HP back); after M2 his dialog offers the fight again | ok |
| 603 Entlaufener Bräutigam | never | the groom Res:17140 is beaten (`braut603` heals him), the fight can be repeated after M2 | ok |
| 701 Vergifteter Brunnen | never (`lose701` is not called) | boss Res:17063 one-time (`Region7Init`, drops the items); M2 resets bit 20 (item taken): stuck if the boss is dead | G3 |
| 702 Mädchen bei Ausritt verschwunden ("Familienbande") | the girl Res:17060 dies (`lose702`) | giver turned hostile and killed: handled (7ec0fa2). Girl's death -> M1: bit 1 stays, giver "Qoffen01": stuck; with G1 redoable (the girl comes from `QIS_OnEnter702`) | G1 |
| 703 Objektschutz Wegbrücke | leaving the bridge area / region before the bandits are dead (`zeit703`: bit 4), then the giver's answer runs `lose703` | M1: bits 4 + 5 stay, giver "ok703": stuck. With G1: redoable (bandits not all dead, else the quest would have been won) | G1 |
| 801 Holzfällerstreit mit den Elfen | the giver Res:17144 dies (`tod801` -> `lose801`) | giver death -> M2 (restart, respawn) instead of the failure | ok |
| 802 Königliche Jäger Verschollen | never | hunters, herbs and amulet are one-time (`Region8Init`); M2 resets 802 (progress bits): stuck when they are used up | G3 |
| 803 Kopfgeldjagd | never | targets one-time (`Region8Init`). On giver death M2 does not reset `803` (quest 801's elf dialog also sets a bit in it), so the respawned giver shows the running branch without accept and the flags say "available": stuck | G3, G9 |
| 901 Soldaten verschleppen Frauen | time limit (`zeit901`, also kills quest 902's women); the women Res:17051..17054 die (`lose901`: bit 5), then the giver's answer runs `lose901` | M1: bit 6 stays, giver "ok901": stuck. With G1: redoable after the time limit; after the women died they are gone (`Region9Init`) | G1, G6 |
| 902 Rache an Reichem Händler | never | boss Res:17049 one-time (`Region9Init`, death `tot902`: bit 2) | G3 |
| 903 Robin Hood | never | Res:17045 is beaten and healed (`re903`), the choice can be made again after M2 | ok |
| 1001 Übergriffe auf die Bevölkerung | never | boss Res:17041 one-time (`Region10Init`, drops the proof) | G3 |
| 1002 Spionage | seen by the spy's group (tag 0x60 `lose1002` on the NPCs from `QIS_OnEnter1002`: bit 4, `LoseQuest`) | M1: giver sets bit 5, "ok" forever: stuck. With G1 redoable; the old group (now hostile) stays next to the new one | G1, G4 |
| 1003 Schlägertypen | the giver Res:17034 dies (`verreckt1003`); seven villagers die (bit 4), then the giver's answer runs `lose1003` | giver death -> M2. Villagers -> M1: bit 5, "ok" forever: stuck. With G1 redoable (the attackers come from the accept trigger again) | G1 |
| 1101 Sektenpriester opfern Jungfrauen | the virgin Res:17112 dies (`Verloren1101` -> `lose11a1`); time limit (`Zeitum1101`: demon instead of the virgin, bit 3) | death -> M1: giver sets bit 5, "ok": stuck; with G1 redoable (all from `QIS_OnEnter1101`, old priests stay). Time limit: vanilla never ends the quest (the giver's bit 3 branch has no `LoseQuest`): running forever | G1, V1 |
| 1102 Kompromittierende Situatuion | time limit (`Zeitum1102`: bit 3, `LoseQuest`) | M1: bit 1 stays, giver "Ok1102": stuck; with G1 redoable (the lady and the letter come from `QIS_OnEnter1102`). After the time limit the lady's bit 3 answer kills the giver (`SetHP 0`); the quest is no longer running then, so M2 does not respawn him | G1, G10 |
| 1103 Verhandelnder Räuber | never | the robber Res:17118 is beaten and healed (`tot1103`) | ok |
| 1111 DeModreys Steuerpresser | the escorted Res:17121 dies (`lose1111` -> `geld1111`: bit 5, `LoseQuest`) | M1: giver sets bit 6, "ok": stuck. With G1: the boss Res:17123 is one-time (`Region111Init`) and `geld1111` deleted his proof Res:6051: cannot be finished | G1, G6 |
| 1112 Animagus terrorisiert Bauernhof | the spared Animagus Res:17127 dies (`ex1112` with bit 4: `LoseQuest`) | M1: bit 4 stays, the giver's answer then runs `postchange1112` (turns the giver hostile) instead of an offer. With G1: the Animagus is one-time (`Region111Init`). `postchange1112` turns the giver hostile by `SetNPCState` (M3 after a load: G8) | G1, G6, G8 |
| 1113 Elfischer Kunstraub | never | thief Res:17129 and the goal object Res:6052 one-time (`Region111Init`) | G3 |
| 1201 Sekte beschwört kleine Dämonen | never | cult one-time (`Region13Init`, group dead: bit 2) | G3 |
| 1202 Heilmittel für Händler | time limit (`zeit1202` kills the patient Res:17163, `LoseQuest`) | M1: giver sets bit 5, "ok": stuck. With G1 the patient (`Region13Init`) is dead: cannot be finished. Vanilla: quest 602's `ok1_602` / `ritterweg_602` walk away and delete `res:17163` too (the same id): finishing 602 removes 1202's patient | G1, G6, V2 |
| 1203 Der Richter und sein Henker | never | judge Res:17166 and executioner Res:17167 one-time (`Region13Init`) | G3 |
| 1301 Entlaufener Gladiatoren-Minotaurus | never | the giver's death label is the quest's end (`exit1301`): `attack1301` turns him hostile (M2 lets it run since 7ec0fa2), the quest ends at once (no M3). Minotaur from `QIS_OnEnter1301` | ok |
| 1302 Das Soldaten-Tunier | timer → `lose1302` | after M1 bits 4/5 and `1302a` stay (G1); opponent Res:17173 is deleted by `attacke1302_1` and created only by region init (G6). Vanilla typos: `DelNPC res17173`/`res17174` (no colon), `attacke1302_2` attacks 17174 | G1 + G6 |
| 1303 Händler - legaler Warentransport | timer → `lose1303` | after M1 bits 3/4 stay (G1); re-accept creates recipient Res:17177 again (G4) | G1 + G4 |
| 1401 Händler - Warenschmuggel | the side chosen dies (`lose1401`) | after M1 bits 1-6 and `1401a`/`1401b` stay (G1); re-accept creates Res:17180/17181 again (G4). Vanilla: soldier's death label `attack1401` doesn't exist (`attacke1401`) | G1 + G4 |
| 1402 Junge Dame vor Übergriffen eines Offiziers schützen | never | officer and soldiers from `QIS_OnEnter1402` | ok |
| 1403 Eskortiere Händler zu geheimen Treffen | recipient after the escorted giver died (`losequest1403`) | giver death is caught by M2 first (restart, giver back); re-accept creates recipient Res:17187 again (G4). Vanilla typo `ok1024` | G4 |
| 1404 Eskortiere Dame zu Treffen mit Geliebten | the lady dies (`lose1404`) | after M1 bits 1/4 stay (G1); lady Res:17189 and boss Res:17190 are one-time (region init), dead lady makes a restart pointless (G6) | G1 + G6 |
| 1405 Sekte von Dämonenanbetern | never | sect leader Res:17195, cultists and the three captives are one-time (region init); M2 reset after the leader died loses the progress | G3 |
| 1501 Menschlicher Wilderer | never | the giver follows; vanilla his death (`ex1501`) lets the quest go on, M2 restarts it and brings him back instead. Re-accept creates the poachers again (G4) | M2 changes vanilla + G4 |
| 1502 Hetzjagd | a label deletes the giver Res:17015, then `losequest1502` | the giver is spawned once by trigger area `hetz1_1502` (deleted after use); after M1 the book points at a deleted giver and nothing spawns him again (G6). Vanilla: his death label `lose1502` doesn't exist | G6 |
| 1503 Arak-Attack | never | spiders and the target from `QIS_OnEnter1503` | ok |
| 1601 Kunstraub | never | thief from `QIS_OnEnter1601` | ok |
| 1602 Attentäter abfangen | the target dies (`target1602`) | after M1 bit 4 stays (G1); target Res:17205 and assassin Res:17201 are one-time (region init), the target is dead (G6) | G1 + G6 |
| 1603 Blockadebrecher | never | | ok |
| 1701 Getrennte Liebende | the lover dies (`lose1701`); afterwards the giver turns hostile and fails it again (`ende1701`) | after M1 bit 6 stays, the giver's dialog runs `ende1701` (G1); lover Res:17209 one-time (G6); `ende1701` makes the giver hostile by `SetNPCState 08 12`, M1 then points at an enemy (G8) | G1 + G6 + G8 |
| 1702 Korruption | never | official Res:17215 one-time (region init) | G3 |
| 1703 Unschuldiger am Galgen | judge after the time-out (`lose1703`) | after M1 bits 6/7 stay (G1); victim Res:17218 and boss Res:17221 are deleted by `zeit1703`, the victim is one-time (G6). `lose1703` kills the giver by `SetHP 0` on purpose; M2 skips his death label `less1703` and brings him back | G1 + G6, M2 changes vanilla |
| 1801 Monströsere Wilderer | never | poachers one-time (region init) | G3 |
| 1802 Dunkle Priester beschwören Dämon | never | priests from `QIS_OnEnter1802` | ok |
| 1803 Dunkelelfengift | time-out (`zeitum1803`) | after M1 bit 4 stays, the giver's dialog runs `losequest1803` again (G1); boss Res:17229 one-time (region init), once killed the poison can't drop again (G6) | G1 + G6 |
| 1901 Rache an bösem Anführer in Dungeon | never | boss Res:17232 one-time (region init) | G3 |
| 1902 Monster haben Item verschleppt in Dungeon | never | monster Res:17020 one-time (region init) | G3 |
| 1903 Entlaufene 'Tochter' | the girl dies (`lose1903`) | after M1 bit 5 stays, the giver's dialog morphs him into the monster at once (G1); girl Res:17237 one-time (G6) | G1 + G6 |
| 2001 Untote Kühe auf Wiesen | never | boss Res:17239 spawns on the 4th trigger area; `2001a` starts at 1 from the start script, a reset to 0 matches no branch of `move2001` and the boss never comes (G1 start-script variable); trigger bits in `2001` | G3 (start-script variable) |
| 2002 Kämpfe gegen Wilde Monster | never | repeatable arena, waves from `monster2_2002` | ok |
| 2003 Anführer der Dämonensekte | never | the giver is the cult leader: `QIS_OnEnter2003` makes him hostile by `SetNPCState 08 12` (G8, M3 would restart). His death runs (hostile, 7ec0fa2). Vanilla typo `res:174242` | G8 |
| 2101 Hands of my Dragon | never | chain with 2102/2103 (and 2303's egg) on dragon Res:17245 (one-time); prince Res:17246 and his guards from `QIS_OnEnter2101`. Shared variables `riesendiamant`/`drachenei` are written by several of these quests (G9 if one is restarted) | ok |
| 2102 Drache - Zahnstocher | never | prince is the giver; boss Res:17249 from `QIS_OnEnter2102` | ok |
| 2103 Return for Refill | never | knights created one after the other by `ziel2103` | ok |
| 2201 Kuss der Spinnefrau | the girl dies (`lose2201`) | after M1 bits stay (G1); girl Res:17283 one-time (G6); `postchange2201` turns the giver Res:17281 hostile by `SetNPCState 08 12` (G8) | G1 + G6 + G8 |
| 2202 Narzisstische Zauberin | never | `change2202` turns the giver Res:17255 hostile by `SetNPCState 08 12` (G8) | G8 |
| 2203 Hinterhältiger Giftmischer | never | poisoner Res:17260 and the six barrels (counter `2303a`) are one-time (region init) | G3 |
| 2301 Besorge Reagentium | never | bush is a fixed MouseEvent, item re-created in OnEnter | ok |
| 2302 Larbortiere | never | the four monsters are one-time (region init), counted in `2302b` | G3 |
| 2401 Botschaft für Scouts | never | chain 2401-2404 on giver Res:17268 (his death label `mann2404` belongs to 2404); scouts one-time (region init), moved/morphed by the quest | G3 |
| 2402 Verlaufene Sielder finden | the settler dies after joining (`losequest2402`) | the failure continues the chain (`SetUpQuest 2403`, giver's dialog set to 2403); M1 restarting 2402 is wrong (G11) | G11 |
| 2403 Verschleppte Sielder befreien | all settlers die (`losequest2403`) | like 2402: the failure continues the chain with 2404 (G11) | G11 |
| 2404 Verteidige Lager | never | vanilla the giver's death (`mann2404`) hands the reward to Res:17280; M2 restarts and brings him back instead | M2 changes vanilla |
| 2411 Das Orkische Relikt | never | relic from `QIS_OnEnter2411` | ok |
| 2412 Der Feige Hund | never | dog Res:17584 one-time (region init) | G3 |
| 2413 Kleine Wuselorks | never | all from `QIS_OnEnter2413` | ok |
| 2501 Finde Drachnschuppe für Rüstung | never | dragon Res:17292 one-time (region init); counts towards `finale` | G3 |
| 2502 Eierdieb | the time-out, reported to the giver (`losequest2502`) | the failure counts towards the region's `finale` (bit 2 + `finalestart`) like a success (G11); after M1 bits 4/5 stay (G1) | G11 |
| 2503 Drachentöter vertreiben | never | dragon slayers one-time (region init) | G3 |
| 2504 Rette Jungfrau | the maiden (= giver) dies (`lose2504`) | M2 catches her death first: restart and respawn instead of failure + `finale` bit; redoable | M2 changes vanilla |
| 9003 Versteckter Händler | `rg3_goodie1_lose` (merchant's death) | progress lives in the shared variable `goodies` (8 quests), M1/M2 can't reset it (G1 + G9): after M1 bit 1 stays and the dialog offers the reward branch (`ExitQuest`) without the quest running | G1 + G9 |
| 9004 Vermisstes Kind | `rg1_goodie_lose` (child's death) | `goodies` bit 4 stays, the giver only answers "ok" (G1 + G9); child Res:17513 one-time (G6) | G1 + G6 + G9 |
| 9005 Der Waldläufer | never | | ok |
| 9006 Der unbekannte Krieger | never | progress in shared `goodies` | ok |
| 9007 Jacquaire's Waffen | never | guards from `QIS_OnEnter9007` | ok |
| 9008 Furchtbares Verbrechen | escorted giver Res:17539 dies (`losequest9008`) | M2 catches the death (restart, respawn); `QIS_OnEnter9008` sets the trigger area again | M2 changes vanilla |
| 9009 Whiskeylieferung | never | | ok |
| 9010 Vergrabene Sklaven | escorted giver Res:17575 dies (`lose9010`) | M2 restarts; but `9010` is a counter (0 = offer, needs key Res:17580 in the inventory), M2's reset to 1 shows the "follow" branch, and `QIS_OnEnter9010` deleted the key, so it can't be accepted again (G6) | G6 |
| 9011 Jacquaires Vergangenheit | never | boss and target from `QIS_OnEnter9011` | ok |
| main quests 1-81, 670 | never | started by trigger areas (`SelfTriggerQuest<N>`), no giver, so M1-M3 don't touch them; 31's giver is only set by `SetNPCState` (not in `g_givers`) | ok |
| 65 Trockenlegung durch Zwergenstaudamm (main) | never | giver Res:18306 (Torfstecher, start script) is in `g_givers`. Vanilla his death leaves 65 unfinishable (61 is activated by `Exit65`); M2 brings him back, but resets `65` incl. bit 5 (pump switched by `SwitchPump65`); if the pump can't be used twice the quest is stuck (G3). Re-accept creates the rune Res:17569 again (G4) | G3 + G4 |
| 210 Verschleppte Novizinnen in Räuberöhle | never | boss Res:17083 one-time (start script) | G3 |
| 9000 Das Untotenlager | the shaman's drop is picked up while the quest runs | refusing makes the giver Res:17500 attackable by `SetNPCState 08 14` (not Morph, G8); killing him drops the item whose label opens the Khorad Nur gate (`ablehnensieg_goodie_wueste`). If M2 sees him as not hostile it skips `drop_goodie_wueste`: **no item, the gate (main quest 55's way) never opens**. Check `IsHostileTo` for `08 14` | G8, critical |
| 5003 Opferritual | the hero refuses at the end (`nein5003`) | a story choice: the shaman Res:17699 and his tribe turn hostile (`SetNPCState 08 12`) and the quest fails. M1 restarts it with bit 6 kept, so the (now hostile) shaman would offer the choice again (G11 + G8) | G8 + G11 |
| 5005 Pony Express | a time limit runs out (`losepe`) | `losepe` deletes the giver Res:17753 (spawned once by main quest label `NachOrkland55`) and all stations; after M1 the book points at nobody and the quest can't be taken again (G5/G6); `5005c` stays (G1) | G1 + G5 |
| 6001 Die Invasion der Eiselfen | all elves of the camp die (`od_welfen6001`) | after M1 bits stay (G1); the elves (incl. giver Res:17706) are one-time, dead (G6); re-accept creates the invaders again (G4). Accept label starts with `SetNPCState`, so the giver isn't in `g_givers` (no M2/M3) | G1 + G4 + G6 |
| 6002 Das Orklager | never | | ok |
| 6003 Elfenbeschützer | the escorted elf Res:17750 dies (`lose6003`) | after M1 bit 3 stays (G1); the elf is one-time (G6); her dialog is set by `SetNPCState`, so she is probably not in `g_givers` (no M2) | G1 + G6 |
| 2600-3599 generic quests (16 templates × 22 regions) | `DQ_RG<n>_..._LOSE_<id>` (and `_ABORT_` for escorts) | no giver (runtime-assigned NPC), so no M2/M3; M1 restarts them although `Quest_End` already copies them (G2) | G2 |
### Underworld (`bin\Addon\NetScriptCamp`)
Underworld quests keep their state in the NPCs' dialogs (`SetNPCState ...
dialog"dlg_<npc>_<id>_<step>"`), rarely in variables, and most givers are
spawned by `QIS_OnSetUp<id>` (run from the start script) without a dialog.
| Quest | Fails when | Finding | Class |
|---|---|---|---|
| 7612 Eskorte | escorted Nanoduk Res:19547 dies (`od_nanoduk`) | he is the giver and one-time (`QIS_OnSetUp7612`); after M1 nobody offers the quest (G6) | G6 |
| 7614 Vermisstes Kind (Underworld) | the child Res:19549 dies (`od_erdriac`) | the giver's dialog is set to the "child is dead" step `_d` (only "ok"); M1 doesn't restore the accept dialog `_a`, so it can't be taken again (G12). The child comes from `QIS_OnEnter7614` | G12 |
| 7617 Eskorte in den Süden | escorted giver Res:19586 dies (`od_7617`) | he is spawned with his accept dialog, so M2 catches his death: restart and respawn | M2 changes vanilla |
| 7619 Tod den Toten | the giver Res:19545 dies (`od_threepwood_7619`) | his accept dialog is only set by `SetNPCState` in `QIS_OnSetUp7619` (not in `g_givers`); after M1 he is dead (G6) | G6 |
| 9518 Unter der Herrschaft von Dämonen | the mother Res:19530 dies while following (`od_lose9518`) | after M1 bits 1/2/4 stay, the giver only answers "ok" (G1); re-accept creates mother and demons again (G4) | G1 + G4 |
| 9520 Cookies Quest | the hero gives the cookies to Von Endlich, then the girl ends it (`btn_FinishLose9520`, gold for experience) | a story choice (G11); after M1 bit 4 stays, so the girl offers `btn_FinishLose9520` again and again (repeatable gold-for-experience trade) | G11 |
| 10254 Der Hilferuf | the giver dies (`od_Auftraggeber_10254`) | the giver is spawned once when the letter is picked up (`ot_Brief_10254`); after M1 he's dead and the letter gone (G6). The 10250-10261 givers have named ids (`res:AUFTRAGGEBER_10254`, after the type argument), which `InstructionScriptId` doesn't read: none of them is in `g_givers` (G13) | G6 + G13 |
| 10255 Panik vor Spinnen | never (its "lose" is a label name; the giver offers a restart himself) | | ok |
| 10260 Das Rätsel in der Wüßte | the wrong chest is opened (`fillchest_chestQJ_0x`) | the giver's dialog is removed (`0a#0`); after M1 nobody offers it (G12) | G12 |
| other Underworld quests (main 11-56, 7600-7630, 9511-9522, 9900, 11101-11110, 15001-15084) | never | main quests have no giver (untouched). Side quests: givers spawned with their accept dialog in `QIS_OnSetUp<id>` are in `g_givers` (7600, 7601, 7605, 7609, 7614, 7617, 7618, 7620, 7622-7624, 7626, 7630, 9511, 9513, 9515, 9518, 9520, 9521); a chain's later quests on the same giver (dialog by `SetNPCState`) are not. Their targets also come from `QIS_OnSetUp` (one-time), so M2 after a target died loses progress only where variables hold it (G3, rare here); named ids (`res:Sam1_Knappe`, `res:AUFTRAGGEBER_…`) are skipped (G13) | ok / G3 |
## Summary and proposed fixes
Counted over the side quests (Ancaria 151-2504, 9003-9011, 210, 65, the
5003-6003 set and the Underworld quests that can fail): about a third are
fine, the rest fall into the classes above. In order of impact:
1. **G8 critical, 9000** (Khorad Nur gate): verify by a log whether a creature
set by `SetNPCState ... 08 14` is hostile to the hero (`IsHostileTo`). If
not, M2 skips the shaman's death label and the gate never opens. Fix
either way: treat a giver as "turned" when any of its quest's labels set
`08 12`/`08 14` on it (extends `ScanGiverTurns` beyond Morph); that also
fixes M3 for 1112, 1301, 1701, 2003, 2201, 2202, 501, 5003.
2. **G1 reset on failure:** M1 resets the quest's own variables like M2
(including the ones only start/region scripts initialise, with their
initial values, e.g. 302a, 2001a = 1). Fixes most "giver only says ok"
cases (152, 702, 703, 1002, 1003, 1302, 1303, 1401, 1404, 1602, 1803,
1903, 9518, ...).
3. **G11 failures that are part of a story or chain** (2402, 2403, 2502,
5003, 9520): M1 must not restart a quest whose failure label also calls
`SetUpQuest`/`finalestart`, or sets the giver hostile.
4. **G2 generic quests:** M1 leaves 2600-3599 (and their runtime copies) to
the game.
5. **G6 restart without NPCs / G3 lost progress:** the bigger design
question. Options: (a) on restart, respawn the quest's one-time NPCs from
their spawn instructions in start/region scripts (like the giver), (b) keep
the variables on M2/M3 (no progress loss, but the giver may answer with a
running branch), (c) don't restart quests whose needed NPCs are gone and
leave them failed. Recommendation: (a) for NPCs the quest's dialogs or
death labels name, else (c).
6. **G4 duplicates:** before re-running `QIS_OnEnter`, delete the quest's
still-alive named NPCs/objects it is about to create.
7. **G5/G7** (154, 301, 1502, 5005): M3 skips quests whose labels `DelNPC`
their giver; M1 skips quests without a giver.
8. **G9/G12/G13** (803, 9003/9004 `goodies`, 7614, 10260, named ids): lower
priority; G12 needs the accept dialog put back (it is in the giver's spawn
instruction or `QIS_OnSetUp`).
## Fixes (2026-10-30)
Request: "all, but leave 1, as i cant play for now" (2-8 above; G8 waits for a
measurement in the game). Not yet tested in the game.
- `mods/questscript.cpp` (new) reads the script code once and keeps, per
quest: the giver (spawned with the accept dialog, else given it by an NPC
state instruction: the Underworld's `QIS_OnSetUp<id>`), its variables (set
only by its labels, plus the one named after it: G9), what `QIS_OnEnter<id>`
creates, the NPCs it needs (its labels set their state, don't create them),
whether it morphs or deletes its giver, and the failure labels that end its
story (`LoseQuest` with `SetUpQuest`/`ActivateQuest`, experience or gold, a
call into another quest's label, or an NPC offering the quest turned hostile
or set to 0 hit points: 1701 `ende1701`, 1703, 2402, 2403, 2502, 2504, 5003,
9520). It also keeps the labels running (for `Quest_End`) and spawns NPCs
once their bodies are gone.
- `questfail.cpp`: at `Quest_Trigger` (first time) the quest's variables are
kept ("questVariables" with the hero). A failed quest stays failed when it
is a generic quest or a copy (G2), has no giver (G7), its failure ends the
story (G11) or its giver / an NPC it needs is gone without a spawn
instruction (G5/G6). Else the restart also: resets its variables to the kept
values (G1; without them: 1 for the one named after the quest, 0 else),
deletes what `QIS_OnEnter` created (G4), spawns dead needed NPCs and the giver
again (G6, from region start labels, another quest's label or
`QIS_OnSetUp`), and gives a living giver the accept dialog again (G12).
After a load, failed quests restarted earlier get their variables reset
(repairs saves stuck by G1).
- `questgiver.cpp` uses the same scan; the load repair skips quests that
delete their giver (G5); the giver comes back through `questfail::Restart`.
- Not done: G8 (fix 1), G3 for progress held in one-time objects (2203's
barrels), G10, G13 (named ids such as `res:AUFTRAGGEBER_10254`: the game's
name table is unknown, those givers can't be checked or respawned).