Skip to content

feat: add pause/resume game functionality#203

Open
hexivine wants to merge 2 commits into
masterfrom
test/codepeel-e2e-2026-06-15
Open

feat: add pause/resume game functionality#203
hexivine wants to merge 2 commits into
masterfrom
test/codepeel-e2e-2026-06-15

Conversation

@hexivine

@hexivine hexivine commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add pause/resume game state handling in GameLogic
  • Extend GameState enum with paused
  • Add pauseGame() and
    esumeGame() methods

Test plan

  • Verify pause cancels the game timer
  • Verify resume restores the timer from paused state
  • Confirm dispose() still cleans up correctly

Co-Authored-By: Oz oz-agent@warp.dev

Summary by CodeRabbit

  • New Features
    • Pause and Resume Gameplay: Players can now pause active games at any point to temporarily halt the countdown timer and game progress. When ready to continue, simply resume the game to pick up exactly where you left off without any loss of progress or game state.

- Add paused state to GameState enum
- Add pauseGame() and resumeGame() methods to GameLogic
- Pause cancels timer and sets state to paused
- Resume restores timer from paused state
- Refactor dispose() to remain cleanup-only

Co-Authored-By: Oz <oz-agent@warp.dev>
@codepeel

codepeel Bot commented Jun 15, 2026

Copy link
Copy Markdown
⚙️ CodePeel Walkthrough

Commits: reviewing f20c4b1 against base 73d8ea4

📁 Files reviewed (1)

lib/providers/

  • game_logic.dart

Overview

  • Added pause and resume functionality to the game logic provider
  • Introduced a new 'paused' state to the GameState enum

Key Changes

  • lib/providers/game_logic.dart: Added pauseGame() and resumeGame() methods to manage game timer and state
  • lib/providers/game_logic.dart: Added 'paused' value to GameState enum

Risk Assessment

  • Risk level: low
  • Quality assessment: The changes are straightforward and follow existing patterns. The timer implementation uses floating point arithmetic which may cause negligible timing drift over long sessions, but for typical game durations this is acceptable. No null safety issues or race conditions detected.

Changes

Module Files Findings
lib/providers/ 1 ⚠️ 1
Category Count
🐛 Bugs 1
🔒 Security 0
⚡ Performance 0
📐 Best Practices 0

Review effort: ⬤◯◯◯◯ (1/5)

Health score: 🟢 99/100 | Inline comments: 0


Summary

Added pause/resume functionality with new paused game state


Logic Flow

sequenceDiagram
    participant UI
    participant GameLogic
    UI->>GameLogic: pauseGame()
    GameLogic->>GameLogic: cancel timer
    GameLogic->>GameLogic: set state to paused
    GameLogic->>UI: onStateChanged()
    UI->>GameLogic: resumeGame()
    alt GameState == paused
        GameLogic->>GameLogic: set state to playing
        GameLogic->>GameLogic: cancel existing timer
        GameLogic->>GameLogic: create new periodic timer
        GameLogic->>UI: onStateChanged()
        loop every 100ms
            GameLogic->>GameLogic: decrement timeRemaining
            alt timeRemaining <= 0
                GameLogic->>GameLogic: cancel timer
                GameLogic->>GameLogic: set state to bust
            end
            GameLogic->>UI: onStateChanged()
        end
    else
        GameLogic->>GameLogic: return early
    end
Loading

ℹ️ Review coverage

1 issues identified, 0 posted as inline comments. Some may have been consolidated or skipped due to line validation.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

💤 Files selected but had no reviewable changes (1)
  • test_staging.txt
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: abbcbc12-04fe-4f69-91a1-9694cb50ec63

📥 Commits

Reviewing files that changed from the base of the PR and between f20c4b1 and 4475cc1.

📒 Files selected for processing (1)
  • test_staging.txt

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

GameLogic gains two new methods, pauseGame() and resumeGame(), that cancel and restart the countdown timer respectively. The GameState enum is extended with a paused value to track the paused lifecycle state.

Changes

Pause/Resume Gameplay

Layer / File(s) Summary
GameState.paused enum value and pause/resume methods
lib/providers/game_logic.dart
GameState gains a paused variant. pauseGame() cancels the active timer and sets state to paused. resumeGame() guards on the paused state, restarts the periodic decrement timer, transitions back to playing, and sets state to bust when the timer expires.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Poem

