Vigil
← All news

v1.10.0 — job-filterable DPS comparison (your static vs the field)

Ship 3 of 3 in the consumer-side push. T-204 `dps_check_for_encounter` already aggregates per-phase raid DPS across kills, but it pools everything (ours + field together) and ther…

Why

Ship 3 of 3 in the consumer-side push. T-204 dps_check_for_encounter already aggregates per-phase raid DPS across kills, but it pools everything (ours + field together) and there's no job-level granularity. The consumer goal was: "compare median total DPS of public vs your own static, filter down to your job if you want". v1.10.0 delivers both — static-split distributions and an optional per-job narrowing.

Added — dps_comparison_for_encounter()

  • New function in analysis/dps_check.py. Splits per-phase DPS into ours (kills from reports in the static's watchlist) vs field (everything else), using the same watchlist-scoping rule as v1.8.0 cartography and v1.9.0 mit aggregate.
  • Without job: each kill contributes one value (raid DPS = phase total damage / duration). Top-line "where do we sit vs the field" view.
  • With job (e.g. "SAM"): contributes one value per matching player per kill. Two SAMs in one kill = two data points. Per-player-DPS distribution that answers "where does our SAM sit vs all SAMs that have cleared".
  • Returns jobs_available (every job seen across both sides) so the Home dropdown doesn't need a second roundtrip.
  • Quartile shape reuses the existing _quartiles helper (n=1 returns all-equal degenerate; ≥2 uses inclusive quantiles).

Added — GET /api/encounters/{id}/dps-comparison?job=<job>

  • Context-scoped. Default no-job returns raid-DPS comparison.

Added — Home section "Your DPS vs the field"

  • New DpsComparisonSection in web/src/Home.jsx, placed after fault contributors.
  • Job dropdown in the section header: All jobs (raid DPS) default + every job seen.
  • Table per phase: Our median · Field p25 · Field median · Field p75 · Δ vs median (percent delta of our median vs field's, color-graded green ≥0 / yellow -10..0 / red <-10).
  • Sample-size hint (n=N) on our column when ≥2 kills aggregated, since one kill is noisy.
  • Two empty states: (a) no kills anywhere in the encounter → "field comparison activates once kill data exists"; (b) job filter produces no rows for one side → friendly note.
  • formatDps() helper renders 27.3k-style numbers; tabular numerics for clean column alignment.

Tests

  • 6 new in tests/test_dps_comparison.py: empty-encounter zero shape; two-kill ours+field split (correct raid-DPS for both sides); job filter narrows to per-player DPS; non-matching jobs excluded (ours side empty when no PCT among ours); jobs_available reflects both sides; static with no watched kills sees only field.
  • 419 tests passing (413 → 419, +6).

Consumer-side push complete

Three ships landed in one session per the plan stated up front: v1.8.0 (Home dashboard), v1.9.0 (mit aggregate), v1.10.0 (job DPS comparison). Non-dev Home now has five vertical sections: encounter picker · Where we are (prog curve) · What's killing us (top wipe mechanics) · How mit usage is going · Who's contributing to wipes · Your DPS vs the field. Together they answer the consumer questions stated this session: "keep inputting reports", "graph progress", "what gimmick are we wiping to", "who's contributing to wipes", "mit being applied or not", "median DPS vs field optionally per job".

No schema change. No new env vars.