Skip to main content

Meta-Build System

The meta-build system aggregates top-performing talent builds from Warcraft Logs (WCL) and provides per-character build classification via SimulationCraft. It answers two questions: "what are the current best builds?" and "what kind of build is this character running?"

Architecture Overview

flowchart TD
subgraph API["NestJS API"]
direction TB
sync["POST /admin/sync-meta-builds"] --> svc[MetaBuildSyncService]
active["GET /admin/sync-meta-builds/active"] --> svc
query["GET /meta-builds"] --> db[(MetaBuild table)]
enc["GET /encounters/:id/meta-builds"] --> db
inst["GET /instances/:id/meta-builds"] --> db
classify["POST /characters/:id/classify-build"] --> simq[SimC Queue]
classifyAll["POST /characters/:id/classify-all-builds"] --> simq
admin["POST /admin/meta-builds"] --> db
guild["POST /organizations/:id/meta-builds"] --> db
end
svc -->|WebSocket| ws["/meta-build-sync namespace<br/>(sync-progress, sync-complete)"]

Data Model

MetaBuild

Each row represents a single popular talent build for a given spec and content type.

FieldDescription
idUUID
specIdBlizzard specialization ID
specNameHuman-readable spec name
classNameWoW class name
nameBuild label (e.g. "Top Patchwerk")
contentTyperaid or mythic_plus
encounterIdBlizzard encounter ID (raid builds)
instanceIdBlizzard instance ID (dungeon builds)
talentLoadoutCodeBlizzard-encoded talent string or fingerprint fallback
talentNodeIdsSorted array of selected talent node IDs
sourcewarcraftlogs, admin, or guild
sourceUrlWCL link to source data
sourceCharactername-realm of representative character
popularityFloat — relative popularity score
sampleSizeNumber of parses in WCL sample
organizationIdNull for global builds, set for guild-scoped
patchVersionWoW patch version string
isActiveSoft-delete flag

MetaBuildSyncSession

Tracks sync progress, following the standard sync session pattern.

FieldDescription
statusrunning, completed, failed
totalSpecsTotal specializations to process
processedSpecsSpecs completed so far
totalQueriesTotal WCL queries to run
processedItemsQueries completed so far
buildsUpsertedTotal builds upserted during sync
triggeredByadmin or scheduler

Talent Fingerprinting

WCL returns talent builds as arrays of node IDs — not Blizzard loadout codes. The system resolves these through two paths:

  1. Loadout encoding (preferred): Uses GDL talent tree data to encode node IDs into a valid Blizzard talentLoadoutCode via encodeTalentLoadout().
  2. Fingerprint fallback: When encoding fails (incomplete tree data, hero spec mismatch), generates a SHA-256 fingerprint of the sorted node IDs (first 16 hex characters).

Fingerprinted builds cannot be simulated directly — they must be resolved to a real loadout code first.

flowchart LR
A["buildTalentFingerprint([101, 203, 305])"] --> B["sort → [101, 203, 305]"]
B --> C["join → '101-203-305'"]
C --> D["SHA-256 → first 16 hex chars"]
D --> E["'a1b2c3d4e5f6a7b8'"]

isTalentFingerprint(code) checks if a string matches /^[0-9a-f]{16}$/ — used to reject fingerprints from simulation queues.

Build Aggregation

aggregateBuilds() groups raw WCL results by fingerprint:

  • Groups builds with identical talent selections
  • Sums player counts and averages DPS
  • Keeps the highest-DPS character as representative
  • Sorts groups by player count (popularity) descending

WCL Sync Flow

Triggered by POST /admin/sync-meta-builds or cron (Mondays 06:00).

  1. Create MetaBuildSyncSession with status running
  2. Load all specs from GDL listTalentTrees()
  3. Load current raid instances and M+ dungeons from GDL
  4. Map M+ dungeons to WCL encounter IDs via getMythicPlusDungeonEncounters()
  5. For each spec × encounter/dungeon:
    • Fetch top builds from WCL (getTopBuildsForEncounter / getTopBuildsForDungeon)
    • aggregateBuilds() to group by fingerprint
    • resolveLoadoutCodes() to convert node IDs → Blizzard loadout codes
    • Upsert MetaBuild rows
  6. Emit progress via WebSocket (/meta-build-sync namespace)
  7. Mark session completed

Build Classification

Build classification determines whether a talent loadout is optimized for single-target, cleave, or AoE via SimulationCraft.

Classification Profiles

Each loadout is simulated against three fight scenarios:

ProfileFight StyleDuration
Sustained STPatchwerk300s
Multi-targetDungeonSlicedefault
Burst STPatchwerk60s

Classification Logic

flowchart TD
A["ratio = DungeonSlice DPS / Patchwerk 300s DPS"] --> B{"buildType"}
B -->|"ratio < 1.05"| C[singleTarget]
B -->|"ratio 1.05–1.15"| D[cleave]
B -->|"ratio > 1.15"| E[aoe]

F["burst ratio = Patchwerk 60s / Patchwerk 300s"] --> G{"isBurst"}
G -->|"> 1.2"| H[true]
G -->|"≤ 1.2"| I[false]

Results are stored in BuildClassification and cached on the character's loadout data.

Classification Endpoints

MethodPathDescription
POST/characters/:id/classify-buildClassify one loadout
POST/characters/:id/classify-all-buildsClassify all loadouts

Both reject talent fingerprints and validate loadout codes against GDL before queueing.

API Endpoints

Public

MethodPathDescription
GET/meta-buildsFilter by specId, contentType, encounterId, instanceId
GET/encounters/:id/meta-buildsBuilds for a specific boss
GET/instances/:id/meta-buildsBuilds for a dungeon

Admin

MethodPathDescription
POST/admin/meta-buildsCreate a build manually
DELETE/admin/meta-builds/:idSoft-delete a build
POST/admin/sync-meta-buildsTrigger WCL sync
GET/admin/sync-meta-builds/activeCheck active sync session

Guild-Scoped

MethodPathDescription
POST/organizations/:orgId/meta-buildsGuild officer adds build
DELETE/organizations/:orgId/meta-builds/:idGuild officer removes

Frontend Integration

RTK Query

  • useClassifyBuildMutation — classify a single loadout
  • useClassifyAllBuildsMutation — classify all loadouts for a character
  • useGetMetaBuildsQuery — fetch meta-builds with filters

WebSocket Hooks

  • useMetaBuildSync(sessionId) — subscribe to sync progress on /meta-build-sync namespace
  • useBuildClassification(jobId) — subscribe to classification result on /sim-sync namespace
  • useBatchClassification(jobIds) — track multiple classification jobs, fires onComplete when all finish

Cron Schedule

JobScheduleDescription
Meta-build sync0 6 * * 1Mondays at 06:00 UTC