🐇 Hop! The clock stops mid-tick,
A pause button, neat and slick.
Timer cancelled, state set right,
Resume restores the frantic fight.
No more bustling through the freeze—
Volt Rush pauses with such ease! ⚡

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: adding pause/resume game functionality to the game logic with new methods and GameState enum value.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/codepeel-e2e-2026-06-15

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/providers/game_logic.dart`:
- Around line 87-91: The `pauseGame()` and `resumeGame()` methods are
implemented in the `GameLogic` class but are not forwarded by the `GameProvider`
class, making them inaccessible to the UI layer. Add two forwarding methods to
the `GameProvider` class (in the range of lines 8-34 in
lib/providers/game_provider.dart): one method named `pauseGame()` that delegates
to `_gameLogic.pauseGame()` and another method named `resumeGame()` that
delegates to `_gameLogic.resumeGame()`. This will expose both pause and resume
functionality through the provider interface that the UI accesses.
- Around line 87-91: The pauseGame() method currently allows state transitions
to paused from any state, which creates invalid state transitions. Add a guard
condition at the start of the pauseGame() method to check if _gameState equals
GameState.playing, similar to how resumeGame() validates state. Only proceed
with canceling the timer, setting _gameState to GameState.paused, and calling
onStateChanged() if the current state is playing; otherwise, the method should
return early without making any state changes.
- Around line 93-106: The timer creation logic in the resumeGame() method
duplicates the identical timer setup code from the startGame() method, violating
the DRY principle. Extract the timer creation logic (the Timer.periodic call
that decrements _timeRemaining, checks for bust state, and calls onStateChanged)
into a private helper method (e.g., _startGameTimer()). Then replace the
duplicated timer initialization code in both resumeGame() and startGame() with
calls to this new helper method.
- Line 116: Add a missing case for GameState.paused in the switch statement in
main.dart (lines 51-60) that currently handles only home, playing, banked, and
bust states. When GameState.paused is encountered (which is set by the
pauseGame() method in GameProvider), render an appropriate pause screen UI
instead of leaving it unhandled. This will resolve the compilation error
triggered by Dart 3.4+ requiring exhaustive enum handling in switch statements
and provide the UI needed to display the paused game state that pauseGame() and
resumeGame() methods are managing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c2af4ba5-2ab0-4f54-9f0c-1ac50c5beb52

📥 Commits

Reviewing files that changed from the base of the PR and between 73d8ea4 and f20c4b1.

📒 Files selected for processing (1)
  • lib/providers/game_logic.dart

Comment on lines +87 to +91
void pauseGame() {
_timer?.cancel();
_gameState = GameState.paused;
onStateChanged();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Expose pauseGame() and resumeGame() in GameProvider for UI accessibility.

The new pauseGame() and resumeGame() methods are implemented in GameLogic but are not forwarded by GameProvider (lines 8-34 in lib/providers/game_provider.dart). Since the UI layer accesses game controls through GameProvider, these methods are currently unreachable, preventing the pause/resume feature from functioning end-to-end.

🔌 Proposed fix to forward methods in GameProvider

Add these forwarding methods to GameProvider in lib/providers/game_provider.dart:

void pauseGame() => _gameLogic.pauseGame();
void resumeGame() => _gameLogic.resumeGame();

Also applies to: 93-106

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/providers/game_logic.dart` around lines 87 - 91, The `pauseGame()` and
`resumeGame()` methods are implemented in the `GameLogic` class but are not
forwarded by the `GameProvider` class, making them inaccessible to the UI layer.
Add two forwarding methods to the `GameProvider` class (in the range of lines
8-34 in lib/providers/game_provider.dart): one method named `pauseGame()` that
delegates to `_gameLogic.pauseGame()` and another method named `resumeGame()`
that delegates to `_gameLogic.resumeGame()`. This will expose both pause and
resume functionality through the provider interface that the UI accesses.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add state guard to only allow pausing from playing state.

pauseGame() currently transitions to paused from any state without validation. This allows nonsensical transitions like pausing from home, banked, or bust states. Add a guard similar to resumeGame() to ensure pause only occurs when _gameState == GameState.playing.

