Skip to content

ProfileSet Builder

The ProfileSet builder is the most critical transformation in the app. It takes the combination specs, the base character profile, and simulation settings, and produces a single .simc file that SimC processes in one run.

The generated .simc file has four sections in order:

[1] Global sim options ← fight_style, max_time, iterations, threads
[2] Base character profile ← currently equipped gear, talents, etc.
[3] Enemy definitions ← enemy=add1, enemy=add2 (if >1 target)
[4] ProfileSet entries ← one per non-baseline combination

Scenario: 2 trinket options x 2 ring options x 2 enchants = 8 combos. The base (currently equipped) is not a profileset — the remaining 7 are.

# ── SECTION 1: Global options ──────────────────────────
fight_style=Patchwerk
max_time=300
vary_combat_length=0.2
iterations=10000
threads=7
process_priority=below_normal
output=nul
json2=/tmp/simc_out_abc.json
profileset_work_threads=2
# ── SECTION 2: Base character (currently equipped) ─────
shaman="Thrall"
level=80
race=orc
region=eu
server=draenor
spec=enhancement
talents=BYQAAAAAAAAAAAAAAAAAAAAAgUSShQSQJRSSJkQSJ...
head=,id=235602,bonus_id=...,gem_id=213743,enchant_id=7359
finger1=,id=235614,bonus_id=...,enchant_id=7340
trinket1=,id=235616,bonus_id=...
# ... all other slots ...
# ── SECTION 3: Enemies (only if num_enemies > 1) ──────
# (omitted in this example — single target)
# ── SECTION 4: ProfileSets ────────────────────────────
# combo_0001: trinket A + ring A + enchant Y
profileset."combo_0001"=finger1=,id=235614,bonus_id=...,enchant_id=7341
# combo_0002: trinket A + ring B + enchant X
profileset."combo_0002"=finger1=,id=229379,bonus_id=...,enchant_id=7340
# combo_0004: trinket B + ring A + enchant X
profileset."combo_0004"=trinket1=,id=225652,bonus_id=...
# combo_0005: trinket B + ring A + enchant Y (multiple override lines)
profileset."combo_0005"=trinket1=,id=225652,bonus_id=...
profileset."combo_0005"+=finger1=,id=235614,bonus_id=...,enchant_id=7341
  • First line uses = (not +=)
  • Subsequent lines for the same combo use +=
  • Name must be unique, no dots, enclosed in double quotes
  • Only include lines that differ from the base profile

Names follow the format combo_NNNN (zero-padded 4-digit index):

  • The base profile has no profileset entry — its DPS comes from sim.players[0]
  • combo_0001 through combo_9999 for profileset entries
  • Indexed names avoid SimC’s internal name buffer truncation issues

A manifest Map<string, CombinationSpec> is built alongside the file for parsing results back.

// Base DPS (currently equipped):
json.sim.players[0].collected_data.dps.mean
// ProfileSet results:
json.profilesets.results[i].mean // matched by name
json.profilesets.results[i].stddev
json.profilesets.results[i].mean_stddev

Always enabled via profileset_work_threads=2:

threads=T (from user config)
profileset_work_threads=2
→ floor(T/2) parallel workers
→ e.g., threads=8 → 4 workers × 2 threads each

When numEnemies > 1, add enemy definitions after the base profile and before profilesets:

enemy=add1
enemy=add2
enemy=add3

Two results are within statistical noise if their confidence intervals overlap:

function areWithinNoise(a: SimResult, b: SimResult): boolean {
return Math.abs(a.dps - b.dps) < 2 * Math.max(a.meanStdDev, b.meanStdDev);
}