The Instances tab groups utilization by server name. Autoscaling reuses lobby numbers, so the tab fills with "Historical" names, and each number mixes many unrelated lobbies.
MetricsTables.svelte:31-37,274 lists one row per recorded name and marks unregistered names "Historical". It sorts by time with players by default (MetricsTables.svelte:57).
autoscaling.md:20 says each create takes the lowest free lobby number from 1 to 20, so "Lobby 2" is a different lobby each time a map scales up.
On live, the last 7 days have 51 rows for 21 registered servers. 30 are "Historical", including t5_zombie_theater_3 through t5_zombie_theater_15.
On a quiet map, Lobby 2 is the spare by construction, so its row reads 0% with players. In the preview, every quiet map's Lobby 2 does.
Per-name utilization describes the autoscaler's numbering rather than anything an operator can act on, which is why metrics.md:37-40 and +page.svelte:390-393 have to explain the caveat.
Remove the Instances tab; per-lobby history stays on server pages
Add average and peak lobbies and empty lobby-hours per map to the maps table
Remove the grouped-by-name text from About (+page.svelte:390-393) and metrics.md:37-40
The Instances tab groups utilization by server name. Autoscaling reuses lobby numbers, so the tab fills with "Historical" names, and each number mixes many unrelated lobbies.
- `MetricsTables.svelte:31-37,274` lists one row per recorded name and marks unregistered names "Historical". It sorts by time with players by default (`MetricsTables.svelte:57`).
- `autoscaling.md:20` says each create takes the lowest free lobby number from 1 to 20, so "Lobby 2" is a different lobby each time a map scales up.
- On live, the last 7 days have 51 rows for 21 registered servers. 30 are "Historical", including `t5_zombie_theater_3` through `t5_zombie_theater_15`.
- On a quiet map, Lobby 2 is the spare by construction, so its row reads 0% with players. In the preview, every quiet map's Lobby 2 does.
Per-name utilization describes the autoscaler's numbering rather than anything an operator can act on, which is why `metrics.md:37-40` and `+page.svelte:390-393` have to explain the caveat.
**Screenshots**
Same preview data as #137.
Before, Instances tab:

After (mockup), lobby columns on the maps table:

**Fix**
- [x] Remove the Instances tab; per-lobby history stays on server pages
- [x] Add average and peak lobbies and empty lobby-hours per map to the maps table
- [x] Remove the grouped-by-name text from About (`+page.svelte:390-393`) and `metrics.md:37-40`
Reviewed aebfc7a783. All three fix items are done, so I'm closing this.
Checklist
Instances tab removed. The tabs are now Maps and Autoscaling signals (+page.svelte:315). MetricsTables.svelte no longer has instance columns, search, sorting or paging. An old ?view=instances link falls back to Maps (+page.svelte:43), which I confirmed on the preview.
Lobby counts per map.fleet/metrics.ts:457 adds each map's lobby count per collection to a per-map running total. MetricsTables.svelte:23,175 shows it as "Lobbies (avg · peak)", with empty lobby-hours underneath, sorted by the average. The row details add captured map time and empty lobby-hours. On the autoscaled preview fixture, Kino Der Toten reads 1.5 · 3 with 160.8 h empty, and Moon reads 1.1 · 2. A separate calculation from the raw samples gives the same averages, peaks and empty hours. Covered by "counts concurrent lobbies per recorded game/map across reused names, clipped intervals and collection gaps".
Grouped-by-name text removed. About this report now describes the per-map lobby counts instead (+page.svelte:411). In metrics.md, the instance-rows paragraph is replaced by a description of the new column (metrics.md:76).
Review notes
On the preview, the seven-column table fits at 1440 px. At 390 px it scrolls inside its own keyboard-reachable region, and the page itself doesn't scroll sideways.
npm run check is clean, and the 8 metrics test files pass locally (109 tests).
Minor and non-blocking: the report still builds a per-name servers row for every lobby name, and background refresh still validates them. The page only uses their count, to choose the empty-state wording (+page.svelte:260,267), so a count or boolean would do. changeScope and rangeHref still delete an old serverPage parameter (+page.svelte:168,193), which only tidies stale URLs.
Reviewed aebfc7a78359da4547a5a85d42350ca0311cde79. All three fix items are done, so I'm closing this.
**Checklist**
- [x] **Instances tab removed.** The tabs are now Maps and Autoscaling signals (`+page.svelte:315`). `MetricsTables.svelte` no longer has instance columns, search, sorting or paging. An old `?view=instances` link falls back to Maps (`+page.svelte:43`), which I confirmed on the preview.
- [x] **Lobby counts per map.** `fleet/metrics.ts:457` adds each map's lobby count per collection to a per-map `running` total. `MetricsTables.svelte:23,175` shows it as "Lobbies (avg · peak)", with empty lobby-hours underneath, sorted by the average. The row details add captured map time and empty lobby-hours. On the autoscaled preview fixture, Kino Der Toten reads 1.5 · 3 with 160.8 h empty, and Moon reads 1.1 · 2. A separate calculation from the raw samples gives the same averages, peaks and empty hours. Covered by "counts concurrent lobbies per recorded game/map across reused names, clipped intervals and collection gaps".
- [x] **Grouped-by-name text removed.** About this report now describes the per-map lobby counts instead (`+page.svelte:411`). In `metrics.md`, the instance-rows paragraph is replaced by a description of the new column (`metrics.md:76`).
**Review notes**
- On the preview, the seven-column table fits at 1440 px. At 390 px it scrolls inside its own keyboard-reachable region, and the page itself doesn't scroll sideways.
- `npm run check` is clean, and the 8 metrics test files pass locally (109 tests).
- Minor and non-blocking: the report still builds a per-name `servers` row for every lobby name, and background refresh still validates them. The page only uses their count, to choose the empty-state wording (`+page.svelte:260,267`), so a count or boolean would do. `changeScope` and `rangeHref` still delete an old `serverPage` parameter (`+page.svelte:168,193`), which only tidies stale URLs.
ServerMetrics and the per-name rows are gone. readMetrics now returns sampledServerCount, a count of distinct names in the same current-window samples that used to create rows, including names with no elapsed time. The empty state uses that count (+page.svelte:260,267), so its wording keeps the same meaning. registeredServerCount is now a single COUNT(*), and background refresh checks that the count is a non-negative integer instead of validating rows.
No metrics code still reads servers. On the autoscaled preview fixture, sampledServerCount is 25, matching both the 25 rows the previous code built and a separate count of distinct names in the window. The 7-day report payload drops from 47.5 KB to 42.8 KB.
npm run check is clean, and the 8 metrics test files pass locally (116 tests), including the new "counts unknown heatmap evidence and sampled names independently of current registrations".
The serverPage deletes in changeScope and rangeHref (+page.svelte:168,193) remain. They only clear the parameter from old links, so they're fine to keep.
Reviewed 0bfda267ecd3b18d35aafb670b8a4cdb871ba41d. It resolves the non-blocking note from my last review, and all three fix items are still done, so this stays closed.
**Checklist**
- [x] **Instances tab removed.** Unchanged since aebfc7a.
- [x] **Lobby counts per map.** Unchanged.
- [x] **Grouped-by-name text removed.** Unchanged.
**Review notes**
- `ServerMetrics` and the per-name rows are gone. `readMetrics` now returns `sampledServerCount`, a count of distinct names in the same current-window samples that used to create rows, including names with no elapsed time. The empty state uses that count (`+page.svelte:260,267`), so its wording keeps the same meaning. `registeredServerCount` is now a single `COUNT(*)`, and background refresh checks that the count is a non-negative integer instead of validating rows.
- No metrics code still reads `servers`. On the autoscaled preview fixture, `sampledServerCount` is 25, matching both the 25 rows the previous code built and a separate count of distinct names in the window. The 7-day report payload drops from 47.5 KB to 42.8 KB.
- `npm run check` is clean, and the 8 metrics test files pass locally (116 tests), including the new "counts unknown heatmap evidence and sampled names independently of current registrations".
- The `serverPage` deletes in `changeScope` and `rangeHref` (`+page.svelte:168,193`) remain. They only clear the parameter from old links, so they're fine to keep.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The Instances tab groups utilization by server name. Autoscaling reuses lobby numbers, so the tab fills with "Historical" names, and each number mixes many unrelated lobbies.
MetricsTables.svelte:31-37,274lists one row per recorded name and marks unregistered names "Historical". It sorts by time with players by default (MetricsTables.svelte:57).autoscaling.md:20says each create takes the lowest free lobby number from 1 to 20, so "Lobby 2" is a different lobby each time a map scales up.t5_zombie_theater_3throught5_zombie_theater_15.Per-name utilization describes the autoscaler's numbering rather than anything an operator can act on, which is why
metrics.md:37-40and+page.svelte:390-393have to explain the caveat.Screenshots
Same preview data as #137.
Before, Instances tab:

