10 KiB
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:
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:
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:
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:
referred-by-south-gate-warden
New objective:
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
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
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:
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:
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:
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:
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