Open
Conversation
Made-with: Cursor
Made-with: Cursor
Adds a SimDaddy-style first-person combat replay visualiser as a ResultComponent that reacts to the shared resultsEmitter — consistent with Timeline and LogRunner. Features: - Arena with Patchwerk boss silhouette, floating nameplates and HP bars - Spell cast ticker strip (last 10 casts) with DOM recycling and image preload cache to prevent layout reflows on each new spell - Hit effects: flash, ring and floating damage numbers on boss - CDM HUD: player name, cast bar, resource bars (MoP resource types including Chi, Solar/Lunar Energy), action icon grid with glow on cast - Playback controls: play/pause, 1x/2x/3x speed, scrubber, seek buttons - Stops and resets playback when the Replay tab is hidden Made-with: Cursor
Dark-theme scene styles for the combat replay arena, ticker strip, enemy cards, CDM HUD (cast bar, resource bars, action grid) and playback controls. Made-with: Cursor
Adds a 'Replay' tab between Timeline and Log. Instantiates CombatReplay against the shared resultsEmitter; wires hide.bs.tab to stop playback when the user navigates away. Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
…hide Health Made-with: Cursor
…th dot segments Made-with: Cursor
Made-with: Cursor
- Add combat_replay block to translation.schema.json (fixes CI test failure) - Show active player buffs as small icons in CDM header row - Show active target debuffs as small icons under enemy HP bar - Wowhead tooltips on all aura icons via setWowheadDataset - Deduplicated aura rendering with key-based reconciliation to avoid per-frame DOM thrash Made-with: Cursor
- parseResult and buildScene now accept SimResultFilter - Enemies rendered from result.getTargets(filter) so dropdown selection is honoured - Hit effects skip targets outside the filtered set - Debuff rendering maps card index -> encounter index via filteredTargetEncounterIndices - Player entity and label resolved via result.getPlayers(filter) Made-with: Cursor
…ps fire tooltips.js (zamimg) hooks into <a href="...wowhead..."> elements. All icon slots (ticker, action grid, buff/debuff) now use <a> elements with setBackgroundAndHref (background-image + href) + setWowheadDataset, matching the pattern used in metrics_table and timeline. Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
Aura logs are emitted as "[entity] gained [aura]" where entity is the RECEIVER, not the caster. Debuffs on targets therefore have source = target entity, not player entity. Calling fromLogs(logs, playerEntity) was finding player-received buffs only and missing all target debuffs. Fix: use the pre-computed UnitMetrics.auraUptimeLogs which correctly uses each unit's own log subset and entity reference: - players[0].auraUptimeLogs -> player buffs - filteredTargets[i].auraUptimeLogs -> per-target debuffs Made-with: Cursor
…faults Made-with: Cursor
Replaces flat flex row with a perspective-depth formation: - Front row: ceil(n/2) targets, full size, bottom-aligned - Back row: remaining targets, scale(0.62), pushed up 14%, brightness(0.6) - All cards absolutely positioned so they naturally overlap - Back row rendered first (lower z-index) so front targets overlap them - Card width scales with target count to prevent overflow at any N Made-with: Cursor
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
1337LutZ
reviewed
Apr 7, 2026
- Enemy cards: build with tsx-vanilla refs; track hp/debuff/hit layer in enemyCardDom[] - Hit effects: makeHitEffectRoot as TSX; DocumentFragment + replaceChildren per target - Hit rings: outcome classes + --bs-hit / --bs-crit (timeline-aligned) - Resources: RESOURCE_PRIORITY const; JSX rows + replaceChildren (no innerHTML strings) - Action grid: Map actionIconByKey instead of querySelectorAll - Auras: fragment + ref-based <a> icons; replaceChildren - Play/pause: Font Awesome fa-play / fa-pause class toggle - formatReplayTime (renamed from fmt); player label ref - encodeHTMLEntities() helper in utils.ts Made-with: Cursor
1337LutZ
reviewed
Apr 9, 2026
1337LutZ
reviewed
Apr 9, 2026
1337LutZ
reviewed
Apr 9, 2026
1337LutZ
reviewed
Apr 9, 2026
1337LutZ
reviewed
Apr 9, 2026
1337LutZ
reviewed
Apr 9, 2026
1337LutZ
reviewed
Apr 9, 2026
1337LutZ
reviewed
Apr 9, 2026
1337LutZ
reviewed
Apr 9, 2026
There was a problem hiding this comment.
Please double check all color hex/rgba usages and replace them with --bs-* css vars
1337LutZ
reviewed
Apr 9, 2026
1337LutZ
reviewed
Apr 17, 2026
| const dmgLogs: DamageDealtLog[] = []; | ||
| const resourceLogs: ResourceChangedLog[] = []; | ||
|
|
||
| for (const log of result.logs) { |
There was a problem hiding this comment.
This can be simplified without typecasting:
for (const log of result.logs) {
if (log.timestamp < 0) continue;
if (log.isCastBegan()) castBeganLogs.push(log);
else if (log.isDamageDealt()) dmgLogs.push(log);
else if (log.isResourceChanged()) resourceLogs.push(log);
}
1337LutZ
reviewed
Apr 17, 2026
| const players = result.getPlayers(filter); | ||
| const playerEntity = players[0] ? new Entity(players[0].name, '', players[0].index, false, false) : null; | ||
|
|
||
| const castBeganLogs: CastBeganLog[] = []; |
There was a problem hiding this comment.
Add const actionMetrics = result.getActionMetrics(filter); above
1337LutZ
reviewed
Apr 17, 2026
| const isRealSpell = (c: CastBeganLog): boolean => { | ||
| const id = c.actionId; | ||
| if (!id) return false; | ||
| if (id.otherId !== OtherAction.OtherActionNone) return false; |
There was a problem hiding this comment.
Add if (actionMetrics.find(m => m.actionId?.equals(id))?.isPassiveAction) return false to filter passive actions as they shouldn't show as "cast" spells
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Replay tab to the
DetailedResultspanel, positioned between the Timeline and Log tabs.The tab uses the same shared
resultsEmitteras Timeline and LogRunner — no separate simulation button is needed; the replay automatically populates after any sim run.Playback stops and resets when the user navigates away from the tab.
Implementation
CombatReplaycomponent (ui/core/components/detailed_results/combat_replay.tsx):ResultComponent, receives data viaonSimResult()for full consistency with the rest of the results panelactionId.setWowheadDataset()Other changes:
assets/img/boss_patchwerk.png— Patchwerk boss silhouetteui/scss/core/components/detailed_results/_combat_replay.scss— dark-theme stylesenandfrlocalesTest plan