Architecture
Data Flow
Section titled “Data Flow”The following diagram shows the complete data flow from user input to simulation results:
USER PASTES SimC addon export string │ ▼┌─────────────────────────────────────────┐│ parser.ts (frontend, pure TypeScript) ││ SimC string → SimcProfile ││ • Extracts character metadata, talents ││ • Parses equipped gear (isEquipped: true) ││ • Parses bag items (isEquipped: false) │└──────────────┬──────────────────────────┘ │ SimcProfile ▼┌─────────────────────────────────────────┐│ GEAR & OPTIMIZATION PANEL (React UI) ││ • GearSlotCard per slot ││ • GemSelector / EnchantSelector ││ • ItemSearch for unowned gear ││ • SimSettings panel │└──────────────┬──────────────────────────┘ │ user selections ▼┌─────────────────────────────────────────┐│ optimization-assembler.ts ││ Collects OptimizationAxis[] from all ││ UI sections. Exposes live combo count. │└──────────────┬──────────────────────────┘ │ OptimizationAxis[] ▼┌─────────────────────────────────────────┐│ combinator.ts (pure function) ││ Cartesian product of all axes ││ → CombinationSpec[] ││ Enforces 1000-combination hard cap │└──────────────┬──────────────────────────┘ │ CombinationSpec[] ▼┌─────────────────────────────────────────┐│ profileset-builder.ts (pure function) ││ CombinationSpec[] + SimcProfile ││ + SimSettings → .simc file string │└──────────────┬──────────────────────────┘ │ .simc content ▼┌─────────────────────────────────────────┐│ Tauri IPC: invoke("run_top_gear") ││ → run_simc.rs (Rust, async) ││ 1. Write .simc to temp file ││ 2. Spawn SimC sidecar ││ 3. Read json2 output ││ 4. Clean up temp files │└──────────────┬──────────────────────────┘ │ json2 output ▼┌─────────────────────────────────────────┐│ parseSimCResults() (frontend) ││ json2 + manifest → SimResult[] ││ Sorted by DPS descending │└──────────────┬──────────────────────────┘ │ SimResult[] ▼┌─────────────────────────────────────────┐│ RESULTS TABLE (React UI) ││ Ranked by DPS with delta vs equipped │└─────────────────────────────────────────┘Key Architecture Rules
Section titled “Key Architecture Rules”-
combinator.tsandprofileset-builder.tsare pure functions — no I/O, no side effects, fully testable without Tauri. -
All SimC knowledge lives in
docs/, not in code comments. Code is clean; docs explain the why. -
season-config.tsis the only file edited for seasonal updates — no other file should contain season-specific IDs or ilvl values. -
The SimC binary exit code is not reliable — always check whether the json2 output file exists rather than checking
exit_code == 0. SimC exits 1 on warnings even for successful simulations. -
Gem axes are conditional — they have a
parentItemIdand only participate in combinations where that item is selected. -
ProfileSet parallel mode is always enabled via
profileset_work_threads=2.
No HTTP Backend
Section titled “No HTTP Backend”WoW Gear Sim has no separate backend server. All “backend” logic runs as Tauri commands in Rust, called from TypeScript via invoke(). This eliminates port conflicts, firewall issues, and the “is the server running?” problem.
// Frontend calls Rust directly via IPCconst result = await invoke<string>('run_top_gear', { simcContent });Item Search Architecture
Section titled “Item Search Architecture”User types in search box (debounced 400ms) │ ├──► SQLite FTS5 query on items.db (instant, offline) │ └──► Wowhead search API (parallel, online)
Results merged, deduplicated by item_id, up to 10 shownUser selects item → gear track picker appearsTrack → bonus_id from GEAR_TRACKS in season-config.tsFinal SimC line: slot=,id=ITEM_ID,bonus_id=TRACK_BONUS_IDSeason Config Architecture
Section titled “Season Config Architecture”All season-specific data flows from a single file:
src/lib/presets/season-config.ts │ ├── GEAR_TRACKS → ItemSearch track picker ├── GEM_PRESETS → GemSelector dropdowns ├── ENCHANT_PRESETS → EnchantSelector dropdowns ├── SOCKET_BONUS_ID → "Assume socket" checkbox └── CURRENT_SEASON → build scriptsValidation: pnpm season:validate (run before every release).