Feature 05: Skill Queue
Overview
The skill queue is Delve’s core strategic system. Players build an ordered list of 6-10 combat skills with optional conditions. The server executes this queue during combat simulation. This feature covers building, saving, validating, and managing multiple named queues.
Dependencies
- Feature 04 (Character Progression) — for skill unlocks and weapon proficiency
Technical Tasks
1. Static Game Data — Skills
- Flesh out
data/skills/TOML files (started in Feature 04) with full combat skill details:- Per skill: id, name, description, type (attack/heal/buff/debuff/utility), resource_cost (type + amount), cooldown (rounds), base_damage/healing, success_modifier, initiative_modifier, target_type (single/aoe/self/ally), conditions_applied, weapon_type_required
- Weapon skills: 10 per weapon type (sword, axe, dagger, bow, staff, wand, shield, mace, spear)
- Class skills: 8-12 per class, unlocked at level milestones
- Species skills: 1 passive per species (not queued — applied automatically)
- Gear skills: defined on Legendary/Artifact weapon templates (not in skills data — on item templates)
2. Skill Queue Types (crates/types)
- Create
src/skill.rs:SkillQueueSlot { skill_id: String, condition: QueueCondition }QueueConditionenum with all condition variants:AlwaysIfHpBelow { threshold: u8 }IfHpAbove { threshold: u8 }IfTargetHpBelow { threshold: u8 }IfEnemyCountAbove { count: u8 }IfEnemyCountBelow { count: u8 }IfAllyHpBelow { threshold: u8 }IfResourceAbove { resource: ResourceType, amount: u16 }IfResourceBelow { resource: ResourceType, amount: u16 }IfHasCondition { condition: StatusEffect }IfTargetHasCondition { condition: StatusEffect }
ResourceTypeenum: Stamina, Momentum, Mana, Devotion, Focus, Fury, Resonance, Zeal, Essence
3. Skill Queue Validation (crates/game)
- Create
src/skill_queue.rs:validate_queue(character: &Character, slots: &[SkillQueueSlot], proficiencies: &[WeaponProficiency], equipped: &[Item]) -> Result<()>:- Queue length: 1-10 slots (minimum 1, maximum 10)
- Every skill_id must be known by the character (from class, weapon proficiency, or equipped gear)
- Weapon skills require the matching weapon type equipped
- Conditions must reference valid resource types for the character’s class
- Thresholds must be in valid ranges (0-100 for HP%, valid amounts for resources)
- Must have at least one
Alwayscondition or the queue may never fire
get_available_skills(character: &Character, proficiencies: &[WeaponProficiency], equipped: &[Item]) -> Vec<SkillInfo>:- Return all skills the character can use based on class, weapon proficiency, and gear
- Used by the client to populate the skill picker
4. Skill Queue Database Operations
- Already created
skill_queuestable in Feature 04 migration - Create
src/queries/skill_queues.rs:create_skill_queue(pool, character_id, name, slots_json) -> SkillQueuefind_skill_queues(pool, character_id) -> Vec<SkillQueue>find_active_queue(pool, character_id) -> Option<SkillQueue>update_skill_queue(pool, id, name?, slots_json?)set_active_queue(pool, character_id, queue_id)— deactivates all others, activates this onedelete_skill_queue(pool, id)
5. Skill Queue Routes (crates/api)
- Create
src/routes/skill_queues.rs:GET /api/characters/:id/skill-queues:- Return all saved queues for the character (each with name, is_active, slots)
POST /api/characters/:id/skill-queues:- Body:
{ name, slots: [{ skill_id, condition }] } - Validate queue (all skills owned, conditions valid)
- Save to DB
- Return created queue
- Body:
PUT /api/characters/:id/skill-queues/:queue_id:- Update name and/or slots
- Re-validate if slots changed
DELETE /api/characters/:id/skill-queues/:queue_id:- Cannot delete the active queue (must activate another first)
POST /api/characters/:id/skill-queues/:queue_id/activate:- Set as active queue (used for the next run)
GET /api/characters/:id/available-skills:- Return all skills the character can currently use (for the queue builder UI)
6. Client — Skill Queue Builder
- Create
routes/(game)/character/skill-queue/+page.svelte:- Queue selector: dropdown of saved queues, “New Queue” button
- Queue builder:
- Ordered list of skill slots (drag-and-drop reordering)
- Each slot shows: skill icon/name + condition dropdown
- “Add Skill” button opens skill picker
- Skill picker: filterable list of available skills grouped by source (class, weapon, gear)
- Condition editor: dropdown per slot with type + threshold input
- Save/rename/delete queue buttons
- “Set Active” button
- Validation feedback: highlight invalid slots, show error messages
- Create
lib/components/character/SkillQueueBuilder.svelte - Create
lib/components/character/SkillPicker.svelte - Create
lib/components/character/ConditionEditor.svelte
Tests
Unit Tests
validate_queue: accepts valid queue with all skills ownedvalidate_queue: rejects empty queuevalidate_queue: rejects queue > 10 slotsvalidate_queue: rejects skill not owned by charactervalidate_queue: rejects weapon skill without matching weapon equippedvalidate_queue: rejects invalid condition threshold (e.g., HP > 100%)validate_queue: warns (but allows) queue with noAlwaysfallbackget_available_skills: returns class skills for character’s classget_available_skills: returns weapon skills up to current proficiencyget_available_skills: returns gear skills from equipped Legendary weaponget_available_skills: doesn’t return skills for unequipped weapon typesQueueConditionserialization round-trips correctly (serde JSON)
Integration Tests
GET /api/characters/:id/skill-queuesreturns empty list for new characterPOST /api/characters/:id/skill-queuescreates queue and returns itPOST /api/characters/:id/skill-queueswith invalid skill → 422PUT /api/characters/:id/skill-queues/:idupdates name and slotsPOST /api/characters/:id/skill-queues/:id/activatesets active flag- Only one queue is active at a time (activating one deactivates others)
DELETEon active queue → 409GET /api/characters/:id/available-skillsreturns skills based on class + proficiency + gear- Queue slots JSONB round-trips correctly (stored and retrieved identically)