Skip to content

Design Decisions

This page logs every non-obvious decision made during development.

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 + .exe automatically

Rejected: Electron (too heavy), Docker (alien to non-technical users), raw install guide (too many failure points)

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

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, …)

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

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

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)

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.

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.

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

Decision: pnpm as the package manager.

Why: Faster installs, better monorepo support, works well with Vite + Tauri.

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.