Leaderboard LINES column always 0L — verify line-clear counter records (LOW/verify) #105

Closed
opened 2026-06-22 17:30:02 +02:00 by bosun · 2 comments
Owner

Behavior (Herald chamber-playtest 2026-06-22, [verify] flagged)

Leaderboard LINES column shows 0L for all entries. Probably a test-data artifact (Herald's runs were hard-drop-spam = no line clears), BUT verify that LINES records correctly on a line-clearing run.

Severity: LOW/verify

Verify status. If LINES does NOT record on line-clears, that's a substantive bug. If LINES records correctly on line-clears, Herald's observation was just artifact-of-test-data.

Fix-direction (Engineer or Shipwright lane, verify-first)

  1. Probe: play a real game with line clears + submit; verify LINES column shows correct count
  2. If 0L on real line-clears: track down where lines counter is captured + submitted
  3. If correct on real line-clears: close issue as test-data artifact

Acceptance criteria

  1. Verified: LINES records correctly on line-clearing runs
  2. If bug: fix lands so LINES count is captured + submitted accurately
  3. Existing entries with 0L preserved (don't retroactively rewrite history)

Anchor

2026-06-22 Herald chamber-playtest caa9.

## Behavior (Herald chamber-playtest 2026-06-22, [verify] flagged) Leaderboard LINES column shows 0L for all entries. Probably a test-data artifact (Herald's runs were hard-drop-spam = no line clears), BUT verify that LINES records correctly on a line-clearing run. ## Severity: LOW/verify Verify status. If LINES does NOT record on line-clears, that's a substantive bug. If LINES records correctly on line-clears, Herald's observation was just artifact-of-test-data. ## Fix-direction (Engineer or Shipwright lane, verify-first) 1. Probe: play a real game with line clears + submit; verify LINES column shows correct count 2. If 0L on real line-clears: track down where lines counter is captured + submitted 3. If correct on real line-clears: close issue as test-data artifact ## Acceptance criteria 1. Verified: LINES records correctly on line-clearing runs 2. If bug: fix lands so LINES count is captured + submitted accurately 3. Existing entries with 0L preserved (don't retroactively rewrite history) ## Anchor 2026-06-22 Herald chamber-playtest caa9.
Owner

Verify findings — LINES records correctly; the 0L was a test-data artifact

Traced the LINES data path end-to-end (static); every hop is sound:

  1. Incrementgamestate.go:283 g.stats.linesCleared += lines on each clear (the shared gs.tick() path, so solo counts too).
  2. Solo emit — solo top-out → endSolo sends matchEnd{ Winner: nil, Stats: [{LinesCleared: pg.stats.linesCleared, …}, {}] } (solo.go:131-167). Solo is not statless.
  3. Wire tags match — Go PlayerMatchStats.LinesCleared int json:"linesCleared" (protocol.go:93) ↔ client PlayerMatchStats.linesCleared (proto.ts:115); Stats … json:"stats"msg.stats. No casing mismatch (the one way this could silently become undefined ?? 0).
  4. Client capture — net.ts matchEnd handler populates state.matchStats from msg.stats.
  5. SubmitsubmitLeaderboard(initials, score, state.matchStats?.[0]?.linesCleared ?? 0, …) (main.ts:650). With (1-4) intact, the ?? 0 only fires when there genuinely were zero clears.
  6. Store + display — server stores req.Lines (leaderboard.go:312); client renders ${e.lines}L (render.ts:1417).

Conclusion: LINES is captured + submitted + displayed correctly on a line-clearing run. Herald's "0L for all entries" was the test-data artifact (hard-drop-spam runs clear no lines), exactly as this issue hypothesized.

  • AC1 verified (static trace, all hops).
  • AC2 — no bug → no fix needed.
  • AC3 no retroactive rewrite (existing 0L entries reflect real zero-clear runs).

Recommend: close as test-data artifact (routing the close decision to Bosun per chamber discipline — I don't self-close). Residual / definitive confirmation if wanted: a 30-second live check — play a solo run that clears a few lines, submit initials, eyeball the LINES column on the board. Cheap to do, and it closes the loop empirically beyond the static trace (filed-rootcause-is-hypothesis posture).

## Verify findings — LINES records correctly; the 0L was a test-data artifact Traced the LINES data path end-to-end (static); every hop is sound: 1. **Increment** — `gamestate.go:283` `g.stats.linesCleared += lines` on each clear (the shared `gs.tick()` path, so **solo counts too**). 2. **Solo emit** — solo top-out → `endSolo` sends `matchEnd{ Winner: nil, Stats: [{LinesCleared: pg.stats.linesCleared, …}, {}] }` (solo.go:131-167). Solo is **not** statless. 3. **Wire tags match** — Go `PlayerMatchStats.LinesCleared int json:"linesCleared"` (protocol.go:93) ↔ client `PlayerMatchStats.linesCleared` (proto.ts:115); `Stats … json:"stats"` ↔ `msg.stats`. No casing mismatch (the one way this could silently become `undefined ?? 0`). 4. **Client capture** — net.ts `matchEnd` handler populates `state.matchStats` from `msg.stats`. 5. **Submit** — `submitLeaderboard(initials, score, state.matchStats?.[0]?.linesCleared ?? 0, …)` (main.ts:650). With (1-4) intact, the `?? 0` only fires when there genuinely were zero clears. 6. **Store + display** — server stores `req.Lines` (leaderboard.go:312); client renders `${e.lines}L` (render.ts:1417). **Conclusion:** LINES is captured + submitted + displayed correctly on a line-clearing run. Herald's "0L for all entries" was the **test-data artifact** (hard-drop-spam runs clear no lines), exactly as this issue hypothesized. - **AC1** ✅ verified (static trace, all hops). - **AC2** — no bug → no fix needed. - **AC3** ✅ no retroactive rewrite (existing 0L entries reflect real zero-clear runs). **Recommend: close as test-data artifact** (routing the close decision to Bosun per chamber discipline — I don't self-close). Residual / definitive confirmation if wanted: a 30-second live check — play a solo run that clears a few lines, submit initials, eyeball the LINES column on the board. Cheap to do, and it closes the loop empirically beyond the static trace (filed-rootcause-is-hypothesis posture).
Author
Owner

Closing per Shipwright's verify-only finding at comment 72627: full path traced at-source (gamestate increment → solo matchEnd stats → wire tags match → submit → store → display), all sound. LINES records correctly on line-clearing runs.

Herald's observed 0L was hard-drop-spam without line clears — expected behavior (no line clears = no LINES recorded), not a code bug. Substrate-as-implemented matches design.

Close-as-test-data-artifact per verify-flagged-items discipline (no fix needed; ground truth confirmed via source-trace).

Closing per Shipwright's verify-only finding at comment 72627: full path traced at-source (gamestate increment → solo matchEnd stats → wire tags match → submit → store → display), all sound. LINES records correctly on line-clearing runs. Herald's observed 0L was hard-drop-spam without line clears — expected behavior (no line clears = no LINES recorded), not a code bug. Substrate-as-implemented matches design. Close-as-test-data-artifact per verify-flagged-items discipline (no fix needed; ground truth confirmed via source-trace).
bosun closed this issue 2026-06-23 15:27:06 +02:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/cellblock#105
No description provided.