6.2 KiB
Ashen Realms – Playable Slice 0.7.5
Monster Categories & Loot Bags
Status: Implementation Specification
Depends on: Slice 0.7 V2
Purpose: Introduce category-based carrying limits for monster trade goods and create the first logistical reason to return from hunting.
1. Goal
Monster loot should not be infinitely farmable in one trip.
The player can carry only a small amount of category-specific trade goods without a bag. Dedicated loot bags increase that capacity.
This creates the loop:
Hunt → fill bag → return → exchange goods → upgrade capacity → hunt longer.
The system must be simple, visible and data-driven.
2. Core Rule
Each trade good belongs to exactly one Loot Category.
A character has a carrying capacity for each loot category.
Without a matching bag, the default carrying capacity is:
1 unit per loot category.
Example:
Ashen Pelt: HIDE
Current HIDE capacity: 1
Player owns 1 Ashen Pelt
→ another Ashen Pelt cannot be carried
A Hide Bag with capacity 5 changes this to:
HIDE capacity: 5
3. Initial Categories
Implement only the categories needed by the current content, but design the enum so future categories can be added.
Initial categories:
HIDE
RAIDER_TROPHY
Suggested future categories, not required yet:
CHITIN
UNDEAD_RELIC
ARCANE_REMAINS
4. Initial Trade Good Mapping
| Trade Good | Loot Category |
|---|---|
| Ashen Pelt | HIDE |
| Tough Hide | HIDE |
| Raider Insignia | RAIDER_TROPHY |
| Charred Raider Insignia | RAIDER_TROPHY |
The mapping belongs to content data, not hardcoded monster-specific UI logic.
5. Monster Categories
Monster definitions also receive a broad gameplay category.
Initial examples:
BEAST
HUMANOID
Suggested mapping:
| Monster | Monster Category |
|---|---|
| Ash Rat | BEAST |
| Feral Road Hound | BEAST |
| Road Bandit | HUMANOID |
| Charred Raider | HUMANOID |
Monster category and loot category are separate concepts.
Example: different BEAST monsters can later drop HIDE, CHITIN or another loot category.
Do not assume monsterCategory === lootCategory.
6. Bag Model
Loot bags are not normal armor equipment slots.
They belong to a separate character loadout/state.
Recommended data model concept:
LootBagDefinition
- id
- key
- name
- lootCategory
- capacity
- iconPath
CharacterLootBag
- characterId
- lootBagDefinitionId
- equipped / active
Only one active bag per loot category is required for V1.
No nesting and no physical inventory grid.
7. Initial Bag Definitions
The system must support at least:
Basic Hide Bag
Name: Basic Hide Bag
Category: HIDE
Capacity: 5
Basic Trophy Pouch
Name: Basic Trophy Pouch
Category: RAIDER_TROPHY
Capacity: 5
They do not both need to be obtainable in this slice. Acquisition is handled by the merchant/quest slices.
8. Capacity Calculation
The server is the single authority.
Conceptually:
capacity(category) = active bag capacity
if no active bag exists:
capacity(category) = 1
The current amount is the sum of all owned trade-good quantities in that category.
Equipment, consumables and normal items are not affected by loot-bag capacity.
9. Full Bag Behavior
If combat loot would exceed the capacity:
- the combat victory remains valid
- the trade good is not granted beyond capacity
- other loot rolls still succeed normally
- equipment must not be lost because the hide bag is full
- the loot summary explains what was left behind
Example:
Loot
Ashen Pelt ×1 – Left behind (Hide Bag full)
Bandit Hood ×1 – Added to inventory
Do not silently discard loot without player feedback.
10. Mixed Loot
If one result grants multiple trade goods, grant as many as fit.
Example:
Current HIDE: 4 / 5
Reward: Tough Hide ×2
Granted: 1
Left behind: 1
The result DTO should make granted and rejected quantities explicit.
11. API / DTO Requirements
The frontend needs enough information to display current carrying state.
Example DTO concept:
{
"category": "HIDE",
"current": 4,
"capacity": 5,
"bag": {
"key": "basic-hide-bag",
"name": "Basic Hide Bag"
}
}
Provide a server-side way for the player UI to retrieve all relevant category capacities.
This can be part of inventory state or a dedicated endpoint, whichever best fits the current codebase.
12. UI Requirements
The current carrying state must be visible during or directly after hunting.
Minimum:
Hides 4 / 5
Raider Trophies 1 / 1
If a category is full, make it obvious before the player starts another farm cycle.
The loot summary must display:
- granted trade goods
- capacity after loot
- left-behind goods when full
Do not turn this into a large inventory-management screen.
13. Tests
Capacity
- no bag gives capacity 1
- Basic Hide Bag gives HIDE capacity 5
- Hide Bag does not increase RAIDER_TROPHY capacity
- only active bag affects capacity
Loot granting
- first Ashen Pelt can be carried without a bag
- second Ashen Pelt is rejected without a bag
- equipment reward still grants when trade-good capacity is full
- partial quantity grant works
Security
- client cannot submit a fake capacity
- client cannot fake an equipped bag
- capacity is derived from persisted character state
14. Acceptance Criteria
- Monster definitions have a reusable monster category.
- Trade goods have a reusable loot category.
- Default capacity without bag is 1 per loot category.
- Dedicated loot bags increase only their configured category.
- Capacity enforcement is server-authoritative.
- Full bags never invalidate a combat victory.
- Excess trade goods are clearly shown as left behind.
- Equipment/consumables are unaffected by trade-good capacity.
- Current bag capacity can be displayed in the UI.
- Tests cover full, partial and no-bag cases.
15. Out of Scope
Do not implement:
- weight
- Tetris inventory
- bag durability
- random bag affixes
- crafting bags
- upgrades on one physical bag item
- more than one active bag per category
- automatic sending of excess loot to storage