After (mockup), lobby columns on the maps table:

Fix
+page.svelte:390-393) andmetrics.md:37-40Reviewed
aebfc7a783. All three fix items are done, so I'm closing this.Checklist
+page.svelte:315).MetricsTables.svelteno longer has instance columns, search, sorting or paging. An old?view=instanceslink falls back to Maps (+page.svelte:43), which I confirmed on the preview.fleet/metrics.ts:457adds each map's lobby count per collection to a per-maprunningtotal.MetricsTables.svelte:23,175shows it as "Lobbies (avg · peak)", with empty lobby-hours underneath, sorted by the average. The row details add captured map time and empty lobby-hours. On the autoscaled preview fixture, Kino Der Toten reads 1.5 · 3 with 160.8 h empty, and Moon reads 1.1 · 2. A separate calculation from the raw samples gives the same averages, peaks and empty hours. Covered by "counts concurrent lobbies per recorded game/map across reused names, clipped intervals and collection gaps".+page.svelte:411). Inmetrics.md, the instance-rows paragraph is replaced by a description of the new column (metrics.md:76).Review notes
npm run checkis clean, and the 8 metrics test files pass locally (109 tests).serversrow for every lobby name, and background refresh still validates them. The page only uses their count, to choose the empty-state wording (+page.svelte:260,267), so a count or boolean would do.changeScopeandrangeHrefstill delete an oldserverPageparameter (+page.svelte:168,193), which only tidies stale URLs.Reviewed
0bfda267ec. It resolves the non-blocking note from my last review, and all three fix items are still done, so this stays closed.Checklist
aebfc7a.Review notes
ServerMetricsand the per-name rows are gone.readMetricsnow returnssampledServerCount, a count of distinct names in the same current-window samples that used to create rows, including names with no elapsed time. The empty state uses that count (+page.svelte:260,267), so its wording keeps the same meaning.registeredServerCountis now a singleCOUNT(*), and background refresh checks that the count is a non-negative integer instead of validating rows.servers. On the autoscaled preview fixture,sampledServerCountis 25, matching both the 25 rows the previous code built and a separate count of distinct names in the window. The 7-day report payload drops from 47.5 KB to 42.8 KB.npm run checkis clean, and the 8 metrics test files pass locally (116 tests), including the new "counts unknown heatmap evidence and sampled names independently of current registrations".serverPagedeletes inchangeScopeandrangeHref(+page.svelte:168,193) remain. They only clear the parameter from old links, so they're fine to keep.