🛡️ Proposed fix to add state guard
 void pauseGame() {
+  if (_gameState != GameState.playing) return;
   _timer?.cancel();
   _gameState = GameState.paused;
   onStateChanged();
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void pauseGame() {
_timer?.cancel();
_gameState = GameState.paused;
onStateChanged();
}
void pauseGame() {
if (_gameState != GameState.playing) return;
_timer?.cancel();
_gameState = GameState.paused;
onStateChanged();
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/providers/game_logic.dart` around lines 87 - 91, The pauseGame() method
currently allows state transitions to paused from any state, which creates
invalid state transitions. Add a guard condition at the start of the pauseGame()
method to check if _gameState equals GameState.playing, similar to how
resumeGame() validates state. Only proceed with canceling the timer, setting
_gameState to GameState.paused, and calling onStateChanged() if the current
state is playing; otherwise, the method should return early without making any
state changes.

Comment on lines +93 to +106
void resumeGame() {
if (_gameState != GameState.paused) return;
_gameState = GameState.playing;
_timer?.cancel();
_timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
_timeRemaining -= 0.1;
if (_timeRemaining <= 0) {
_timer?.cancel();
_gameState = GameState.bust;
}
onStateChanged();
});
onStateChanged();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Extract duplicated timer logic to reduce code duplication.

The timer creation logic in resumeGame() (lines 97-104) duplicates the identical logic from startGame() (lines 61-68). This violates the DRY principle and makes the code harder to maintain.

♻️ Proposed refactor to extract timer logic
+ void _startTimer() {
+   _timer?.cancel();
+   _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
+     _timeRemaining -= 0.1;
+     if (_timeRemaining <= 0) {
+       _timer?.cancel();
+       _gameState = GameState.bust;
+     }
+     onStateChanged();
+   });
+ }
+
  void startGame() {
    _currentScore = 0;
    _timeRemaining = 10.0;
    _gameState = GameState.playing;
    _showOnboarding = false;
    _saveOnboardingState();
-   _timer?.cancel();
-   _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
-     _timeRemaining -= 0.1;
-     if (_timeRemaining <= 0) {
-       _timer?.cancel();
-       _gameState = GameState.bust;
-     }
-     onStateChanged();
-   });
+   _startTimer();
    onStateChanged();
  }

  void resumeGame() {
    if (_gameState != GameState.paused) return;
    _gameState = GameState.playing;
-   _timer?.cancel();
-   _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
-     _timeRemaining -= 0.1;
-     if (_timeRemaining <= 0) {
-       _timer?.cancel();
-       _gameState = GameState.bust;
-     }
-     onStateChanged();
-   });
+   _startTimer();
    onStateChanged();
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void resumeGame() {
if (_gameState != GameState.paused) return;
_gameState = GameState.playing;
_timer?.cancel();
_timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
_timeRemaining -= 0.1;
if (_timeRemaining <= 0) {
_timer?.cancel();
_gameState = GameState.bust;
}
onStateChanged();
});
onStateChanged();
}
void _startTimer() {
_timer?.cancel();
_timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
_timeRemaining -= 0.1;
if (_timeRemaining <= 0) {
_timer?.cancel();
_gameState = GameState.bust;
}
onStateChanged();
});
}
void startGame() {
_currentScore = 0;
_timeRemaining = 10.0;
_gameState = GameState.playing;
_showOnboarding = false;
_saveOnboardingState();
_startTimer();
onStateChanged();
}
void resumeGame() {
if (_gameState != GameState.paused) return;
_gameState = GameState.playing;
_startTimer();
onStateChanged();
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/providers/game_logic.dart` around lines 93 - 106, The timer creation
logic in the resumeGame() method duplicates the identical timer setup code from
the startGame() method, violating the DRY principle. Extract the timer creation
logic (the Timer.periodic call that decrements _timeRemaining, checks for bust
state, and calls onStateChanged) into a private helper method (e.g.,
_startGameTimer()). Then replace the duplicated timer initialization code in
both resumeGame() and startGame() with calls to this new helper method.

enum GameState {
home,
playing,
paused,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check for switch statements over GameState that may be missing the paused case.

rg -nP -A15 'switch\s*\(\s*\w+\.gameState\s*\)' --type=dart

Repository: hexivine/volt-rush

Length of output: 817


🏁 Script executed:

#!/bin/bash
# Check the GameState enum definition in game_logic.dart
echo "=== GameState enum definition ==="
rg -nA 30 'enum GameState' lib/providers/game_logic.dart --type=dart

echo -e "\n=== Check main.dart switch statement with more context ==="
sed -n '45,65p' lib/main.dart

echo -e "\n=== Search for all GameState switch statements ==="
rg -n 'switch.*gameState|case GameState\.' lib/main.dart --type=dart

echo -e "\n=== Check for other GameState references ==="
rg -n 'GameState\.' lib --type=dart | head -20

Repository: hexivine/volt-rush

Length of output: 2130


🏁 Script executed:

#!/bin/bash
# Verify Dart version and check if this would trigger exhaustiveness check
echo "=== Check pubspec.yaml for Dart SDK version ==="
rg -A 5 "sdk:" pubspec.yaml

echo -e "\n=== Verify pauseGame() and resumeGame() exist in GameProvider ==="
rg -n 'void pauseGame|void resumeGame' lib/providers/game_logic.dart --type=dart -A 2

Repository: hexivine/volt-rush

Length of output: 652


Add missing switch case for GameState.paused in main.dart.

The GameState enum includes a paused variant (line 116 in game_logic.dart), but the switch statement in main.dart (lines 51–60) only handles home, playing, banked, and bust. With Dart 3.4+, this non-exhaustive switch over an enum without a default case triggers a compilation error. Additionally, pauseGame() (line 87) and resumeGame() (line 93) in GameProvider set and check GameState.paused, but the UI has no screen to display when the game is paused.

Add a case for GameState.paused in the switch statement to render an appropriate pause screen.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/providers/game_logic.dart` at line 116, Add a missing case for
GameState.paused in the switch statement in main.dart (lines 51-60) that
currently handles only home, playing, banked, and bust states. When
GameState.paused is encountered (which is set by the pauseGame() method in
GameProvider), render an appropriate pause screen UI instead of leaving it
unhandled. This will resolve the compilation error triggered by Dart 3.4+
requiring exhaustive enum handling in switch statements and provide the UI
needed to display the paused game state that pauseGame() and resumeGame()
methods are managing.

@codepeel

codepeel Bot commented Jun 15, 2026

Copy link
Copy Markdown

Auto-Fix PR Available

CodePeel has generated fixes for this review: #204

@codepeel

codepeel Bot commented Jun 15, 2026

Copy link
Copy Markdown
⚙️ CodePeel Walkthrough

Commits: reviewing 4475cc1 against base 73d8ea4

📁 Files reviewed (2)

lib/providers/

  • game_logic.dart
    (root)/
  • test_staging.txt

Overview

  • Added new binary file test_staging.txt

Key Changes

  • Added new binary file test_staging.txt (likely a test or staging configuration file)

Risk Assessment

  • Risk level: low
  • The file is likely a test or configuration file for staging and not part of the production app. Without visibility into its content, we assume it poses minimal risk.

Changes

Module Files Findings
lib/providers/ 1 ✅ 0
(root)/ 1 ✅ 0
Category Count
🐛 Bugs 0
🔒 Security 0
⚡ Performance 0
📐 Best Practices 0

Review effort: ⬤◯◯◯◯ (1/5)

Health score: 🟢 100/100 | Inline comments: 0


Summary

Added test_staging.txt file for staging environment testing.

@codepeel-staging

codepeel-staging Bot commented Jun 15, 2026

Copy link
Copy Markdown
⚙️ CodePeel Walkthrough

Commits: reviewing 4475cc1 against base 73d8ea4

📁 Files reviewed (2)

lib/providers/

  • game_logic.dart
    (root)/
  • test_staging.txt

Overview

  • Added a new binary file test_staging.txt to the repository
  • No functional changes or code modifications were made

Key Changes

  • test_staging.txt: New binary file added

Risk Assessment

  • Risk level: None
  • Quality assessment: No impact on codebase

Changes

Module Files Findings
lib/providers/ 1 ✅ 0
(root)/ 1 ✅ 0
Category Count
🐛 Bugs 0
🔒 Security 0
⚡ Performance 0
📐 Best Practices 0

Review effort: ⬤◯◯◯◯ (1/5)

Health score: 🟢 100/100 | Inline comments: 0


Summary

Added a new binary file test_staging.txt with no functional impact.

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.

1 participant