Skip to content

added win streaks, Maria will be happy :)#20

Open
matteomekhail wants to merge 2 commits intoT3-Content:mainfrom
matteomekhail:feature/Win-Streak
Open

added win streaks, Maria will be happy :)#20
matteomekhail wants to merge 2 commits intoT3-Content:mainfrom
matteomekhail:feature/Win-Streak

Conversation

@matteomekhail
Copy link
Copy Markdown
Contributor

@matteomekhail matteomekhail commented Feb 23, 2026

pretty explanatory from the title, i do have written a test, not sure if was good to merge tho
image

Summary by CodeRabbit

  • New Features
    • Added per-player streak tracking that counts consecutive wins.
    • Streaks display with a visual badge (flame emoji and highlighting) when a player reaches 2+ consecutive wins.
    • Streaks reset to zero on losses or ties.
    • Streak indicators appear in both the live arena view and leaderboard standings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 23, 2026

📝 Walkthrough

Walkthrough

This PR adds per-player streak tracking to the game. A streaks field is added to GameState, round outcome logic increments the winner's streak and resets the loser's, and the data flows through server and client state to UI components (ContestantCard, LeaderboardSection) where badges display streaks >= 2. CSS styling for the badge is included.

Changes

Cohort / File(s) Summary
Game State Structure
game.ts, quipslop.tsx
Added streaks: Record<string, number> field to GameState type and initialized it as empty object in game state setup.
Game Logic
game.ts, server.ts
Implemented streak tracking: increment winner's streak, reset loser's streak to 0 on round outcome; reset both streaks on tie. Streaks are computed from historical rounds during initialization.
Server State Management
server.ts
Extended initial game state with streaks field, propagated via getClientState() to client, and ensured streaks are reset during full admin reset.
UI Components
frontend.tsx
Updated Arena, ContestantCard, Standings, and LeaderboardSection to accept and pass streaks data; renders streak badges for streaks >= 2.
Styling
frontend.css
Added .streak-badge class with mono font, 11px size, amber color (#f59e0b), padding, and left auto-margin.
Broadcast Rendering
broadcast.ts
Updated drawScoreboard and drawScoreboardSection to accept streaks map and render flame emoji with highlight for streaks >= 2.

Sequence Diagram

sequenceDiagram
    participant Game as Game Logic
    participant Server as Server State
    participant Client as Client State
    participant UI as UI Components
    
    Game->>Game: Process round outcome
    activate Game
    Game->>Game: Increment winner streak / Reset loser streak
    deactivate Game
    
    Server->>Server: Update streaks in GameState
    Server->>Client: Send streaks via getClientState()
    
    Client->>Client: Store streaks in state
    Client->>UI: Pass streaks to Arena & Standings
    
    UI->>UI: ContestantCard renders badge if streak >= 2
    UI->>UI: LeaderboardSection renders badge if streak >= 2
    UI->>UI: Display flame emoji with highlight
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related issues

  • [Prompt] Add Streaks #24: Directly implements per-contestant streak tracking with increment/reset logic on round outcomes and UI badge rendering as requested.

Poem

🔥 A streak, a flame, a hop of pride,
When bunnies win, they're side by side,
Each victory builds their glowing chain,
Till defeat resets, and starts again!
Our whisker'd code now tracks the way,
Streaks shine bright in games we play! 🐰

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title describes the main feature (win streaks) but includes informal language and lacks clarity about what the change accomplishes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@macroscopeapp
Copy link
Copy Markdown

macroscopeapp bot commented Feb 23, 2026

Add win streak tracking and render 🔥 badges for streaks ≥2 across game state, server init, and UI (Maria will be happy)

Add streaks: Record<string, number> to GameState, update runGame to increment/reset streaks on wins/losses/ties, initialize and persist streaks on the server, and render a flame badge for streaks ≥2 in broadcast and frontend views. Core changes land in game.ts, server.ts, broadcast.ts, and frontend.tsx.

📍Where to Start

Start in the runGame scoring updates in game.ts, then follow state plumbing through server.ts to client renderers in broadcast.ts and frontend.tsx.


Macroscope summarized 8bad3a2.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
frontend.css (1)

236-243: margin-left: auto on .streak-badge may conflict with .lb-entry__score's margin-left: auto.

In .lb-entry__top, both .streak-badge and .lb-entry__score use margin-left: auto. The first auto-margin consumes all free space, so the score will sit flush against the streak badge instead of being independently right-aligned. Visually this may be acceptable (both cluster on the right), but verify the spacing looks intentional in the leaderboard entries.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend.css` around lines 236 - 243, In .lb-entry__top, both .streak-badge
and .lb-entry__score use margin-left: auto causing the first auto margin to
consume available space; update the CSS so only the element intended to be
right-aligned uses margin-left:auto (or switch the container to display:flex and
use gap/justify-content to control spacing). Specifically, remove or change
margin-left:auto on .streak-badge (or replace it with a fixed margin like
margin-left:8px or margin-inline-start) and ensure .lb-entry__score retains
margin-left:auto (or alternatively make .lb-entry__top a flex container and use
gap to separate .streak-badge and .lb-entry__score) so the score and badge align
and space as intended.
frontend.tsx (2)

635-635: Line is quite long but functionally correct.

The ?? {} fallbacks for viewerScores and streaks are defensive against potentially undefined server state during initial connection. Consider breaking this into multiple lines for readability.

Proposed formatting
-        <Standings scores={state.scores} viewerScores={state.viewerScores ?? {}} streaks={state.streaks ?? {}} activeRound={state.active} />
+        <Standings
+          scores={state.scores}
+          viewerScores={state.viewerScores ?? {}}
+          streaks={state.streaks ?? {}}
+          activeRound={state.active}
+        />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend.tsx` at line 635, The JSX line rendering the Standings component is
long; split the props across multiple lines or precompute fallback values to
improve readability: either break the <Standings ... /> element so each prop
(scores, viewerScores, streaks, activeRound) sits on its own line, or create
local constants like safeViewerScores = state.viewerScores ?? {} and safeStreaks
= state.streaks ?? {} then pass those into <Standings scores={state.scores}
viewerScores={safeViewerScores} streaks={safeStreaks}
activeRound={state.active}>, keeping the same defensive ?? {} behavior.

432-434: Non-null assertion streaks![name] is safe here, but could be cleaner.

The guard (streaks?.[name] || 0) >= 2 ensures streaks is defined and the value is ≥ 2, so streaks![name] won't be undefined. Consider using streaks?.[name] for consistency to avoid the ! assertion.

Proposed fix
                 {(streaks?.[name] || 0) >= 2 && (
-                  <span className="streak-badge">🔥{streaks![name]}</span>
+                  <span className="streak-badge">🔥{streaks?.[name]}</span>
                 )}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend.tsx` around lines 432 - 434, Replace the non-null assertion in the
JSX span content with a safe optional access to match the guard: in the
conditional that uses (streaks?.[name] || 0) >= 2, change the displayed value
from streaks![name] to streaks?.[name] (or streaks?.[name] ?? 0) so you avoid
the `!` assertion while preserving the same behavior for the streak-badge span.
quipslop.tsx (1)

227-227: Minor inconsistency: streaks initialized differently from scores and viewerScores.

scores and viewerScores are pre-populated with all model names keyed to 0, but streaks starts as {}. This works because consumers use || 0 fallbacks, but it's inconsistent. Consider initializing it the same way for uniformity.

Proposed fix
-    streaks: {},
+    streaks: Object.fromEntries(MODELS.map((m) => [m.name, 0])),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@quipslop.tsx` at line 227, streaks is initialized as an empty object while
scores and viewerScores are pre-populated with all model names set to 0; change
the initialization of streaks to use the same pre-population pattern (e.g., use
the same helper or mapping used for scores/viewerScores or iterate MODEL_NAMES)
so streaks contains every model key with value 0, ensuring consistency with
scores and viewerScores and avoiding reliance on "|| 0" fallbacks in consumers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@frontend.css`:
- Around line 236-243: In .lb-entry__top, both .streak-badge and
.lb-entry__score use margin-left: auto causing the first auto margin to consume
available space; update the CSS so only the element intended to be right-aligned
uses margin-left:auto (or switch the container to display:flex and use
gap/justify-content to control spacing). Specifically, remove or change
margin-left:auto on .streak-badge (or replace it with a fixed margin like
margin-left:8px or margin-inline-start) and ensure .lb-entry__score retains
margin-left:auto (or alternatively make .lb-entry__top a flex container and use
gap to separate .streak-badge and .lb-entry__score) so the score and badge align
and space as intended.

In `@frontend.tsx`:
- Line 635: The JSX line rendering the Standings component is long; split the
props across multiple lines or precompute fallback values to improve
readability: either break the <Standings ... /> element so each prop (scores,
viewerScores, streaks, activeRound) sits on its own line, or create local
constants like safeViewerScores = state.viewerScores ?? {} and safeStreaks =
state.streaks ?? {} then pass those into <Standings scores={state.scores}
viewerScores={safeViewerScores} streaks={safeStreaks}
activeRound={state.active}>, keeping the same defensive ?? {} behavior.
- Around line 432-434: Replace the non-null assertion in the JSX span content
with a safe optional access to match the guard: in the conditional that uses
(streaks?.[name] || 0) >= 2, change the displayed value from streaks![name] to
streaks?.[name] (or streaks?.[name] ?? 0) so you avoid the `!` assertion while
preserving the same behavior for the streak-badge span.

In `@quipslop.tsx`:
- Line 227: streaks is initialized as an empty object while scores and
viewerScores are pre-populated with all model names set to 0; change the
initialization of streaks to use the same pre-population pattern (e.g., use the
same helper or mapping used for scores/viewerScores or iterate MODEL_NAMES) so
streaks contains every model key with value 0, ensuring consistency with scores
and viewerScores and avoiding reliance on "|| 0" fallbacks in consumers.

@UtkarshUsername
Copy link
Copy Markdown

image Its placement is making the bar appear smaller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants