Repository navigation
Item Library and Discovery
Team 5, Sprint 4 | Permanent item discovery, acquisition rules, Library presentation and Save/Load integration | Implemented in PR #520
The Item Library is a permanent collection catalogue, not the player's current inventory. It lists every configured ItemType, but only reveals a record after the player legitimately obtains that item during a run. This lets the Library show collection progress without exposing unrevealed item names, effects, sources or artwork.
The system is owned by ItemDiscoveryService. It is deliberately separate from PlayerRunState.ownedItems: an item can be consumed or lost from the active run while remaining discovered in the Library.
For run-scoped ownership, item effects and the inventory popup, see Inventory and Item Persistence. For reward generation and claiming, see Reward System.
Each ItemType begins in LOCKED and can advance one way to DISCOVERED.
| State | Library list | Detail panel |
|---|---|---|
LOCKED |
A ??? entry remains visible so the player can see collection progress. |
The name, source, effect and artwork are hidden. The artwork area uses a blank ? silhouette and the panel says: Obtain this item during a run to reveal it.
|
DISCOVERED |
The real item name is shown. | The real artwork, source and description are shown. |
The display provides separate Relics and Curses filters and a Discovered n / total counter. It listens for discovery updates and rebuilds immediately when a record advances.
All known-source item grants should go through ItemAcquisitionService.grant(playerState, item, source). The service first adds the item to the active run and then records permanent discovery only when that source is allowed to discover it.
ItemAcquisitionSource |
Discovery result |
|---|---|
NORMAL_REWARD |
Discovers the item after a successful normal post-battle reward claim. |
CHANCE_EVENT |
Is the supported source for a completed chance-event item grant; event code should use this path when it grants an item. |
DEBUG |
Adds the item for testing but does not reveal it in the Library. |
This central entry point prevents previews, browsing and developer commands from accidentally changing player progression.
flowchart LR
grant["Item grant"] --> acquire["ItemAcquisitionService.grant"]
acquire --> inventory["PlayerRunState ownedItems"]
acquire --> allowed{"Source can discover?"}
allowed -->|"NORMAL_REWARD or CHANCE_EVENT"| discover["ItemDiscoveryService"]
allowed -->|"DEBUG"| unchanged["No discovery change"]
discover --> store[("item_discovery.json")]
discover --> display["ItemLibraryDisplay refresh"]
saved["Saved progress.items"] --> merge["mergeProgress"]
merge --> discover
GdxGame loads item discovery into the shared ItemDiscoveryService at startup and writes changed progress to DECO2800Game/item_discovery.json through ItemDiscoveryStore. The store records only non-locked entries using stable ItemType.name() identifiers. Missing, unreadable or obsolete entries leave the corresponding item locked rather than breaking startup.
Discovery is profile-wide and survives a completed run, item consumption, game restart and switching save slots.
Manual saves also carry a snapshot of non-locked item discovery entries in ProgressSaveData.items as ItemProgressSaveData(itemId, unlockState). SaveGameRestoreService validates the list before applying any loaded state, ignores item IDs removed from a future item roster, and then calls ItemDiscoveryService.mergeProgress(...).
The merge is intentionally monotonic: loading an older save may add discoveries from that save, but can never re-lock an item that the live profile learned later. Older save files with no progress.items field remain valid and simply contribute no item-discovery data.
ItemLibraryScreen opens from the Library menu and uses ItemLibraryDisplay's list-and-detail layout. The page is read-only: it is not a shop, reward chooser or inventory view. It always contains all configured item records, while the discovery state controls what each record reveals.
The Library uses the shared menu theme and item artwork paths. A missing item artwork asset falls back through the normal icon-view handling; it must not expose hidden artwork for a locked entry.
| Concern | Owner / source of truth |
|---|---|
| Items currently owned during the active run, quantities and item effects |
PlayerRunState.ownedItems / ItemInventory
|
| Permanent knowledge that an item has been found | ItemDiscoveryService |
| Item reward generation and selection | Reward system |
| Collection browsing and lock-state presentation | Item Library |
These states intentionally do not mirror each other. For example, using a consumable removes it from the run inventory but does not hide its discovered Library entry.
Automated coverage includes:
-
ItemDiscoveryServiceTestfor state transitions, validation and non-downgrading merges. -
ItemDiscoveryStoreTestfor profile-file round trips and malformed/missing data handling. -
ItemAcquisitionServiceTestfor legitimate acquisition versusDEBUGbehaviour. -
ItemLibraryDisplayTestandItemLibraryScreenTestfor locked presentation, filters, counts, refreshes and asset paths. - Save/Load snapshot and restore tests for
progress.items, legacy saves and merge-on-load behaviour.
Manual regression checks should confirm that a newly claimed normal reward reveals its entry, a Debug grant does not, a consumed item remains discovered, and loading an earlier save cannot hide a later discovery.
Entities and Components
Input Handling
Game Screens and Areas
Encounters
Tutorials and Contextual Help (Team 2)
- Feature Overview
- Tutorial Entry and Fresh Run Transition
- Tutorial Battle Setup and Enemy Integration
- Battle Tutorial Guidance UI
- Battle Tutorial Steps and Progression
- Contextual Event Help and Tutorial Content
- Tutorial Acceptance Test Plan
- Card Keyword Tooltips
- Map Introduction
- Tutorial Status Teaching
- Tutorial Victory Screen