Skip to content

Feat: Game Speed + Pause keybinds#3397

Open
bijx wants to merge 6 commits intomainfrom
fast-forward-keybinds
Open

Feat: Game Speed + Pause keybinds#3397
bijx wants to merge 6 commits intomainfrom
fast-forward-keybinds

Conversation

@bijx
Copy link
Contributor

@bijx bijx commented Mar 10, 2026

Description:

Can't tell you how many times I've been playing solo, I try to go change the speed from Max to x1 and before I've opened the speed controls and clicked on one the AI completely wipes me. But not to worry, we now have a pause and speed toggle up/down keybinds!

Screen.Recording.2026-03-10.162255.mp4

Keybinds were added to "Menu Shortcuts" submenu:

image

Tested on Solo, custom match, and public lobbies. Pause intent works correctly on solo and private match (only if you are host), and neither feature works in public matches, as expected.

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory
  • I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced

Please put your Discord username so you can be contacted if a bug or regression is found:

bijx

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 33eaa8e6-adc9-49d9-b764-040bd29b0c94

📥 Commits

Reviewing files that changed from the base of the PR and between b498841 and 71611d3.

📒 Files selected for processing (1)
  • src/client/LocalServer.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/client/LocalServer.ts

Walkthrough

Adds pause and single-player/replay speed controls: new intent events, default keybinds (P, Period, Comma), localization keys, UI entries in help and settings, event wiring in input, sidebar, local server, and replay panel to handle pause and replay-speed changes.

Changes

Cohort / File(s) Summary
Localization
resources/lang/en.json
Added new localization keys for help_modal.action_pause_game, help_modal.action_game_speed, and user_setting labels/descriptions for pause and game speed controls.
Input Events & Keybinds
src/client/InputHandler.ts
Added TogglePauseIntentEvent, GameSpeedUpIntentEvent, GameSpeedDownIntentEvent; registered keybinds for pauseGame (KeyP), gameSpeedUp (Period), gameSpeedDown (Comma); emit intent events on keydown/keyup.
Help & Settings UI
src/client/HelpModal.ts, src/client/UserSettingModal.ts
HelpModal: added UI rows and key labels for pause and speed controls. UserSettingModal: added default keybinds and settings entries for pause, speed up, and speed down.
Game Speed Logic
src/client/LocalServer.ts
Introduced SPEED_ORDER; handlers for GameSpeedUpIntentEvent and GameSpeedDownIntentEvent to move replaySpeedMultiplier within bounds and emit ReplaySpeedChangeEvent.
UI Event Handling
src/client/graphics/layers/GameRightSidebar.ts, src/client/graphics/layers/ReplayPanel.ts
GameRightSidebar listens for TogglePauseIntentEvent and triggers existing pause toggle when allowed. ReplayPanel listens for ReplaySpeedChangeEvent and updates its replay speed multiplier and UI.

Sequence Diagrams

sequenceDiagram
    participant User
    participant InputHandler
    participant EventBus
    participant GameRightSidebar
    participant GameLogic

    User->>InputHandler: Press P (pauseGame)
    InputHandler->>EventBus: emit TogglePauseIntentEvent
    EventBus->>GameRightSidebar: dispatch TogglePauseIntentEvent
    GameRightSidebar->>GameRightSidebar: check single-player/replay or lobby owner
    GameRightSidebar->>GameLogic: onPauseButtonClick()
    GameLogic->>GameLogic: toggle paused state
    GameLogic->>EventBus: emit PauseGameIntentEvent
Loading
sequenceDiagram
    participant User
    participant InputHandler
    participant EventBus
    participant LocalServer
    participant ReplayPanel

    User->>InputHandler: Press Period/Comma (speed control)
    InputHandler->>EventBus: emit GameSpeedUpIntentEvent / GameSpeedDownIntentEvent
    EventBus->>LocalServer: dispatch speed intent event
    LocalServer->>LocalServer: update replaySpeedMultiplier using SPEED_ORDER
    LocalServer->>EventBus: emit ReplaySpeedChangeEvent
    EventBus->>ReplayPanel: dispatch ReplaySpeedChangeEvent
    ReplayPanel->>ReplayPanel: update _replaySpeedMultiplier and request UI render
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

