Metrics ignores match records, so it can't show matches started or group sizes per map #138

Closed
opened 2026-10-10 14:33:49 -04:00 by goddard · 1 comment
Collaborator

Metrics measures demand only as player-hours, although every match is recorded with its map and players. Operators can't see how many groups played a map or how big they were.

  • fleet/metrics.ts:76-81,297-303 readMetrics reads only metric_samples (and registered names at fleet/metrics.ts:96-102). It never reads leaderboard_matches or leaderboard_match_players.
  • metrics.ts:101-120 MetricsData has no match fields, so neither the summary nor the maps table can show them.
  • On live, 265 matches started in the last 7 days across 19 maps, and 116 of them (44%) were solo.

Player-hours can't tell one four-player group playing for two hours from four solo players. Matches started per map is the demand that each empty spare lobby exists to serve.

Screenshots

Same preview data as #137. Match counts come from the fixture's match records.

Before, summary cards:
Before

After (mockup), matches started:
After (mockup)

Before, maps table:
Before

After (mockup), Matches column:
After (mockup)

Fix

  • Add a matches-started card with average group size and solo share
  • Add a Matches column, with average group size, to the maps table
  • Apply the report's range, game and map filters to the match counts
  • Document the new measures in metrics.md
Metrics measures demand only as player-hours, although every match is recorded with its map and players. Operators can't see how many groups played a map or how big they were. - `fleet/metrics.ts:76-81,297-303` `readMetrics` reads only `metric_samples` (and registered names at `fleet/metrics.ts:96-102`). It never reads `leaderboard_matches` or `leaderboard_match_players`. - `metrics.ts:101-120` `MetricsData` has no match fields, so neither the summary nor the maps table can show them. - On live, 265 matches started in the last 7 days across 19 maps, and 116 of them (44%) were solo. Player-hours can't tell one four-player group playing for two hours from four solo players. Matches started per map is the demand that each empty spare lobby exists to serve. **Screenshots** Same preview data as #137. Match counts come from the fixture's match records. Before, summary cards: ![Before](https://gitea.thewrightserver.net/attachments/8962989c-a1c8-46d1-9240-56b67f6d315e) After (mockup), matches started: ![After (mockup)](https://gitea.thewrightserver.net/attachments/5e307eae-93fa-4615-86fd-f0108fc54978) Before, maps table: ![Before](https://gitea.thewrightserver.net/attachments/e410e69e-4694-48c2-83d0-f49375971beb) After (mockup), Matches column: ![After (mockup)](https://gitea.thewrightserver.net/attachments/ab5a3bf6-27bf-4ca0-a49c-eada4ae8c807) **Fix** - [x] Add a matches-started card with average group size and solo share - [x] Add a Matches column, with average group size, to the maps table - [x] Apply the report's range, game and map filters to the match counts - [x] Document the new measures in `metrics.md`
goddard added the
priority
low
type/ux
labels 2026-10-10 14:33:49 -04:00
josh was assigned by goddard 2026-10-10 14:33:49 -04:00
Author
Collaborator

Reviewed 616b1937ed. All four fix items are done, so I'm closing this.

Checklist

  • Matches-started card. MetricsSummary.svelte:68 adds "Matches started" with the average group size, the solo count and the solo share. When some matches have no recorded players, the card says so ("Players recorded for X of Y matches"). On the autoscaled preview fixture it reads 268 matches, average group 2.4, 48 solo (17.9%). An independent SQL count over the same window gives the same totals.
  • Matches column. MetricsTables.svelte:26 adds a sortable Matches column with "avg group" under each count, and the row details add matches with recorded players and solo share. On the preview, Kino Der Toten shows 81 matches with an average group of 2.1.
  • Range, game and map filters. fleet/metrics.ts:270-279 limits matches to started_at within the report window and to the selected game and exact map_name. Participants are counted per match before maps are summed, so roster size never inflates the start count. Covered by "filters matches by game and exact recorded map label…" and "weights group sizes by matches and counts unique participants per match…".
  • Docs. metrics.md:33 adds "Matches and groups", covering what counts as a start, how distinct players are counted, how matches with no recorded players are handled, and match retention. The API section lists the new fields. I checked the retention claims: matchKeepDays defaults to 0, meaning kept indefinitely, under Matches & players (fleet-settings.ts:50,219-222), and expiry only applies to completed or interrupted matches (retention.ts:146-150).

