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.
| Field | Description |
|---|---|
id | UUID |
specId | Blizzard specialization ID |
specName | Human-readable spec name |
className | WoW class name |
name | Build label (e.g. "Top Patchwerk") |
contentType | raid or mythic_plus |
encounterId | Blizzard encounter ID (raid builds) |
instanceId | Blizzard instance ID (dungeon builds) |
talentLoadoutCode | Blizzard-encoded talent string or fingerprint fallback |
talentNodeIds | Sorted array of selected talent node IDs |
source | warcraftlogs, admin, or guild |
sourceUrl | WCL link to source data |
sourceCharacter | name-realm of representative character |
popularity | Float — relative popularity score |
sampleSize | Number of parses in WCL sample |
organizationId | Null for global builds, set for guild-scoped |
patchVersion | WoW patch version string |
isActive | Soft-delete flag |
MetaBuildSyncSession
Tracks sync progress, following the standard sync session pattern.
| Field | Description |
|---|---|
status | running, completed, failed |
totalSpecs | Total specializations to process |
processedSpecs | Specs completed so far |
totalQueries | Total WCL queries to run |
processedItems | Queries completed so far |
buildsUpserted | Total builds upserted during sync |
triggeredBy | admin or scheduler |
Talent Fingerprinting
WCL returns talent builds as arrays of node IDs — not Blizzard loadout codes. The system resolves these through two paths:
- Loadout encoding (preferred): Uses GDL talent tree data to encode node IDs into a valid Blizzard
talentLoadoutCodeviaencodeTalentLoadout(). - 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).
- Create
MetaBuildSyncSessionwith statusrunning - Load all specs from GDL
listTalentTrees() - Load current raid instances and M+ dungeons from GDL
- Map M+ dungeons to WCL encounter IDs via
getMythicPlusDungeonEncounters() - For each spec × encounter/dungeon:
- Fetch top builds from WCL (
getTopBuildsForEncounter/getTopBuildsForDungeon) aggregateBuilds()to group by fingerprintresolveLoadoutCodes()to convert node IDs → Blizzard loadout codes- Upsert
MetaBuildrows
- Fetch top builds from WCL (
- Emit progress via WebSocket (
/meta-build-syncnamespace) - 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:
| Profile | Fight Style | Duration |
|---|---|---|
| Sustained ST | Patchwerk | 300s |
| Multi-target | DungeonSlice | default |
| Burst ST | Patchwerk | 60s |
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
| Method | Path | Description |
|---|---|---|
| POST | /characters/:id/classify-build | Classify one loadout |
| POST | /characters/:id/classify-all-builds | Classify all loadouts |
Both reject talent fingerprints and validate loadout codes against GDL before queueing.
API Endpoints
Public
| Method | Path | Description |
|---|---|---|
| GET | /meta-builds | Filter by specId, contentType, encounterId, instanceId |
| GET | /encounters/:id/meta-builds | Builds for a specific boss |
| GET | /instances/:id/meta-builds | Builds for a dungeon |
Admin
| Method | Path | Description |
|---|---|---|
| POST | /admin/meta-builds | Create a build manually |
| DELETE | /admin/meta-builds/:id | Soft-delete a build |
| POST | /admin/sync-meta-builds | Trigger WCL sync |
| GET | /admin/sync-meta-builds/active | Check active sync session |
Guild-Scoped
| Method | Path | Description |
|---|---|---|
| POST | /organizations/:orgId/meta-builds | Guild officer adds build |
| DELETE | /organizations/:orgId/meta-builds/:id | Guild officer removes |
Frontend Integration
RTK Query
useClassifyBuildMutation— classify a single loadoutuseClassifyAllBuildsMutation— classify all loadouts for a characteruseGetMetaBuildsQuery— fetch meta-builds with filters
WebSocket Hooks
useMetaBuildSync(sessionId)— subscribe to sync progress on/meta-build-syncnamespaceuseBuildClassification(jobId)— subscribe to classification result on/sim-syncnamespaceuseBatchClassification(jobIds)— track multiple classification jobs, firesonCompletewhen all finish
Cron Schedule
| Job | Schedule | Description |
|---|---|---|
| Meta-build sync | 0 6 * * 1 | Mondays at 06:00 UTC |