Skip to content

Add configurable leaderboard income columns#4453

Open
jsshap wants to merge 4 commits into
openfrontio:mainfrom
jsshap:feature/4074-leaderboard-income-columns-v2
Open

Add configurable leaderboard income columns#4453
jsshap wants to merge 4 commits into
openfrontio:mainfrom
jsshap:feature/4074-leaderboard-income-columns-v2

Conversation

@jsshap

@jsshap jsshap commented Jun 30, 2026

Copy link
Copy Markdown

Before opening a PR: discuss new features on Discord first, and file bugs or small improvements as issues. You must be assigned to an approved issue — unsolicited PRs will be auto-closed.

Add approved & assigned issue number here:

Resolves #4074

Description:

Adds gold/min and configurable scoreboard columns. Adds optional cities column.

Leaderboard

Leaderboard column chooser

Testing: npm test

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

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

jsshap

@CLAassistant

CLAassistant commented Jun 30, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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: a2c7ddcc-b876-4377-bf84-2c7fa0fa7e79

📥 Commits

Reviewing files that changed from the base of the PR and between ed3536f and ae514fe.

📒 Files selected for processing (2)
  • tests/PackedPlayerUpdates.test.ts
  • tests/PlayerUpdateDiff.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/PlayerUpdateDiff.test.ts

Walkthrough

Adds a rolling gold-per-minute stat on the server, carries it through player update paths, and lets the leaderboard show configurable columns saved in user settings.

Changes

goldPerMinute stat and configurable leaderboard columns

Layer / File(s) Summary
goldPerMinute tracking in PlayerImpl
src/core/game/Game.ts, src/core/game/PlayerImpl.ts, src/core/game/GameImpl.ts
addGold gets a countAsIncome flag, donateGold passes false, and PlayerImpl tracks rolling gold-income buckets to emit goldPerMinute in full and partial updates.
Packed update protocol: stride 4→5
src/core/game/GameUpdates.ts, src/core/game/GameUpdateUtils.ts, src/client/render/types/Renderer.ts, src/client/view/GameView.ts, src/client/view/PlayerView.ts, tests/GameUpdateUtils.test.ts, tests/PackedPlayerUpdates.test.ts, tests/PlayerUpdateDiff.test.ts, tests/client/render/frame/derive/*, tests/client/view/GameView.test.ts, tests/util/viewStubs.ts
PlayerUpdate, PlayerState, diff/apply logic, packed record decoding, and related tests all move to a 5-field player stats record that includes goldPerMinute.
UserSettings leaderboard column persistence
src/core/game/UserSettings.ts, tests/UserSettings.test.ts
Adds persisted leaderboard column selection with allowed-key filtering, default fallback, and toggle behavior.
Leaderboard HUD: dynamic columns and settings UI
src/client/hud/layers/Leaderboard.ts, resources/lang/en.json
Leaderboard headers and rows now render from configurable column definitions, with new settings controls and translation labels for the extra column UI.

Sequence Diagram(s)

sequenceDiagram
  participant PlayerImpl
  participant GameUpdateUtils
  participant GameView
  participant PlayerView
  participant Leaderboard

  PlayerImpl->>GameUpdateUtils: toUpdate() / toFullUpdate()
  GameUpdateUtils-->>GameView: packedPlayerUpdates + PlayerUpdate
  GameView->>PlayerView: stateFromUpdate()
  PlayerView-->>Leaderboard: goldPerMinute(), tiles, gold, troops
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

UI/UX, Feature

Suggested reviewers

  • evanpelle
  • Celant

Poem

Gold flows steady, soft and bright,
Packed in records, day and night.
Columns wake and sort anew,
Quiet stats now shine through.
A minute counts, the board can say,
Who earns the most along the way.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR also adds a column chooser and a Cities column, which go beyond the linked issue's gold/min scoreboard request. Split the column-chooser UI and Cities column into a separate PR or issue if they are intended as follow-up work.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding configurable leaderboard income columns.
Description check ✅ Passed The description matches the change set and describes the gold/min and configurable leaderboard work.
Linked Issues check ✅ Passed The implementation appears to cover server-side gold/min tracking, sliding-window buckets, and client updates required by #4074.

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.

@jsshap jsshap force-pushed the feature/4074-leaderboard-income-columns-v2 branch from a059744 to 7534539 Compare June 30, 2026 00:34

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@src/client/hud/layers/Leaderboard.ts`:
- Around line 186-202: The ranking logic in updateLeaderboard is using the full
playerViews list, so dead players can affect the computed fallback place for the
local player. Update the Leaderboard.updateLeaderboard flow to filter the
game.playerViews() result to alive players before sorting, or compute the place
from an alive-only list, so the local player’s rank is based only on active
players.

In `@tests/PackedPlayerUpdates.test.ts`:
- Around line 51-55: The PackedPlayerUpdates assertions are incorrectly using
Number(alice.gold()) for the new goldPerMinute slot, which can hide a packing
bug in PackedPlayerUpdates. Update the expectations in the affected test cases
to assert goldPerMinute with its known income value directly, using the relevant
PackedPlayerUpdates/record tuple checks instead of deriving that field from
alice.gold().

In `@tests/PlayerUpdateDiff.test.ts`:
- Around line 134-211: The new tests are bypassing the shared core-simulation
harness by constructing players and calling game.addPlayer directly. Update
these cases to use the setup() helper from tests/util/Setup.ts to create the
game instance and obtain players, keeping the assertions around PlayerInfo,
game.player, toUpdate, donateGold, and drainPackedPlayerUpdates intact. If a
special exception applies, make it explicit; otherwise route both tests through
the standard test setup pattern.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ef07d4b5-718a-4069-92f2-e1e7acf75e78

📥 Commits

Reviewing files that changed from the base of the PR and between f4b47ce and 7534539.

📒 Files selected for processing (19)
  • resources/lang/en.json
  • src/client/hud/layers/Leaderboard.ts
  • src/client/render/types/Renderer.ts
  • src/client/view/GameView.ts
  • src/client/view/PlayerView.ts
  • src/core/game/Game.ts
  • src/core/game/GameImpl.ts
  • src/core/game/GameUpdateUtils.ts
  • src/core/game/GameUpdates.ts
  • src/core/game/PlayerImpl.ts
  • src/core/game/UserSettings.ts
  • tests/GameUpdateUtils.test.ts
  • tests/PackedPlayerUpdates.test.ts
  • tests/PlayerUpdateDiff.test.ts
  • tests/UserSettings.test.ts
  • tests/client/render/frame/derive/nuke-telegraphs.test.ts
  • tests/client/render/frame/derive/player-status.test.ts
  • tests/client/view/GameView.test.ts
  • tests/util/viewStubs.ts

Comment thread src/client/hud/layers/Leaderboard.ts Outdated
Comment thread tests/PackedPlayerUpdates.test.ts Outdated
Comment thread tests/PlayerUpdateDiff.test.ts Outdated
@github-project-automation github-project-automation Bot moved this from Triage to Development in OpenFront Release Management Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Development

Development

Successfully merging this pull request may close these issues.

Add income (as gold per minute) to the scoreboard

2 participants