# Suitbuilder Architecture & Implementation Status ## Overview The Equipment Suit Builder is a real-time optimization engine that finds optimal equipment loadouts for characters by searching across multiple characters' inventories (mules). It uses constraint satisfaction algorithms derived from the original Mag-SuitBuilder (C#) plugin, reimplemented in Python as part of the inventory-service. **Status:** Production Ready **Access:** `/suitbuilder.html` **Backend:** `inventory-service/suitbuilder.py` **Frontend:** `static/suitbuilder.js`, `static/suitbuilder.html`, `static/suitbuilder.css` --- ## Key Achievements (2025-2026) - Multi-character search across 100+ characters and 25,000+ items - Mag-SuitBuilder constraint satisfaction algorithms with branch pruning - Real-time SSE streaming with phase updates and progress tracking - Spell bitmap-based overlap detection and scoring - Locked slot constraints with set/spell preservation across searches - Stable deterministic sorting for reproducible results - Comprehensive UI with suit summary and copy-to-clipboard - Individual slot clear buttons for granular control - Full cantrip/ward selection UI (attributes, weapon skills, magic skills, defenses, wards) --- ## Architecture ### Core Components 1. **ConstraintSatisfactionSolver** - Main search engine. Performs recursive depth-first search through equipment buckets, applying constraints and scoring at each level. 2. **ItemBucket** - Slot-based item organization. Groups items by equipment slot, sorts by priority (armor level, ratings, spells), and handles armor reduction variants. 3. **SpellBitmapIndex** - O(1) spell overlap detection using bitwise operations. Each spell is assigned a unique bit position, enabling instant duplicate detection. 4. **SuitState** - Mutable state during recursive search. Tracks equipped items, aggregated spell bitmap, set counts, total armor, and ratings. 5. **SearchConstraints** - User-defined requirements including character selection, set preferences, required spells, locked slots, and scoring weights. 6. **ItemPreFilter** - Pre-processing step that removes strictly dominated items (items surpassed in all metrics by another item in the same slot). ### Data Flow ``` User (suitbuilder.html) | | POST /inv/suitbuilder/search (constraints JSON) | v Main Service (main.py) | | Streaming proxy (dedicated SSE endpoint) | v Inventory Service (inventory-service/main.py) | | Routes to suitbuilder module | v ConstraintSatisfactionSolver | | 1. Load items from inventory DB | 2. Create equipment buckets per slot | 3. Apply armor reduction rules | 4. Sort buckets (smallest first for pruning) | 5. Recursive search with constraint checking | 6. Score and yield suits via SSE stream | v User (real-time suit results appear as found) ``` ### SSE Streaming Architecture The suitbuilder search is a long-running operation (up to 5 minutes). Results stream in real-time via Server-Sent Events (SSE). **Main service** (`main.py`) has a dedicated streaming proxy endpoint at `/inv/suitbuilder/search` that uses `httpx.AsyncClient.stream()` to forward chunks without buffering. The generic `/inv/{path:path}` proxy buffers entire responses, which would cause timeouts for SSE streams. **Event types streamed:** - `phase` - Search phase updates (loading, buckets, reducing, sorting, searching) - `suit` - New suit found with items and score - `log` - Verbose debug messages - `stats` - Search statistics (branches explored, suits found, elapsed time) - `complete` - Search finished - `error` - Error occurred --- ## Spell System Implementation ### Spell Bitmap Index Uses bitwise operations for O(1) spell overlap detection: - Each spell is assigned a unique bit position in an integer bitmap - `spell_bitmap |= item.spell_bitmap` aggregates spells across items in a suit - `new_spells = item_bitmap & needed_bitmap & ~current_bitmap` detects novel spell contributions - Prevents duplicate spell slots across items in strict mode ### Spell Constraint Flow 1. **UI Collection**: Checkboxes for legendary cantrips and wards - **Attributes**: Strength, Endurance, Coordination, Quickness, Focus, Willpower - **Weapon Skills**: Finesse, Heavy, Light, Missile, Two-handed - **Magic Skills**: War Magic, Void Magic, Creature, Item, Life Magic - **Defenses**: Magic Resistance, Invulnerability - **Wards**: Flame, Frost, Acid, Storm, Slashing, Piercing, Bludgeoning, Armor 2. **Backend Processing**: - `needed_spell_bitmap = spell_index.get_bitmap(required_spells)` pre-computes target - During item loading: `item.spell_bitmap = spell_index.get_bitmap(item.spell_names)` - During search: `_can_get_beneficial_spell_from()` rejects items with only duplicate spells - Items with spells that contribute nothing new to the suit are pruned 3. **Scoring**: - Each fulfilled required spell: +100 points - Duplicate spells prevented by constraint (not scored negatively, just blocked) - Encourages maximum spell diversity across the suit ### Jewelry Special Handling Jewelry (rings, bracelets, necklaces, trinkets) receives special treatment: - Only added to suits if they contribute new required spells - Prevents jewelry spam when no spell constraints are specified - Prioritizes spell contribution over raw stats for jewelry slots - Items with zero beneficial spell contribution are rejected --- ## Recent Features (February 2026) ### Locked Slots System Allows users to lock specific equipment slots with set and spell constraints. Locked slots are preserved when selecting different suit results. **Features:** - Lock populated slots automatically (extracts set + spells from the item) - Lock empty slots manually (configure set + spell requirements via form) - Visual distinction (red border, lock icon) - Constraints sent to backend (locked slots filtered from search buckets) - Preserved when selecting different suits from results **Use Cases:** - "I already have this Legendary Empyrean Helm, find suits around it" - "Lock Head slot to Empyrean set with L. Strength + L. Flame Ward" - Iterative refinement: lock good items, re-search for better accessories ### Suit Summary Panel Copy-paste friendly summary below equipment slots showing all items with their source characters. **Format:** ``` Slot: Item Name [Spell1, Spell2] - Character Name ``` **Features:** - Auto-updates when suit selected or slots cleared - Copy to clipboard button with visual feedback - Monospace font for readability - Shows all equipped items with their source characters ### Clear Slot Button Small "x" button on populated slots for granular control: - Clears individual slots without affecting locked state - Removes item from selected suit state - Updates summary automatically --- ## Known Limitations ### Slot-Aware Spell Filtering The system currently treats all slots equally when checking spell availability. In reality, certain cantrips and wards never appear on underclothes (shirt/pants). The search could be optimized by pre-filtering based on realistic spell pools per slot type. ### Spell Priority Weighting All required spells are weighted equally (+100 points each). There is no mechanism to mark certain spells as "critical" vs "nice to have." --- ## Future Enhancements Roadmap ### Phase 1: Spell System Improvements #### Spell Priority Weighting Allow users to mark certain spells as critical vs optional: - Critical spells: +200 points (must have) - High priority: +150 points - Normal priority: +100 points (current default) - Low priority: +50 points #### Slot-Aware Spell Filtering Pre-filter items based on realistic spell pools per slot type: - **Underclothes** (Shirt/Pants): Primarily damage rating, rarely cantrips/wards - **Armor** (Head/Chest/Arms/Legs/Hands/Feet): Full cantrip/ward pool - **Jewelry** (Rings/Bracelets/Neck): Full cantrip/ward pool - **Trinket**: Limited or no spells Benefits: Faster search (smaller search space), more realistic suit expectations, better UX. ### Phase 2: New Builders #### Weapon Suit Builder Optimize weapon + shield/offhand combinations: - Weapon skill requirements (Heavy, Light, Finesse, etc.) - Damage type optimization - Special property constraints (Crushing Blow, Armor Rending, etc.) #### Accessory-Only Builder Find best jewelry/trinket combinations when armor is already decided: - Smaller search space = faster results - Focus on spell coverage and rating optimization - Use case: "I have my armor set, find best accessories" #### Multi-Suit Batch Generation Generate multiple viable suits in one search: - "Show me top 10 suits for different playstyles" - Variation in set combinations - Export/compare multiple options ### Phase 3: Advanced Features #### Saved Searches - Save constraint configurations as named presets - Quick re-run with updated inventory - Presets like "Mage Build", "Tank Build", etc. #### Suit Comparison - Side-by-side comparison of 2-3 suits - Highlight differences in items, spells, and ratings - Visual scoring breakdown