Repository navigation
Player Inventory
The Player Inventory System manages items owned by the player. It uses a slot-based grid to support item storage, stacking, selection, hotbar access, and inventory expansion.
By default, the inventory contains 3 rows × 8 columns (24 slots). The first row is used as the player's hotbar.
The main component responsible for inventory state and operations, including:
- Adding and removing items
- Item selection
- Item sorting by Itemid
- Inventory capacity
- Slot swapping and expansion
Represents one physical inventory slot containing an ItemType and its quantity. Empty slots contain no item.
Displays the first row of the inventory as the player's hotbar.
Displays the complete inventory grid and selected item information.
Handles world-item pickup, automatic gold collection, and dropping or deleting the selected item stack.
Stores a world coin's gold value and prevents it from being collected more than once. Gold is managed as currency rather than occupying an inventory slot.
The inventory stores its slots using:
List<InventorySlot> slots;Items of the same ItemType are stacked together. New item types are placed into the first available empty slot.
The first inventory row acts as the hotbar:
┌────┬────┬────┬────┬────┬────┬────┬────┐
│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ Hotbar
├────┼────┼────┼────┼────┼────┼────┼────┤
│ │ │ │ │ │ │ │ │
├────┼────┼────┼────┼────┼────┼────┼────┤
│ │ │ │ │ │ │ │ │
└────┴────┴────┴────┴────┴────┴────┴────┘
Inventory changes trigger inventoryChanged, while selection changes trigger inventorySelectionChanged. UI components listen to these events and update automatically.
classDiagram
class InventoryComponent {
-List~InventorySlot~ slots
-int rows
-int columns
-int selectedSlotIndex
+addItem(ItemType, int) boolean
+removeItem(ItemType, int) boolean
+selectSlot(int)
+selectNext()
+selectPrevious()
+swapSlots(int, int)
+sortByItemId()
}
class InventorySlot {
-ItemType itemType
-int quantity
+getItemType() ItemType
+getQuantity() int
+isEmpty() boolean
}
InventoryComponent "1" *-- "*" InventorySlot
| Method | Purpose |
|---|---|
addItem(item, quantity) |
Add items to the inventory |
removeItem(item, quantity) |
Remove items |
getItemCount(item) |
Get an item's quantity |
hasItem(item) |
Check whether an item exists |
selectSlot(index) |
Select a specific slot |
selectNext() / selectPrevious()
|
Cycle between owned items |
swapSlots(a, b) |
Swap two inventory slots |
sortByItemId() |
Sort item by itemid |
addRow() / addColumn()
|
Expand the inventory |
InventoryComponent inventory = new InventoryComponent(0);
inventory.addItem(ItemType.ARROW, 10);
inventory.addItem(ItemType.RopeArrow, 1);
inventory.selectSlot(0);
int arrows = inventory.getItemCount(ItemType.ARROW);
inventory.removeItem(ItemType.ARROW, 1);Gold coins within 0.75 world units of the player's centre are collected automatically without pressing F. A standard coin grants 10 gold, while custom coins may grant a different amount.
Collected gold increases the player's currency without occupying an inventory slot. Each coin can only be awarded once. Automatic collection stops while the game is paused or the shop is open.
Ordinary items and wheel tokens still require manual interaction.
| Key | Action | Result |
|---|---|---|
R |
Drop the selected stack | Removes the entire stack from the inventory and creates a world item at the player's position, allowing it to be picked up again. |
Delete (Forward Delete) |
Delete the selected stack | Permanently removes the entire stack without creating a world item. |
If an empty slot is selected, neither operation changes the inventory. Successful operations update the inventory display and emit itemDropped or itemDeleted.
Automated tests cover the inventory, item-use, player-interaction, and ranged-combat systems.
InventoryComponentTest verifies:
- Adding, stacking, and removing items
- Inventory capacity and invalid quantities
- Item selection, switching, and sorting
- Slot swapping and selection preservation
- Row and column expansion
- Quick-slot selection
- Invalid and no-op inventory operations
- Inventory and selection change events
PlayerInteractionComponentTest verifies:
- Detecting the nearest item within interaction range
- Ignoring non-item and out-of-range entities
- Picking up items and handling a full inventory
- Dropping the complete selected item stack
- Permanently deleting the complete selected item stack
- Rejecting drop or delete operations when no item is selected
- Switching between owned items
- Emitting the appropriate success and failure events
- Automatically collecting all gold within the pickup radius
- Respecting the automatic pickup distance boundary
- Preventing duplicate gold awards before deferred removal
- Suspending automatic collection while paused or shopping
- Leaving ordinary items and wheel tokens for manual interaction
ItemUseComponentTest verifies:
- Standard arrows are consumed when fired
- A projectile attack event is produced for a valid standard-arrow attack
- The player cannot attack without owning and selecting an item
- Health potions heal the player and are consumed
- Potions cannot be used at full health
- Rope Arrows are not consumed
- Rope Arrow cooldown is applied and enforced
KeyboardPlayerInputComponentTest verifies:
-
Eproduces only one attack per key press - Attacks use the current mouse aim direction
- The player cannot bypass inventory validation when
ItemUseComponentis missing -
Rdrops the selected stack -
Deleteremoves the selected stack - Movement, jumping, sprinting, and grapple input events
GrappleComponentTest, BowComponentTest, and
ArrowProjectileComponentTest verify:
- Grappling is rejected when the player does not own a Rope Arrow
- Grappling succeeds without consuming an owned Rope Arrow
- Bow attacks create projectiles in the requested direction
- Projectiles damage valid targets only once
- Projectiles expire when hitting terrain or obstacles
- Projectile range and movement behaviour
The following behaviours should also be checked during gameplay:
-
Fpicks up the nearest item within range -
Edoes nothing when no owned arrow is selected - Standard arrows visibly spawn and damage a target
-
Rcreates a dropped world item containing the complete selected stack -
Deleteremoves the selected stack without spawning a world item - Rope grappling only works while a Rope Arrow is owned
- Inventory and hotbar displays refresh after pickup, use, drop, and deletion
- Attack, item-use, and failure audio/visual feedback appears at the correct time
- Fire Arrow and Cold Arrow attributes are unit tested, but their complete attack-effect pipelines are not yet covered by integration tests.
From the source directory:
./gradlew core:testEntities and Components
Input Handling
Arrow Selection Wheel Arrow Selection Wheel — Sprint 3
Game Screens and Areas
Enemies
-
Individual Enemy Pages:
-
Misc Enemy Pages: