MosswartOverlord/docs/plans/2026-02-09-suitbuilder-architecture.md
erik 850cd62d7b Update suitbuilder documentation to reflect production-ready status
- Replace outdated CLAUDE.md suitbuilder section with concise production-ready summary
- Remove incorrect claims about spell system not being implemented
- Create detailed architecture document at docs/plans/2026-02-09-suitbuilder-architecture.md
- Document spell bitmap system, locked slots, suit summary, and SSE streaming
- Add future enhancement roadmap (spell improvements, new builders, advanced features)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 08:44:00 +00:00

233 lines
8.9 KiB
Markdown

# 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