⏸️ Tap P to pause the play,
Period speeds the clouds away,
Comma brakes the replay line,
Small keys make the pace divine. 🎮

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Feat: Game Speed + Pause keybinds' clearly and concisely summarizes the main change—adding keyboard shortcuts for pause and game speed control.
Description check ✅ Passed The description directly relates to the changeset, explaining the motivation, implementation details, testing across game modes, and compliance with project standards.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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.

Copy link
Contributor

@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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/client/UserSettingModal.ts (1)

50-52: Consider a shared default-keybind source.

These new defaults now have to stay aligned across UserSettingModal, InputHandler, and HelpModal. Pulling the default map into one exported constant would avoid the next default change drifting between runtime behavior, help text, and conflict validation.

Also applies to: 640-668

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

In `@src/client/UserSettingModal.ts` around lines 50 - 52, Extract the default
keybind map into a single exported constant (e.g., DEFAULT_KEYBINDS) and import
it wherever defaults are needed instead of hardcoding values: replace the inline
map in UserSettingModal (pauseGame, gameSpeedUp, gameSpeedDown, etc.), the
default/conflict logic in InputHandler, and the help text generation in
HelpModal to reference DEFAULT_KEYBINDS so all three modules use the same source
of truth for defaults.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/client/HelpModal.ts`:
- Around line 61-63: getKeybinds() currently drops "Null" entries so HelpModal's
displayed keybinds (pauseGame, gameSpeedUp, gameSpeedDown) show defaults instead
of an unbound state; update either getKeybinds() to preserve explicit
null/"Null" values or update HelpModal's rendering to detect a "Null"/null value
for pauseGame, gameSpeedUp, gameSpeedDown and either render an "Unbound" label
or hide the row entirely (same change needed for the other rows referenced
around the same block). Ensure the check uses the exact token used in your
codebase ("Null" vs null) and apply the same logic for all affected keybind rows
so unbinding in settings is reflected correctly in the UI.

In `@src/client/LocalServer.ts`:
- Around line 109-125: The replay speed hotkeys are currently registered for
replay sessions; wrap the GameSpeedUpIntentEvent and GameSpeedDownIntentEvent
handler registrations in a guard so they only register for non-replay sessions
(check this.isReplay). Specifically, in LocalServer where eventBus.on is used
for GameSpeedUpIntentEvent and GameSpeedDownIntentEvent (which manipulate
SPEED_ORDER, replaySpeedMultiplier, and emit ReplaySpeedChangeEvent), gate the
block with if (!this.isReplay) { ... } or alternatively add an early return
inside each handler that checks this.isReplay; prefer gating the registration to
avoid registering unnecessary listeners.

---

Nitpick comments:
In `@src/client/UserSettingModal.ts`:
- Around line 50-52: Extract the default keybind map into a single exported
constant (e.g., DEFAULT_KEYBINDS) and import it wherever defaults are needed
instead of hardcoding values: replace the inline map in UserSettingModal
(pauseGame, gameSpeedUp, gameSpeedDown, etc.), the default/conflict logic in
InputHandler, and the help text generation in HelpModal to reference
DEFAULT_KEYBINDS so all three modules use the same source of truth for defaults.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 58f9810a-5f87-475d-a574-55f6977d66f9

📥 Commits

Reviewing files that changed from the base of the PR and between 8eb879a and b498841.

📒 Files selected for processing (7)
  • resources/lang/en.json
  • src/client/HelpModal.ts
  • src/client/InputHandler.ts
  • src/client/LocalServer.ts
  • src/client/UserSettingModal.ts
  • src/client/graphics/layers/GameRightSidebar.ts
  • src/client/graphics/layers/ReplayPanel.ts

@github-project-automation github-project-automation bot moved this from Triage to Development in OpenFront Release Management Mar 10, 2026
@bijx bijx added this to the v31 milestone Mar 11, 2026
@bijx bijx added the Gameplay Features that affect gameplay label Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Gameplay Features that affect gameplay

Projects

Status: Development

Development

Successfully merging this pull request may close these issues.

1 participant