docs: record the Slice 0.9 quest system and its deviations
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1354,13 +1354,22 @@ Erster NPC: **Borin, Quartermaster** an `south-gate` (Graufurt) mit
|
||||
DIALOGUE + MERCHANT + RESOURCE_EXCHANGE gleichzeitig — der Kompositionsfall
|
||||
aus §2/§26 in echt.
|
||||
|
||||
## Abweichung 1 — kein `NpcQuestAssignment`
|
||||
## Abweichung 1 — kein `NpcQuestAssignment` — **aufgelöst in Slice 0.9**
|
||||
|
||||
§34 listet es im V1-Scope, aber es gibt noch kein Questsystem (Slice 0.9).
|
||||
§34 listet es im V1-Scope, aber es gab in Slice 0.8 noch kein Questsystem.
|
||||
Eine Tabelle mit Fremdschlüssel auf eine nicht existierende `quests`-Tabelle
|
||||
ist nicht baubar, und ein `questKey`-String ohne Validierung wäre spekulative
|
||||
Architektur (AGENTS §1.7). Nachzuholen mit Slice 0.9, zusammen mit den
|
||||
Dialog-Actions `START_QUEST` / `COMPLETE_QUEST`.
|
||||
Architektur (AGENTS §1.7).
|
||||
|
||||
Slice 0.9 hat das nachgeholt: `NpcQuestAssignment` liegt unter
|
||||
`apps/api/src/quests/entities/npc-quest-assignment.entity.ts` und trägt die
|
||||
Rollen `OFFER` / `TURN_IN` / `PROGRESS` aus §14. Der Unique-Index umfasst die
|
||||
Rolle mit, damit derselbe NPC eine Quest sowohl vergeben als auch annehmen
|
||||
kann — genau der Fall aus §14, den die erste Questkette benutzt: der South
|
||||
Gate Warden vergibt und nimmt an, Borin steht als `PROGRESS` dazwischen.
|
||||
|
||||
Die Dialog-Actions `START_QUEST` / `COMPLETE_QUEST` bleiben offen, siehe
|
||||
Abweichung 4.
|
||||
|
||||
## Abweichung 2 — kein `NpcDialogueProfile`
|
||||
|
||||
@@ -1372,14 +1381,52 @@ neu zu schreiben.
|
||||
|
||||
## Abweichung 3 — Conditions, die (noch) nichts beantworten kann
|
||||
|
||||
`GameConditionType` enthält die vollständige V1-Liste aus §19, aber nur
|
||||
`REGION_REPUTATION`, `WORLD_RENOWN`, `FLAG_SET` und `HAS_ITEM` sind
|
||||
auswertbar. `QUEST_ACTIVE`, `QUEST_COMPLETED`, `BOSS_DEFEATED` und
|
||||
`LOCATION_DISCOVERED` haben noch kein System dahinter.
|
||||
`GameConditionType` enthält die vollständige V1-Liste aus §19, aber nicht jeder
|
||||
Typ hat ein System dahinter.
|
||||
|
||||
Sie werten **fail-closed** aus, also immer "nicht erfüllt". Für ein Gate ist
|
||||
die sichere Richtung eines Fehlers zu, nicht offen — ein Quest-Gate darf
|
||||
niemals aufgehen, nur weil es keine Quests gibt.
|
||||
Seit Slice 0.9 auswertbar: `REGION_REPUTATION`, `WORLD_RENOWN`, `FLAG_SET`,
|
||||
`HAS_ITEM`, `QUEST_ACTIVE`, `QUEST_COMPLETED`. Offen bleiben `BOSS_DEFEATED`
|
||||
(Slice 0.11) und `LOCATION_DISCOVERED` (wird pro Charakter nicht getrackt).
|
||||
|
||||
Die beiden Quest-Typen werten boolesch aus wie `FLAG_SET`, nicht numerisch:
|
||||
eine Quest läuft oder nicht, `actual` bleibt `null`. `value: false` ist die Art,
|
||||
wie Content die Verneinung ausdrückt — die Angebotszeile des Wardens braucht
|
||||
"noch nicht begonnen und noch nicht abgeschlossen", ohne dass die
|
||||
Condition-Sprache ein NOT bekommt.
|
||||
|
||||
Die verbleibenden Typen werten **fail-closed** aus, also immer "nicht erfüllt".
|
||||
Für ein Gate ist die sichere Richtung eines Fehlers zu, nicht offen.
|
||||
|
||||
## Abweichung 4 — Questschritte laufen nicht über Dialog-Actions
|
||||
|
||||
`DialogueActionType` enthält `START_QUEST` und `COMPLETE_QUEST`, aber beide
|
||||
bleiben auch mit dem Questsystem aus Slice 0.9 wirkungslos.
|
||||
|
||||
Sie auszuführen bräuchte zwei Dinge, die es nicht gibt: einen Endpoint, über
|
||||
den der Client eine Dialog-Response *auswählt*, und einen Action-Executor
|
||||
dahinter. Playable Slice 0.9 §10 verlangt ausdrücklich einen
|
||||
schrittbasierten Questautomaten und verbietet eine verzweigende
|
||||
Narrative-Engine — und ein Response-Endpoint plus Executor wäre genau deren
|
||||
Anfang, für eine Kette mit fünf Schritten.
|
||||
|
||||
Stattdessen:
|
||||
|
||||
```text
|
||||
POST /api/npcs/:npcKey/quests/:questKey/accept
|
||||
POST /api/npcs/:npcKey/quests/:questKey/advance
|
||||
```
|
||||
|
||||
Keine der beiden Routen nimmt einen Body. Welcher Schritt gerade dran ist, was
|
||||
er vergibt und was er verbraucht, entscheidet der Server (AGENTS §5). Der Satz,
|
||||
den der NPC zu einem Schritt sagt, ist Content auf dem `QuestObjective`
|
||||
(`npc_line`) und kommt mit der Antwort zurück.
|
||||
|
||||
Nachzuholen wäre das, sobald ein NPC wirklich verzweigende Antworten braucht:
|
||||
dann ein Response-Auswahl-Endpoint, ein Executor über
|
||||
`SUPPORTED_DIALOGUE_ACTIONS`, und die Questschritte können auf Dialog-Actions
|
||||
umziehen, ohne dass die Questtabellen sich ändern.
|
||||
|
||||
---
|
||||
|
||||
## Offene Designfrage — World Renown im Tausch
|
||||
|
||||
@@ -1398,3 +1445,40 @@ anzufassen.
|
||||
|
||||
Falls Renown später doch als Punktwährung gedacht ist, muss das zuerst in
|
||||
0.6.5 geändert werden — nicht hier.
|
||||
|
||||
---
|
||||
|
||||
# 41. Implementierungsstand (Slice 0.9)
|
||||
|
||||
```text
|
||||
QuestDefinition / QuestObjective apps/api/src/quests/entities/
|
||||
NpcQuestAssignment Rollen aus §14
|
||||
CharacterQuest Player-State, ein Row pro Charakter/Quest
|
||||
QuestProgressService leitet den aktiven Schritt ab (lesend)
|
||||
QuestService accept / advance, Effekte, Belohnungen
|
||||
QuestController / NpcQuestController apps/api/src/quests/quest.controller.ts
|
||||
```
|
||||
|
||||
Erste Questkette: **Trouble Beyond the Gate**, vergeben und angenommen von
|
||||
Halvik am Südtor, mit Borin als Zwischenschritt — der Mehr-NPC-Fall aus §14
|
||||
in echt.
|
||||
|
||||
Zwei Module statt einem: `QuestProgressModule` enthält nur den lesenden Teil,
|
||||
weil `NpcService` Questmarker braucht und `QuestService` umgekehrt `NpcService`
|
||||
für die Erreichbarkeitsprüfung. Der Schnitt hält den Modulgraphen zyklenfrei,
|
||||
ohne `forwardRef`.
|
||||
|
||||
Es gibt bewusst **keine** Tabelle für Objective-Fortschritt. Slice 0.9 §11
|
||||
verlangt, dass Sammelschritte ihren Stand aus dem aktuellen Besitz ableiten;
|
||||
genau das macht `QuestProgressService`, und dadurch fallen die Softlock-Fälle
|
||||
aus §11 von selbst weg, statt einzeln behandelt zu werden.
|
||||
|
||||
Was ein Schritt *tut*, steht als Content auf dem `QuestObjective`
|
||||
(`sets_flag_key` / `sets_flag_npc_key`, `grants_loot_bag_key`,
|
||||
`consume_on_complete`, `advance_when_blocked`). `QuestService` wendet an, was
|
||||
es vorfindet, und verzweigt nirgends auf einen Questkey (AGENTS §9).
|
||||
|
||||
Markerregeln für die Ortsansicht (§24, Slice 0.9 §12): höchstens ein
|
||||
Questmarker pro NPC, Reihenfolge `QUEST_TURN_IN` > `QUEST_AVAILABLE` >
|
||||
`QUEST_IN_PROGRESS`. Halvik hält für dieselbe Quest zwei Rollen; ohne
|
||||
Vorrangregel trüge er zwei Symbole und keines würde etwas aussagen.
|
||||
|
||||
Reference in New Issue
Block a user