Files
ashen-realms/docs/playable-slices/Ashen Realms – Playable Slice 0.6.5_ Renown & Reputation Foundation.md
Bastian Wagner 8a5f57fa1c specs
2026-08-20 16:17:19 +02:00

1618 lines
26 KiB
Markdown
Raw 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.
# Ashen Realms Playable Slice 0.6.5: Renown & Reputation Foundation
**Status:** Ready for implementation
**Prerequisite:** Playable Slice 0.6 Full First Combat
**Scope:** Replace classical XP/Level progression with the foundational Renown, Regional Reputation and trophy-based reward model
**Next Slice:** Updated Playable Slice 0.7 Complete Verbrannte Straße
---
# 1. Goal
Playable Slice 0.6.5 replaces the remaining classical RPG progression assumptions before additional content is built on top of them.
The old model:
```text
kill monster
→ receive XP
→ receive Silver
→ fill XP bar
→ gain Level
```
must no longer be the progression model of Ashen Realms.
The new model is:
```text
hunt
→ fight
→ receive equipment / trade goods / trophies
→ collect loot
→ return to civilization
→ turn in or sell loot
→ gain Silver + Regional Reputation
→ unlock better opportunities
→ complete meaningful milestones
→ gain Renown
→ improve equipment
→ overcome stronger content
```
The core rule becomes:
> **Renown opens doors. Equipment provides power.**
This slice must establish this as the technical foundation before Slice 0.7 adds the complete Verbrannte Straße reward loop.
---
# 2. Design principles
The implementation must follow these rules.
## 2.1 No classical XP
Ashen Realms no longer uses classical experience points.
Remove or migrate existing concepts such as:
```text
XP
experience
experiencePoints
experienceReward
XP reward
level-up through XP
```
Normal combat must never award global progression points simply because a monster died.
---
## 2.2 Renown is not renamed XP
Renown represents the character's overall significance and accomplishments in the world.
Renown comes primarily from meaningful milestones.
Examples:
```text
discover important location
complete important quest
reach important regional reputation rank
defeat Elite for first time
defeat regional Boss for first time
complete major story objective
```
Repeatedly killing weak monsters must not be an efficient way to increase Renown.
---
## 2.3 Equipment remains the main source of power
The existing Ashen Realms balance philosophy remains:
```text
approximately 20% base/global progression
approximately 80% equipment
```
Combat Power continues to represent actual combat strength.
Renown does not replace Combat Power.
A well-equipped character with lower Renown may be stronger than a poorly equipped character with higher Renown.
---
# 3. Global Renown
Replace the visible player Level with:
# Renown
The first full Vertical Slice is designed around:
```text
Renown 115
```
Instead of the previous Level 17 progression.
Target distribution:
| Region | Recommended Renown |
|---|---:|
| Aschenfelder | 15 |
| Dämmerwald | 510 |
| Vergessene Ruinen | 1015 |
These ranges are recommendations.
They are not access requirements.
A player may enter more dangerous areas early.
Actual danger remains determined primarily by equipment, Combat Power and enemy strength.
---
# 4. Renown power curve
Do not increase total character power merely because there are now more progression steps.
The previous total base-stat progression from approximately:
```text
100 HP / 6 Attack
```
to:
```text
148 HP / 12 Attack
```
should be distributed across Renown 115.
Use the following V1 reference:
| Renown | Base HP | Base Attack |
|---:|---:|---:|
| 1 | 100 | 6 |
| 2 | 104 | 6 |
| 3 | 107 | 7 |
| 4 | 111 | 7 |
| 5 | 114 | 8 |
| 6 | 118 | 8 |
| 7 | 121 | 9 |
| 8 | 125 | 9 |
| 9 | 128 | 9 |
| 10 | 132 | 10 |
| 11 | 135 | 10 |
| 12 | 139 | 11 |
| 13 | 142 | 11 |
| 14 | 145 | 11 |
| 15 | 148 | 12 |
These values are balancing references and may later be tuned through playtesting.
Do not increase equipment power budgets as part of this slice.
---
# 5. Renown milestones
Renown progression must be milestone-based.
Create a reusable concept for Renown milestones.
Conceptually:
```text
RenownMilestoneDefinition
CharacterRenownMilestone
```
Possible definition fields:
```text
id
key
name
description
renownReward
repeatable
enabled
```
Player completion should record:
```text
characterId
milestoneId
completedAt
timesCompleted
```
For normal V1 progression:
```text
repeatable = false
```
for almost all Renown milestones.
The exact numeric implementation may either:
A) accumulate Renown points from milestones and derive Renown Rank from thresholds
or
B) use milestone progress to advance Renown Rank directly.
Prefer the simplest design that fits the existing architecture.
However:
> Normal monster kills must never directly grant Renown.
---
# 6. Renown progression target for the Vertical Slice
The content should eventually produce approximately the following progression.
## Aschenfelder
```text
Renown 1
→ Renown 2
→ Renown 3
→ Renown 4
→ Renown 5
```
Possible milestone themes:
### Renown 1
Game start.
### Renown 2
First meaningful success outside Graufurt.
Examples:
```text
first successful hunt
first meaningful trophy returned
Verbrannte Straße established
```
### Renown 3
The player becomes known to the Grenzwacht.
Examples:
```text
reach first meaningful Grenzwacht reputation rank
complete important Wachtposten objective
```
### Renown 4
Player proves capable against stronger Aschenfelder threats.
Examples:
```text
defeat first Elite
discover Aschengrube
```
### Renown 5
Major Aschenfelder accomplishment.
Examples:
```text
defeat Hauptmann der Aschenbande
complete central Aschenfelder progression
```
Do not implement all of these content milestones in Slice 0.6.5.
Implement the system so later slices can define them through data.
---
# 7. Regional Reputation
Renown and Regional Reputation are separate systems.
## Renown answers:
> How far has this character progressed through the world?
## Regional Reputation answers:
> How much has this character done for these people?
Regional Reputation may be farmed through repeatable regional gameplay.
Renown generally may not.
---
# 8. Reputation factions
Create a reusable faction/reputation model.
For the current Vertical Slice plan for at least:
```text
Grenzwacht
Dämmerjäger
Letzte Wacht
```
Only the Grenzwacht needs to be seeded and technically usable in this slice.
Stable key:
```text
border-guard
```
Possible future keys:
```text
dusk-hunters
last-watch
```
Do not implement the later regions' content yet.
---
# 9. Reputation data model
Introduce:
```text
ReputationFaction
CharacterReputation
```
Conceptually:
## ReputationFaction
```text
id
key
name
description
regionKey
enabled
```
## CharacterReputation
```text
id
characterId
factionId
reputation
createdAt
updatedAt
```
Required database constraint:
```text
UNIQUE(characterId, factionId)
```
Reputation must be server-authoritative.
---
# 10. Reputation ranks
Regional Reputation uses named ranks.
Use the following V1 baseline:
| Reputation | Rank |
|---:|---|
| 0 | Stranger |
| 100 | Tolerated |
| 250 | Known |
| 500 | Recognized |
| 800 | Trusted |
| 1200 | Esteemed |
These thresholds are initial balancing values.
They may later be adjusted without changing the underlying architecture.
Internally define stable rank keys, for example:
```text
STRANGER
TOLERATED
KNOWN
RECOGNIZED
TRUSTED
ESTEEMED
```
Do not hardcode reputation rank logic separately in shops, quests and UI.
Create one authoritative reputation-rank resolver.
---
# 11. ReputationService
Introduce a dedicated backend service.
Conceptually:
```ts
grantReputation(
characterId: string,
factionKey: string,
amount: number,
): Promise<ReputationGrantResult>
```
The result should contain enough information for later UI feedback.
Example:
```ts
interface ReputationGrantResult {
factionKey: string;
previousReputation: number;
newReputation: number;
previousRank: string;
newRank: string;
rankChanged: boolean;
}
```
Also support reading the player's current reputation.
Conceptually:
```ts
getCharacterReputation(characterId: string): Promise<CharacterReputationDto[]>
```
---
# 12. RenownService
Introduce a dedicated Renown service.
Conceptually:
```ts
completeMilestone(
characterId: string,
milestoneKey: string,
): Promise<RenownMilestoneResult>
```
The service must verify:
```text
milestone exists
milestone is enabled
whether it was already completed
whether it is repeatable
reward is server-defined
resulting Renown
resulting Renown rank
```
Calling a non-repeatable milestone twice must not grant its reward twice.
---
# 13. Character migration
Inspect the current Character model.
If it already contains:
```text
level
experience
xp
```
migrate the player progression model.
The final Character domain should no longer rely on classical XP.
At minimum the character must expose:
```text
Renown
```
The exact persistence model may be:
```text
renown
```
or:
```text
renownPoints
renownRank
```
depending on the milestone implementation chosen.
Do not retain an unused player Level merely for compatibility.
If existing local development data only contains temporary demo characters, a simple migration such as:
```text
old Level 1 → Renown 1
old Level 2 → corresponding Renown baseline
```
is sufficient.
Do not over-engineer migration of disposable development data.
---
# 14. Remove requiredLevel from equipment
Inspect the existing ItemDefinition.
Classical:
```text
requiredLevel
```
must no longer act as the standard equipment restriction.
Core rule:
> **If the player earns an item, the player may use it.**
A strong item acquired unusually early may be equipped.
Reputation later restricts merchant availability.
It does not restrict an already-owned item's equipment eligibility.
Remove existing equipment validation based purely on player Level.
---
# 15. Reward model migration
Inspect existing combat victory and loot logic.
Old flow:
```text
Combat WON
→ XP
→ direct Silver
→ item loot
```
New flow:
```text
Combat WON
→ equipment roll
→ trade goods
→ trophies
→ optional milestone event
```
No normal combat victory automatically grants:
```text
XP
Renown
generic Silver
```
unless the monster explicitly has a lore-valid direct currency drop.
That must remain an exception rather than the default system.
---
# 16. Item reward roles
Extend the item/content model only as much as needed to support:
```text
EQUIPMENT
TRADE_GOOD
TROPHY
QUEST_ITEM
CONSUMABLE
```
Reuse the existing ItemDefinition where practical.
Do not create separate complex inheritance trees for every loot type.
At minimum Trade Goods and Trophies must support:
```text
stacking
quantity
icon
name
description
```
The existing inventory model should remain the source of player-owned items.
---
# 17. Trade Goods
Trade Goods primarily represent economic monster loot.
Examples for future Slice 0.7:
```text
Aschenfell
Zähes Fell
stolen goods
animal remains
```
They later convert into Silver.
Trade Goods do not inherently grant Renown.
Some may optionally be valid Reputation turn-ins if explicitly configured.
---
# 18. Trophies
Trophies represent proof that the character defeated a relevant enemy.
Examples:
```text
Räuberabzeichen
Plündererabzeichen
Elite trophy
Boss trophy
```
Trophies may later produce:
```text
Silver
Regional Reputation
first-time Renown milestone
```
These rewards must be defined through content data.
Not through special-case controller logic.
---
# 19. Turn-in foundation
Create a reusable content definition for future trophy/material turn-ins.
Conceptually:
```text
TurnInDefinition
```
Suggested minimal fields:
```text
id
key
itemDefinitionId
factionId
silverRewardPerItem
reputationRewardPerItem
repeatable
enabled
```
Optional later fields may include:
```text
firstTurnInMilestoneKey
minimumQuantity
maximumQuantity
```
Do not add these unless actually needed.
The important requirement is:
```text
item
→ faction
→ Silver reward
→ Reputation reward
```
is data-driven.
---
# 20. Turn-in service
Implement the domain service now even if the full NPC merchant UI comes later.
Conceptually:
```ts
turnIn(
characterId: string,
turnInKey: string,
quantity: number,
): Promise<TurnInResult>
```
The server must:
```text
load definition
verify character inventory quantity
calculate reward
remove submitted items
grant Silver
grant Regional Reputation
evaluate optional milestone
commit transaction
```
The operation must be atomic.
If any step fails:
```text
no items are lost
no Silver is granted
no Reputation is granted
```
---
# 21. Minimal Slice 0.6.5 content
Seed only enough content to prove the architecture.
## Faction
```text
Grenzwacht
key: border-guard
```
## Trade Good
```text
Aschenfell
```
## Trophy
```text
Räuberabzeichen
```
## Example Turn-In definitions
Initial development values:
### Aschenfell
```text
1 Aschenfell
→ 4 Silver
→ 1 Grenzwacht Reputation
```
### Räuberabzeichen
```text
1 Räuberabzeichen
→ 12 Silver
→ 4 Grenzwacht Reputation
```
These values are balancing placeholders.
Keep them in persisted content/seed data so they can be tuned without modifying business logic.
---
# 22. Loot integration
Connect the new loot types to the current reward pipeline.
If the currently implemented Slice 0.5/0.6 enemies already grant XP or direct Silver:
migrate those rewards now.
For the minimal current enemy set:
## Aschenratte
Should be capable of dropping:
```text
Aschenfell
```
## Straßenräuber
Should be capable of dropping:
```text
Räuberabzeichen
```
Equipment drops already implemented may remain.
Do not add the full Slice 0.7 loot tables yet.
Slice 0.7 will expand this content.
---
# 23. No Grenzmarken
Do not implement or preserve Grenzmarken as the normal guaranteed-progression currency.
The role previously intended for Grenzmarken is now primarily handled by:
```text
Regional Reputation
+
Silver
```
Future targeted merchant progression becomes:
```text
play content
→ collect trophies
→ gain Reputation + Silver
→ unlock shop offer by Reputation
→ buy with Silver
```
instead of:
```text
play content
→ gain Grenzmarken
→ buy item with Grenzmarken
```
Existing Grenzmarken code that has already been implemented should be removed or migrated unless another explicitly documented purpose exists.
---
# 24. Silver
Silver remains the global normal currency.
Character Silver persistence may remain unchanged if already implemented correctly.
The important change is its source.
Old:
```text
monster dies
→ automatically add Silver
```
New:
```text
monster dies
→ loot has economic value
→ player later sells / turns in loot
→ receive Silver
```
This slice may use the TurnInService to prove Silver gain server-side.
Do not implement a complete economy.
---
# 25. API
Expose minimal read APIs for the new progression system.
Conceptually:
```http
GET /api/renown
GET /api/reputation
```
A combined character endpoint may also expose these values if that matches the existing architecture better.
For turn-ins:
```http
POST /api/turn-ins
```
Example request:
```json
{
"turnInKey": "bandit-insignia-border-guard",
"quantity": 3
}
```
Do not accept:
```text
silverReward
reputationReward
faction reward
Renown reward
item value
```
from the client.
All reward values come from persisted server content.
---
# 26. Frontend progression display
Replace visible player Level in the persistent UI with:
```text
Renown 1
```
The Topbar should expose:
```text
character name
Renown
HP
Silver
```
Do not show all Regional Reputation values permanently in the Topbar.
Regional Reputation is contextual information.
---
# 27. Reputation UI foundation
Add a minimal reusable reputation display component.
Conceptually:
```text
Grenzwacht
Known
320 / 500 Reputation
```
It should support:
```text
faction name
current rank
current reputation
next threshold
progress visualization
```
This component does not need its final dedicated Reputation screen yet.
It will later be reusable in:
```text
Character screen
Merchant
NPC dialog
Region information
Quest rewards
```
---
# 28. Renown UI foundation
Renown should visibly appear as a character progression value.
Do not recreate a classical always-filling monster XP bar.
If progress toward the next Renown rank is shown, the UI should communicate that progress comes from accomplishments.
Possible presentation:
```text
Renown 3
Progress toward Renown 4:
2 / 3 major accomplishments
```
or another milestone-oriented presentation.
Do not display:
```text
742 / 1000 XP
```
with only a renamed label.
---
# 29. Rank-up feedback
When Regional Reputation crosses a rank threshold, the API result must expose this.
The frontend should be capable of later displaying:
```text
Grenzwacht reputation increased.
New rank:
Known
```
Similarly, when a Renown milestone results in a new Renown rank:
```text
Renown increased to 3.
```
Keep feedback visually appropriate to the existing Ashen Realms UI.
Do not implement large mobile-game-style reward popups.
---
# 30. Server authority
The server is authoritative for:
```text
Renown
completed milestones
Regional Reputation
Reputation ranks
Turn-In definitions
inventory quantities
Silver rewards
Reputation rewards
item removal
merchant eligibility later
```
The client only requests actions and displays resulting state.
---
# 31. Transactions
The following operations must be transactional:
## Turn-In
```text
consume items
+
grant Silver
+
grant Reputation
+
optional milestone completion
```
## Milestone completion
A non-repeatable milestone must not grant duplicate Renown due to:
```text
double click
retry
parallel request
race condition
```
Use database constraints and/or transactional validation where appropriate.
---
# 32. Required database migration
Create proper TypeORM migrations.
Do not use:
```text
synchronize: true
```
The migration should cover whichever of the following are required by the final implementation:
```text
Character Renown fields
ReputationFaction
CharacterReputation
Reputation rank content if persisted
RenownMilestoneDefinition
CharacterRenownMilestone
TurnInDefinition
ItemType changes
stackable item support
removal of obsolete XP fields
removal of requiredLevel
```
If dropping old fields in the same migration would make development migration unnecessarily risky, use staged migrations.
Prefer correctness over schema cleverness.
---
# 33. Existing XP migration
Search the entire repository for:
```text
xp
XP
experience
experienceReward
levelUp
requiredLevel
playerLevel
characterLevel
```
Every occurrence must be reviewed.
Do not blindly replace:
```text
level
```
because monster/content difficulty levels may still exist internally.
Player Level progression must disappear.
Monster Level may remain as internal balancing metadata if useful.
Visible danger should continue to use:
```text
Weak
Match
Strong
Very Dangerous
Deadly
```
rather than relying only on a number.
---
# 34. Existing Silver reward migration
Search for:
```text
silverMin
silverMax
silverReward
grantSilver
```
Identify which uses represent:
```text
direct monster reward
```
versus legitimate economy logic.
Direct generic monster-Silver rewards must be migrated to loot value.
Do not remove Character Silver itself.
---
# 35. Existing tests
Migrate obsolete tests such as:
```text
monster grants XP
character levels after enough XP
item rejected because requiredLevel is too high
combat directly grants normal Silver
```
Replace with tests covering the new model.
---
# 36. Required backend tests
At minimum verify:
## Renown
- normal monster kill grants no Renown
- milestone can grant Renown
- non-repeatable milestone cannot reward twice
- Renown rank is calculated correctly
- character base stats use Renown rather than old Level
## Reputation
- character starts at 0 Reputation for unknown faction
- Reputation grant persists
- rank resolver returns correct rank
- crossing threshold reports `rankChanged`
- Reputation cannot be authoritatively supplied by client
## Turn-In
- valid Turn-In consumes correct item quantity
- valid Turn-In grants configured Silver
- valid Turn-In grants configured Reputation
- insufficient quantity rejects transaction
- failed Turn-In consumes nothing
- failed Turn-In grants nothing
- multi-item quantity reward is calculated server-side
## Equipment
- owned equipment can be equipped without Level requirement
- reputation is not required to equip owned loot
---
# 37. Required frontend tests
Verify at minimum:
- Topbar displays Renown instead of Level
- no XP value is displayed
- Reputation component renders faction and rank
- Reputation threshold progress renders correctly
- Turn-In request contains only authoritative action input
- rank-change response can be represented in UI state
---
# 38. Existing Combat must remain unchanged
Do not rewrite Slice 0.6 combat mechanics.
These must continue to work:
```text
ATTACK
HEAVY_STRIKE
SHIELD_BASH
DEFEND
POTION
Telegraphing
Interrupt
Combat Log
Enemy Intent
```
The new progression system begins primarily after combat resolution.
Combat itself remains deterministic and server-authoritative.
---
# 39. Explicit non-goals
Do not implement yet:
```text
full merchant UI
NPC dialogue integration
quests
bag capacity system
crafting
professions
player trading
auction house
reputation decay
daily reputation caps
daily quests
faction wars
multiple competing factions
discount systems
dynamic prices
prestige Renown
achievements system
complete Dämmerwald Reputation
complete Ruins Reputation
```
Do not prematurely implement all 15 Renown ranks as unique content.
This slice builds the system.
Later slices provide the content.
---
# 40. Update Slice 0.7 assumptions
After this slice, Playable Slice 0.7 must no longer implement the following old rewards:
```text
XP
automatic normal Silver
Grenzmarken
```
The Complete Verbrannte Straße loop should instead become:
```text
hunt
→ fight
→ equipment / Trade Goods / Trophies
→ inventory
→ become stronger through equipment
→ accumulate turn-in loot
```
Examples:
## Aschenratte
Old:
```text
47 Silver
8 XP
60% Aschenfell
```
New direction:
```text
Aschenfell / Trade Goods
small equipment chance
```
## Straßenräuber
Old:
```text
915 Silver
16 XP
equipment
```
New direction:
```text
Räuberabzeichen
possible Trade Goods
equipment
```
## Verkohlter Plünderer
Do not award:
```text
35 XP
Grenzmarke
```
Use:
```text
valuable Trophy
better equipment chance
possible future first-kill milestone
```
Exact reward quantities belong in the updated Slice 0.7 content definition.
---
# 41. Update future merchant assumptions
The previously planned Grenzmarken merchant must eventually be migrated.
Future shop progression should use:
```text
Silver price
+
required Regional Reputation rank
```
Example:
```text
Aschenklinge
Price:
180 Silver
Requirement:
Grenzwacht Recognized
```
The requirement controls purchasing.
It does not control equipping an already-owned Aschenklinge.
---
# 42. Architecture rule
Keep the solution data-driven.
Do not create code such as:
```ts
if (item.key === 'bandit-insignia') {
reputation += 4;
}
```
Instead:
```text
ItemDefinition
+
TurnInDefinition
+
ReputationFaction
```
must define the relationship.
Likewise Renown milestones should be content definitions rather than scattered controller conditions where practical.
---
# 43. First complete future progression loop
This slice prepares the game for the eventual Aschenfelder loop:
```text
Graufurt / Südtor
travel
Verbrannte Straße
hunt
combat
collect Trade Goods + Trophies
continue hunting
inventory / bag fills
return to safe location
turn in hunting haul
Silver + Grenzwacht Reputation
higher Reputation rank
new merchant offer
buy equipment with Silver
Combat Power increases
stronger enemy becomes realistic
complete major milestone
Renown increases
```
This is the progression identity the architecture must support.
---
# 44. Definition of Done
Playable Slice 0.6.5 is complete when:
- classical player XP no longer exists in the active progression flow
- visible player Level has been replaced by Renown
- Renown supports the V1 target range of 115
- existing total base-stat power progression has been redistributed across Renown 115
- normal monster kills do not directly grant Renown
- Renown milestones exist as a reusable server-authoritative concept
- Grenzwacht exists as the first Reputation faction
- Character Reputation is persisted
- Reputation ranks are calculated centrally
- Trade Goods and Trophies can exist as inventory loot
- Turn-In definitions are data-driven
- a Turn-In can atomically consume loot and grant Silver + Reputation
- Aschenfell and Räuberabzeichen prove the new content model
- generic direct XP rewards are removed
- generic direct monster-Silver rewards are removed from currently implemented content
- `requiredLevel` no longer blocks owned equipment
- Grenzmarken are not introduced as the normal Aschenfelder progression currency
- UI displays Renown instead of Level
- UI has a reusable Regional Reputation presentation
- existing Slice 0.6 combat still works
- TypeORM migrations succeed
- backend tests pass
- frontend tests pass
- project-wide search shows no active classical XP progression remaining
---
# 45. Handoff
After this slice, continue with an **updated**:
```text
Playable Slice 0.7 Complete Verbrannte Straße
```
Slice 0.7 must build its rewards directly on:
```text
Equipment
Trade Goods
Trophies
Regional Reputation preparation
Renown milestones
```
and must not reintroduce:
```text
XP
automatic generic Silver rewards
Grenzmarken
```
The progression foundation is now:
> **Renown opens doors. Equipment provides power.**
> **Drops create excitement. Reputation guarantees long-term progress.**
> **Monsters provide loot. Civilization gives that loot economic and social value.**