vertical slice assessment

Guide for vertical slice assessment

Vertical Slice Assessment - Ranged Combat

Context

During the Equipment UI implementation, a vertical slice assessment was performed to identify remaining tasks for game completion. The focus was on verifying Ranged Combat mechanics.

Key Finding: Ranged Combat is Already Implemented

Ammo Consumption ✅

Location: src/systems/combat/mod.rs, lines 315-336
The system already handles:
  • Multi-shot weapons (e.g., Sharanga divine bow fires 2 arrows)
  • Ammo deduction from Equipment.ammo slot
  • Automatic slot clearing when ammo reaches 0
// Calculate ammo per shot BEFORE mutable borrow
let ammo_per_shot = if let Some(weapon_slot) = &equip.weapon {
    match weapon_slot.id.0 {
        11235 => 2,  // sharanga (divine bow)
        _ => 1,      // default single shot
    }
} else {
    1
};

// Consume ammo
if let Some(ammo_slot) = &mut equip.ammo {
    ammo_slot.quantity -= ammo_per_shot;
    if ammo_slot.quantity <= 0 {
        equip.ammo = None;
    }
}

Ammo Retrieval ✅

Location: src/systems/combat/mod.rs, lines 443-490 (on death), 513-542 (retrieval handler)
The system implements:
  • Quiver-based retrieval chances:
    • Raw arrows (no quiver): 0% retrieval
    • Basic Quiver: 50% retrieval
    • Enchanted Quiver: 70% retrieval
    • Enchanted Quiver + Peacock Feather: 80% retrieval
    • Enchanted Quiver + Garuda's Plume: 90% retrieval
  • Per-arrow roll (each arrow has independent chance)
  • Automatic return to inventory via AddItemEvent
// Calculate retrieval chance based on quiver type
let retrieval_chance = if let Some(ammo_slot) = &equip.ammo {
    match ammo_slot.id.0 {
        1001 | 1002 | 1003 => 0.0,  // raw arrows - lost forever
        10499 => 0.50,  // basic_quiver
        10500 => 0.70,  // enchanted_quiver
        10501 => 0.80,  // enchanted_quiver_peacock
        10502 => 0.90,  // enchanted_quiver_garuda
        _ => 0.0,
    }
} else {
    0.0
};

// Send retrieval event
ammo_retrieval_events.send(AmmoRetrievalEvent {
    killer: killer_entity,
    ammo_type: ammo_slot.id,
    ammo_count,
    retrieval_chance,
});

Remaining Gap: Equipment UI

The only missing piece was the player interface to equip weapons and ammo. This was addressed by:
  1. Adding equipment slots to Inventory UI
  2. Wiring UseItemEvent to EquipItemEvent via InteractionPlugin
  3. Implementing unequip functionality

Vertical Slice Status

✅ Complete

  • Magic System (spells, bijas, teleportation)
  • Ranged Combat mechanics (consumption + retrieval)
  • Equipment System UI (this implementation)
  • Skills (Cooking, Brewing, Farming)

🚧 Remaining (Non-Critical)

  • Item icons (currently showing IDs)
  • Drag-and-drop equipping
  • Ground item spawning for drops
  • Additional skill implementations

Testing Checklist

To verify Ranged Combat works end-to-end:
  1. ✅ Equip bow via Inventory UI
  2. ✅ Equip arrows via Inventory UI
  3. ✅ Attack enemy → verify ammo consumption
  4. ✅ Kill enemy → verify ammo retrieval (based on quiver)
  5. ✅ Equip Sharanga → verify 2 arrows consumed per shot
  6. ✅ Run out of ammo → verify combat stops

Architecture Notes

The Ranged Combat system demonstrates good separation of concerns:
  • Combat System: Handles attack logic and ammo consumption
  • Equipment System: Manages equipped items
  • Inventory System: Stores and retrieves items
  • UI System: Provides player interface
  • Interaction System: Bridges UI actions to game logic
No circular dependencies, clean event-driven architecture.