407 lines
10 KiB
Markdown
407 lines
10 KiB
Markdown
# Ashen Realms – Playable Slice 0.9
|
||
|
||
## First Quest & Loot-Bag Tutorial
|
||
|
||
**Status:** Implementation Specification
|
||
**Depends on:** Slice 0.8.5
|
||
**Purpose:** Introduce quests, NPC-directed progression, bag capacity and the merchant loop through one small coherent tutorial chain.
|
||
|
||
---
|
||
|
||
## 1. Goal
|
||
|
||
This slice should teach several systems without a conventional tutorial popup sequence.
|
||
|
||
The player learns naturally that:
|
||
|
||
- NPCs provide direction
|
||
- monster goods must be carried
|
||
- carrying capacity matters
|
||
- merchants can help
|
||
- reputation affects relationships/offers
|
||
- hunting goods can later be exchanged for progression
|
||
|
||
The quest should feel like world interaction, not a checklist tutorial.
|
||
|
||
---
|
||
|
||
## 2. Quest Concept
|
||
|
||
Working quest title:
|
||
|
||
**Trouble Beyond the Gate**
|
||
|
||
Quest-giver:
|
||
|
||
**South Gate Warden**
|
||
|
||
Use an existing named gate NPC if one has already been implemented. Do not create a duplicate NPC merely because this document uses a generic title.
|
||
|
||
Merchant:
|
||
|
||
**Borin, Quartermaster** or the existing Graufurt merchant.
|
||
|
||
---
|
||
|
||
## 3. Narrative Flow
|
||
|
||
### Step 1 – Speak with the South Gate Warden
|
||
|
||
The warden is concerned about increasingly aggressive scavengers and raiders beyond the gate.
|
||
|
||
Player-facing English example:
|
||
|
||
> "The road has gone bad. Start small. Bring me five Ashen Pelts from the rats beyond the gate. I want to know what the ash is doing to them."
|
||
|
||
Objective:
|
||
|
||
```text
|
||
Collect 5 Ashen Pelts
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Capacity Problem
|
||
|
||
The player currently has no Hide Bag.
|
||
|
||
Default HIDE capacity is 1.
|
||
|
||
After collecting the first Ashen Pelt:
|
||
|
||
```text
|
||
Ashen Pelts 1 / 1
|
||
Hide capacity reached.
|
||
```
|
||
|
||
The quest remains at `1 / 5`.
|
||
|
||
The game should now provide a clear next action rather than leaving the player confused.
|
||
|
||
Suggested quest update:
|
||
|
||
```text
|
||
You cannot carry enough pelts. Return to the South Gate Warden.
|
||
```
|
||
|
||
Do not secretly increase capacity for the quest.
|
||
|
||
---
|
||
|
||
## 5. Referral to the Merchant
|
||
|
||
On returning, the warden acknowledges the problem and refers the player to Borin.
|
||
|
||
Example:
|
||
|
||
> "Right. You're not equipped for hauling spoils yet. Go see Borin in Graufurt. Tell him I sent you. He'll complain, but he'll give you something useful."
|
||
|
||
Set a persisted unlock/referral flag, for example:
|
||
|
||
```text
|
||
referred-by-south-gate-warden
|
||
```
|
||
|
||
New objective:
|
||
|
||
```text
|
||
Speak with Borin in Graufurt
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Merchant Interaction
|
||
|
||
Borin normally would not provide the bag at the player's current reputation.
|
||
|
||
His dialogue should make the relationship system visible.
|
||
|
||
Example:
|
||
|
||
> "I don't know you, and I don't hand out gear to every wanderer who walks in here."
|
||
|
||
Then after recognizing the referral:
|
||
|
||
> "But the South Gate Warden sent you. Fine. Take this. Bring it back full and make it worth my trouble."
|
||
|
||
Grant:
|
||
|
||
**Basic Hide Bag**
|
||
|
||
```text
|
||
Category: HIDE
|
||
Capacity: 5
|
||
```
|
||
|
||
The grant uses the referral exception built in Slice 0.8.5: the Basic Hide Bag
|
||
offer (`BORIN_OFFER_IDS.hideBag`) carries
|
||
|
||
```text
|
||
bypassConditions: [{ type: FLAG_SET, key: 'referred-by-south-gate-warden' }]
|
||
```
|
||
|
||
so setting that flag on the character's Borin state opens the offer without
|
||
changing any reputation. The offer's own gate stays at Border Watch
|
||
Reputation 40.
|
||
|
||
---
|
||
|
||
## 7. Continue the Hunt
|
||
|
||
The player can now carry five HIDE-category goods.
|
||
|
||
Objective returns to:
|
||
|
||
```text
|
||
Collect 5 Ashen Pelts
|
||
```
|
||
|
||
Important:
|
||
|
||
- an already-owned first pelt still counts
|
||
- the player should need four more, not five more
|
||
- the bag capacity view changes immediately to `1 / 5`
|
||
|
||
---
|
||
|
||
## 8. Quest Turn-In
|
||
|
||
The player returns to the South Gate Warden with five Ashen Pelts.
|
||
|
||
The quest consumes the required five pelts.
|
||
|
||
The warden explains the normal long-term loop:
|
||
|
||
> "Good. That's enough for me. From now on, take hides and trophies to Borin. He'll pay for useful spoils, and word gets around when you keep the roads clear."
|
||
|
||
This line connects:
|
||
|
||
- monster loot
|
||
- merchant exchange
|
||
- Silver
|
||
- regional reputation
|
||
- World Renown
|
||
|
||
without needing a separate tutorial screen.
|
||
|
||
---
|
||
|
||
## 9. Quest Rewards
|
||
|
||
The main reward of this quest is the **Basic Hide Bag** and system knowledge.
|
||
|
||
Optional one-time rewards may include:
|
||
|
||
- small regional reputation increase
|
||
- small World Renown milestone increase
|
||
- quest completion flag
|
||
|
||
Avoid a large Silver reward that undermines the merchant trade loop.
|
||
|
||
No XP reward.
|
||
|
||
---
|
||
|
||
## 10. Minimal Quest System Requirements
|
||
|
||
The system must support at least:
|
||
|
||
- quest definition
|
||
- quest acceptance
|
||
- ordered objectives
|
||
- item collection progress
|
||
- NPC interaction objective
|
||
- persisted completion
|
||
- quest flags/unlock flags
|
||
- item consumption on turn-in
|
||
- one-time rewards
|
||
|
||
Do not build a full branching narrative engine.
|
||
|
||
A simple step-based quest state machine is sufficient.
|
||
|
||
---
|
||
|
||
## 11. Quest State Safety
|
||
|
||
The flow must not softlock when:
|
||
|
||
- player already owns one or more Ashen Pelts before accepting
|
||
- player sells/trades pelts while quest is active
|
||
- player disconnects during a quest step
|
||
- bag was already obtained through development data
|
||
- player tries to receive the referral bag twice
|
||
|
||
Define deterministic behavior.
|
||
|
||
Recommended:
|
||
|
||
- objectives derive progress from current owned quantity where appropriate
|
||
- quest item consumption validates quantity at turn-in
|
||
- bag grant is idempotent
|
||
- referral flag persists
|
||
|
||
---
|
||
|
||
## 12. UI Requirements
|
||
|
||
At minimum:
|
||
|
||
### NPC / Local View
|
||
|
||
- quest available marker
|
||
- quest in progress marker
|
||
- quest turn-in marker
|
||
- Talk interaction
|
||
|
||
### Quest UI
|
||
|
||
Show:
|
||
|
||
- title
|
||
- short description
|
||
- current objective
|
||
- progress
|
||
|
||
Example:
|
||
|
||
```text
|
||
Trouble Beyond the Gate
|
||
Collect Ashen Pelts 1 / 5
|
||
|
||
You cannot carry enough pelts. Return to the South Gate Warden.
|
||
```
|
||
|
||
### Bag UI
|
||
|
||
When the bag is granted:
|
||
|
||
```text
|
||
New Loot Bag
|
||
Basic Hide Bag
|
||
Hide Capacity: 5
|
||
```
|
||
|
||
---
|
||
|
||
## 13. Tests
|
||
|
||
- quest can be accepted only once in active state
|
||
- first pelt updates objective to 1/5
|
||
- no bag blocks carrying second HIDE item
|
||
- return step activates correctly
|
||
- referral flag is set
|
||
- merchant grants Basic Hide Bag once
|
||
- capacity becomes 5
|
||
- previously owned pelt remains counted
|
||
- five pelts allow turn-in
|
||
- turn-in consumes five pelts
|
||
- quest completes and cannot reward bag repeatedly
|
||
|
||
---
|
||
|
||
## 14. Acceptance Criteria
|
||
|
||
- [ ] One complete NPC quest chain is playable.
|
||
- [ ] The quest intentionally exposes the default 1-item carrying limit.
|
||
- [ ] The player is directed back instead of softlocked.
|
||
- [ ] A persisted merchant referral is created.
|
||
- [ ] Merchant grants Basic Hide Bag because of the referral.
|
||
- [ ] Hide capacity becomes 5.
|
||
- [ ] Player can collect five Ashen Pelts.
|
||
- [ ] Turn-in consumes the pelts and completes the quest.
|
||
- [ ] NPC explains that future goods should be traded to the merchant.
|
||
- [ ] Quest grants no XP.
|
||
- [ ] All dialogue/UI text is English.
|
||
|
||
### Verification status
|
||
|
||
Every criterion above is covered by automated tests: the quest chain in
|
||
`quest-state.spec.ts` and `quest.service.spec.ts`, the content in
|
||
`vertical-slice.seed.spec.ts`, the markers in `npc.service.spec.ts`, and the
|
||
three UI requirements of §12 in the web specs for the journal, the NPC screen
|
||
and the location hotspots.
|
||
|
||
The boxes stay unticked because two things have not been run: the migration and
|
||
seed against a real PostgreSQL database, and a hand-played pass through the
|
||
chain in the running app. Neither was possible in the environment this slice was
|
||
built in — no database was reachable. Do both before ticking, following the
|
||
walkthrough in the implementation plan
|
||
(`docs/superpowers/plans/2026-08-22-first-quest-and-bag-tutorial.md`, Task 13).
|
||
|
||
---
|
||
|
||
## 15. Implementation Decisions
|
||
|
||
Recorded here rather than only in the implementation plan, so the next slice
|
||
reads them from the specification.
|
||
|
||
### D1 — The Basic Hide Bag is granted, not sold
|
||
|
||
§6 has Borin say "Take this" while also describing the Slice 0.8.5 offer, which
|
||
costs 35 Silver. A player standing at that step has close to none, so the
|
||
purchase path alone would stall the chain.
|
||
|
||
Borin's quest step therefore hands the bag over directly and idempotently. The
|
||
referral flag is still written to the character's Borin state, so the 0.8.5
|
||
`bypassConditions` gate opens the offer as well — a visible consequence, and a
|
||
way back to a bag that is somehow lost. Nothing about reputation changes.
|
||
|
||
### D2 — No World Renown milestone
|
||
|
||
§9 lists one as optional. The demo character sits at Renown 1 and the first
|
||
trade-in takes them to 2; a quest milestone would reach 3 and unlock Borin's
|
||
Bandit Blade, which Slice 0.8.5 deliberately placed out of reach until Slice
|
||
0.11. The quest pays regional reputation instead: **+10 Border Watch**.
|
||
|
||
### D3 — No Silver reward
|
||
|
||
§9 warns against a Silver reward that undermines the merchant trade loop, and
|
||
names the bag and system knowledge as the point of the chain. `rewardSilver` is
|
||
a content column set to 0, so retuning it later is a seed change.
|
||
|
||
### D4 — Quest steps use their own endpoints
|
||
|
||
NPC spec §40 asked Slice 0.9 to also wire the `START_QUEST` / `COMPLETE_QUEST`
|
||
dialogue actions. There is no dialogue-response endpoint at all, and building
|
||
one plus an action executor is the branching narrative engine §10 rules out.
|
||
|
||
Steps run through `POST /api/npcs/:npcKey/quests/:questKey/{accept,advance}`.
|
||
Neither takes a body — which step is current, what it grants and what it
|
||
consumes are the server's to decide. The line an NPC speaks for a step is
|
||
content on the objective. Recorded as Abweichung 4 in the NPC specification.
|
||
|
||
### D5 — The demo character starts with no loot bag
|
||
|
||
The vertical-slice seed handed over a free Basic Hide Bag as a stopgap between
|
||
Slices 0.8.5 and 0.9, with a note to remove it once a quest could grant one.
|
||
That is done: the bagless HIDE capacity of 1 is the whole premise of §4. The
|
||
migration also clears that one row for the demo character on databases seeded
|
||
before this change.
|
||
|
||
### Addition — a hint for the second pelt hunt
|
||
|
||
Not in the specification, but the same courtesy §4 asks for. The Hide Bag holds
|
||
five of *any* hide, so Tough Hides can crowd out the fifth Ashen Pelt. That step
|
||
must not give up the way the first one does — it is meant to be finished (§7) —
|
||
so it carries a hint instead:
|
||
|
||
```text
|
||
Your hide bag is full of other goods. Trade some to Borin to make room for pelts.
|
||
```
|
||
|
||
---
|
||
|
||
## 16. Out of Scope
|
||
|
||
Do not implement:
|
||
|
||
- branching quest choices
|
||
- voice acting
|
||
- cinematic dialogue
|
||
- daily quests
|
||
- repeatable bounty framework
|
||
- quest sharing
|
||
- party quest progress
|
||
- large quest journal taxonomy
|