Skip to content

Loot Generation

Ruhan edited this page Aug 30, 2026 · 10 revisions

Base Items

The Item class provides the base structure for items in the loot generation system.

Each item has:

  • A unique ID
  • A name
  • An item type
  • A quantity
  • A maximum quantity

Item Types

The ItemType enum contains the following item types:

  • CONSUMABLE
  • WEAPON
  • CURRENCY

Quantity

The item quantity is limited between 0 and the maximum quantity.

The setQuantity() method prevents the quantity from going above the maximum quantity or below 0.

The addQuantity() method increases the item quantity while keeping it within the allowed range.

The isStackFull() method checks whether the item has reached its maximum quantity.

The isEmpty() method checks whether the item quantity is 0.

Validation

The Item constructor validates:

  • The item name cannot be null or blank.
  • The item type cannot be null.
  • The maximum quantity must be greater than 0.

Invalid values result in an IllegalArgumentException.

Testing

ItemTest verifies:

  • Item creation and properties
  • Unique IDs
  • Quantity limits
  • Adding quantity
  • Maximum quantity limits
  • Full stack detection
  • Empty stack detection
  • Invalid maximum quantity
  • Blank item names
  • Null item types
  • All three item types

Currency Items

Overview

The Currency Item introduces gold as an in-game currency and adds a visible Gold Coin entity to the game world. Gold is managed through InventoryComponent, while the coin itself is created using GoldCoinFactory.

Implementation

  • GoldCoinFactory creates the Gold Coin entity and attaches an AnimationRenderComponent.
  • The coin uses gold_coin.atlas for a spinning animation .
  • ForestGameArea loads the Gold Coin assets and spawns a coin at the center.
  • InventoryComponent manages the player's gold balance.
  • InventoryComponentTest tests the currency management functionality.

Current Status

The Gold Coin is created and spawned in the game world, and the player's gold balance can be managed through the inventory system. The connection between collecting the physical coin and automatically adding gold to the inventory is being handled by another team.

Weapon Items and Weapon Generation

Overview

This feature implements weapon items and weapon generation for the game. It supports different weapon types, damage values, weapon assets, and basic playable weapon functionality.

Weapon Item

WeaponItem extends the existing item structure with weapon-specific properties:

  • Weapon type
  • Damage value

The currently implemented weapon types are:

  • SWORD
  • BOW

Weapon Generation

WeaponGenerator generates weapon items based on their weapon type and level. This allows weapons to be generated consistently and used with other game systems.

Weapon Assets

Assets were added for the implemented weapons and projectile:

  • images/sword.png
  • images/bow.png
  • images/arrow.png

Playable Weapons

Sword

The sword is rendered with the player and supports basic attack behaviour using the weapon's damage value.

Bow and Arrow

The bow supports ranged attacks by creating an arrow projectile. The projectile travels through the game world in the attack direction.

Weapon Display

A basic weapon display was added to show the player's equipped weapon and its damage value.

Example:

Weapon: Sword
Damage:

Weapon Loot Spawning

Generated swords and bows can be spawned as weapon loot in the game area. This demonstrates that generated WeaponItem objects can be integrated with the game's loot system.

Testing

The implementation was tested using Gradle and manual in-game testing.

Gradle commands used:

.\gradlew.bat test

.\gradlew.bat spotlessCheck

In-game testing included weapon generation, sword attacks, bow functionality, projectile movement, weapon rendering, and weapon loot spawning.

Consumable Items

Overview

Consumable items are items the player can use for an immediate effect. There are three of them:

Consumable Sprite Effect
Health Potion Health.png Restores health, up to the player's maximum
Damage Potion Poison.png Multiplies attack damage for a set time, then reverts
Speed Potion Strength.png Multiplies movement speed for a set time, then reverts

ConsumableItem

ConsumableItem extends Item, in the same way WeaponItem does, and adds two properties:

  • consumableType - which consumable it is
  • effect - what happens when it is used

