Design Decisions
This page logs every non-obvious decision made during development.
Tauri Instead of Electron or Docker
Section titled “Tauri Instead of Electron or Docker”Decision: Desktop app via Tauri 2.x.
Why:
- Target users are WoW gamers — comfortable with installers, not terminals or Docker
- Tauri bundles the SimC sidecar and React UI into a single native installer
- Smaller binary footprint than Electron (~5-15MB vs ~150MB)
- GitHub Actions produces
.dmg+.exeautomatically
Rejected: Electron (too heavy), Docker (alien to non-technical users), raw install guide (too many failure points)
No HTTP Backend — Tauri IPC Only
Section titled “No HTTP Backend — Tauri IPC Only”Decision: All backend logic implemented as Tauri commands in Rust. No Express/Hono server.
Why:
- Tauri already provides a message-passing bridge
- Eliminates port conflicts and firewall issues
- Simpler mental model: one process, not two
Sequential SimC Execution
Section titled “Sequential SimC Execution”Decision: Only one SimC process runs at a time.
Why:
- SimC itself is multi-threaded and uses all CPU cores
- Multiple instances cause CPU thrashing and slower results
- Sequential gives predictable progress (1/N, 2/N, …)
ProfileSet over N Sequential Processes
Section titled “ProfileSet over N Sequential Processes”Decision: All combinations in one .simc file using SimC’s profileset feature.
Why:
- Dramatically faster — SimC shares warm-up cost across profiles
- Statistically more consistent — same RNG seeds
- Simpler code — one process spawn instead of N
Combination Cap: 1000, Warning at 200
Section titled “Combination Cap: 1000, Warning at 200”Decision: Hard cap at 1000 combinations, warning above 200.
Why:
- At 10k iterations, each sim takes 5–30s. 1000 combos could be 8+ hours
- Users don’t always understand combinatorial explosion
- The UI shows live combo count to prevent surprises
Enchant Inheritance for Bag Items
Section titled “Enchant Inheritance for Bag Items”Decision: When a bag item lacks an enchant_id, inherit from the equipped item in that slot.
Why:
- Users expect alternatives to be simulated with enchants applied
- An unenchanted bag item would simulate artificially low
- Matches standard Sim Gear behavior (as seen in other simulators)
Gem Axes Are Per-Item, Not Per-Slot
Section titled “Gem Axes Are Per-Item, Not Per-Slot”Decision: Gem OptimizationAxis instances have a parentItemId and only apply in combinations where that item is selected.
Why: Different items in the same slot can have different socket counts. Item A might have 1 socket while Item B has 2. Gem combinations must reflect each item’s actual socket layout.
SimC Exit Code 1 Is Not Always Failure
Section titled “SimC Exit Code 1 Is Not Always Failure”Decision: Don’t treat exit code 1 as an automatic failure.
Why: SimC exits 1 even on successful simulations when non-fatal warnings are present (e.g., unrecognized bonus_ids for newly added items). Instead, check whether the json2 output file exists and contains valid data.
Item Names from Wowhead, Not Blizzard API
Section titled “Item Names from Wowhead, Not Blizzard API”Decision: Fetch item names from Wowhead XML API. Cache with 7-day TTL.
Why:
- No auth required (unlike Blizzard API which needs OAuth)
- Returns item name, quality, and base ilvl
- Wowhead has been stable for 20 years
- Fallback: show “Item #ID” if offline. Names are cosmetic — sims work regardless
pnpm over npm/yarn
Section titled “pnpm over npm/yarn”Decision: pnpm as the package manager.
Why: Faster installs, better monorepo support, works well with Vite + Tauri.
Gear Track bonus_ids Ship as TBD
Section titled “Gear Track bonus_ids Ship as TBD”Decision: GEAR_TRACKS ships with bonusId: 0 placeholders until confirmed.
Why: bonus_ids are expansion/season-specific and not published in player-facing guides. Shipping wrong values would silently produce incorrect ilvl simulations, which is worse than a visible warning.