Review notes

  • Good extra work: maps that only have match history now appear in the filter options (fleet/metrics.ts:210) and in the table. Migration 14 refreshes cached reports when matches or participants change but ignores score and heartbeat updates (revisions.ts:4). The empty table state now tells "no history in this window" apart from "no search results".
  • The map join relies on match records and occupancy samples using the same label. Both come from selectedZombieMap(...).friendly (leaderboard-ingest.ts:35-45 and worker.ts). On live, all 19 map labels in the 577 saved matches exactly match the 19 occupancy labels, so no map will split into two rows.
  • The four-card summary fits at 1440 px and stacks cleanly at 390 px on the preview.
  • npm run check is clean. The 8 metrics test files pass locally (105 tests), and so do the 23 leaderboard, match, retention and telemetry test files (283 tests), which exercise the new triggers.
  • Minor and non-blocking: About this report now says "Occupancy history defaults to 31 days" (+page.svelte:404). That's no longer wrong, but it still doesn't show the configured value, so #141 stays open.
Reviewed 616b1937edaab482cfadc973f6f484d5d0b60e3a. All four fix items are done, so I'm closing this. **Checklist** - [x] **Matches-started card.** `MetricsSummary.svelte:68` adds "Matches started" with the average group size, the solo count and the solo share. When some matches have no recorded players, the card says so ("Players recorded for X of Y matches"). On the autoscaled preview fixture it reads 268 matches, average group 2.4, 48 solo (17.9%). An independent SQL count over the same window gives the same totals. - [x] **Matches column.** `MetricsTables.svelte:26` adds a sortable Matches column with "avg group" under each count, and the row details add matches with recorded players and solo share. On the preview, Kino Der Toten shows 81 matches with an average group of 2.1. - [x] **Range, game and map filters.** `fleet/metrics.ts:270-279` limits matches to `started_at` within the report window and to the selected `game` and exact `map_name`. Participants are counted per match before maps are summed, so roster size never inflates the start count. Covered by "filters matches by game and exact recorded map label…" and "weights group sizes by matches and counts unique participants per match…". - [x] **Docs.** `metrics.md:33` adds "Matches and groups", covering what counts as a start, how distinct players are counted, how matches with no recorded players are handled, and match retention. The API section lists the new fields. I checked the retention claims: `matchKeepDays` defaults to 0, meaning kept indefinitely, under Matches & players (`fleet-settings.ts:50,219-222`), and expiry only applies to completed or interrupted matches (`retention.ts:146-150`). **Review notes** - Good extra work: maps that only have match history now appear in the filter options (`fleet/metrics.ts:210`) and in the table. Migration 14 refreshes cached reports when matches or participants change but ignores score and heartbeat updates (`revisions.ts:4`). The empty table state now tells "no history in this window" apart from "no search results". - The map join relies on match records and occupancy samples using the same label. Both come from `selectedZombieMap(...).friendly` (`leaderboard-ingest.ts:35-45` and `worker.ts`). On live, all 19 map labels in the 577 saved matches exactly match the 19 occupancy labels, so no map will split into two rows. - The four-card summary fits at 1440 px and stacks cleanly at 390 px on the preview. - `npm run check` is clean. The 8 metrics test files pass locally (105 tests), and so do the 23 leaderboard, match, retention and telemetry test files (283 tests), which exercise the new triggers. - Minor and non-blocking: About this report now says "Occupancy history defaults to 31 days" (`+page.svelte:404`). That's no longer wrong, but it still doesn't show the configured value, so #141 stays open.
Sign in to join this conversation.