All consumables have the item type ItemType.CONSUMABLE. Each one also carries its own sprite, so nothing else has to look up a texture:

ConsumableType.HEALTH_POTION.getTexturePath();  // "images/Health.png"

Rather than one class deciding every behaviour with a switch, each item holds an effect object. HealEffect restores health and BuffEffect starts a timed stat change. Adding a new consumable later means writing a new effect class, not editing an existing one.

Using a consumable

ConsumableUseComponent is added to the player and listens for a useItem event carrying an inventory slot number:

entity.getEvents().trigger("useItem", slot);

An effect reports whether it actually did anything, and the item is only removed if it did. So a health potion used at full health has no effect and stays in the inventory.

"useItem" is triggered with a slot
      ↓
ConsumableUseComponent reads that slot from the inventory
      ↓
The item's effect is applied
      ↓
Did the effect do anything?
      ↓  yes                    ↓  no
One is removed from the stack   The item is left alone

Buffs

PlayerBuffComponent applies temporary stat changes and reverts them on its own. It uses the GameTime service, the same way WaitTask does, so there is no separate timer in the codebase.

It remembers the player's normal stats when it is created, then sets each buffed stat to its normal value multiplied by every active buff. Starting a buff and ending one both use that same rule, so overlapping buffs work and nothing drifts.

Buff state can be read from outside, so a buff timer UI can be added later:

  • buffApplied and buffExpired events, each carrying the ActiveBuff
  • getActiveBuffs() for the current list
  • ActiveBuff.getRemainingSeconds(currentTime) for a countdown

Item values and tiers

Heal amount, buff strength and duration are stored in configs/consumables.json and loaded into ConsumableConfig / ConsumableConfigs, following the same pattern as NPCConfigs. Values are not hardcoded.

ConsumableGenerator builds an item at a given loot tier, matching WeaponGenerator:

ConsumableItem potion =
    new ConsumableGenerator().generateConsumable(ConsumableType.HEALTH_POTION, 2);

Healing multiplies by tier. For buffs, only the part above 1.0 grows, so a configured 1.5x becomes 2.0x at tier 2. Items above tier 1 get a tier in their name, because the inventory stacks items by name and a weak potion should not merge with a strong one.

Rendering

Consumables are dropped and collected through the existing LootFactory, the same as weapons, so walking over one adds it to the inventory. They are drawn with BobbingTextureRenderComponent, which floats the sprite up and down so a dropped item reads as collectable. The float is applied when drawing rather than by moving the entity, so the pickup area stays where the item was placed.

Loot Generation and Inventory Connection

The loot generation system was connected to the inventory so that the items created in the game can actually be collected and stored by the player.

When a loot item is created, it is attached to the loot entity using LootPickupComponent. When the player touches the loot, the item is passed to the player's InventoryComponent.

This works for the different item types used in the game:

  • Weapons such as swords and bows are added to the inventory.
  • Consumables such as potions are added to the inventory with their quantity.
  • Currency such as gold coins is added to the player's stored gold.

The basic flow is:

Loot is generated
      ↓
LootFactory creates the loot entity
      ↓
LootPickupComponent handles the pickup
      ↓
Player touches the loot
      ↓
InventoryComponent receives the item
      ↓
Item is stored in the inventory

Testing

The loot generation and inventory connection was tested by running the game and checking each type of generated loot.

  1. Run the game and enter the Forest area.
  2. Locate the generated coins, weapons and consumable items.
  3. Move the player over each item to pick it up.
  4. Check that the item disappears from the game world after being collected.
  5. Open the player's inventory and check that the collected item has been added.
  6. Repeat this for coins, weapons and consumable items to confirm that all loot types are correctly connected to the Inventory system.

Expected Result

Coins, weapons and consumable items should all be collectible by the player. After being collected, each item should be stored correctly in the player's inventory.

Clone this wiki locally