Skip to content

Add map-specific player overview breakdown details#230

Open
lordscarlet wants to merge 17 commits into
YourDeveloperFriend:mainfrom
lordscarlet:feature/map-specific-breakdown-details
Open

Add map-specific player overview breakdown details#230
lordscarlet wants to merge 17 commits into
YourDeveloperFriend:mainfrom
lordscarlet:feature/map-specific-breakdown-details

Conversation

@lordscarlet

@lordscarlet lordscarlet commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR adds support for map-specific customization of player overview breakdowns in the game interface. Maps can now control what information is displayed to players during gameplay, enabling unique UI experiences for different game mechanics.

Key Features

1. Map-Specific Multiplier Labels (London)

  • Maps can define custom multipliers applied to income and expense calculations
  • London demonstrates with ×2 multiplier on income points and -2 on share penalties
  • Formatted labels clearly show the multipliers in the Financial Details panel

2. Optional Score Breakdown Panel

  • Maps can hide the Score Breakdown section (e.g., games with hidden scoring or solo play)
  • Detroit: Bankruptcy mechanics make mid-game scoring less meaningful
  • Barbados: Solo gameplay mode doesn't require score comparison

3. Monsoon Impact Visualization (India)

  • Shows probabilistic outcomes for upcoming income decisions
  • Each scenario displays:
    • Probability as percentage + odds (e.g., "67% (2 in 3)")
    • Cost of the scenario
    • Resulting end-of-turn money (matches bidding impact UI pattern)
    • Warning if money would go negative
  • Helps players understand financial risk before income phase

Changes Made

Core Infrastructure

  • [3 commits] Added map-specific view settings hooks:
    • useLondonMultipliers() - Income/expense multipliers
    • useHiddenScoreBreakdown() - Hide Score Breakdown panel
    • useMonsoonScenarios() - Future income probabilities

E2E Test Coverage

  • London multiplier test: Verifies ×2 labels display correctly
  • Detroit hidden score test: Confirms Score Breakdown is absent (bankruptcy case)
  • Barbados hidden score test: Confirms Score Breakdown is absent (solo play case)
  • India monsoon test: Validates probability display and end-of-turn money impact

All tests include screenshot artifacts for PR documentation.

UI Polish

  • Monsoon scenarios grid layout - Visual cards showing each scenario side-by-side
  • Probability formatting - Intuitive percentages + odds notation
  • Consistent styling - Extends bidding impact panel design patterns

Testing Strategy

  • Fresh PostgreSQL + Redis containers for isolated test environment
  • Deterministic game seeds for reproducible outcomes
  • Adaptive player joining (polling for button availability)
  • Optional E2E screenshot capture via E2E_SCREENSHOTS=true flag

Screenshots

Generated via E2E_SCREENSHOTS=true npm run e2e-test:

  • london-multiplier-breakdown.png - Shows ×2 multiplier labels
image
  • detroit-score-hidden.png - Financial Details without Score Breakdown
    image

  • barbados-score-hidden.png - Financial Details without Score Breakdown
    image

  • india-monsoon-scenarios.png - Probability cards with end-of-turn impact
    image

Related Maps

  • ✅ London (×2 multipliers)
  • ✅ Detroit (hidden score for bankruptcy)
  • ✅ Barbados (solo play)
  • ✅ India (monsoon probabilities)

Other maps continue to use default player overview (no customizations).

Merge from YourDeveloperFriend
- Extended MapViewSettings with useExpenseBreakdownItems, useScoreBreakdownItems, hideScoreBreakdown, and useMonsoonScenarios
- Added getIncomeMultiplier() and getSharesMultiplier() to PlayerHelper base class
- Updated London and Chicago-L to override multipliers (x2 instead of x3)
- Implemented expense breakdowns for Chesapeake & Ohio, Montreal Metro, Detroit
- Implemented score breakdowns for Sweden, New England, California Gold Rush
- Added hideScoreBreakdown flag for Detroit and Barbados
- Implemented monsoon scenarios display for India map
- Updated UI components (FinancialDetailsPanel, ScoreBreakdownPanel, ScoreTooltipContent) to display custom items

Related to PR YourDeveloperFriend#226 (expanded player overview gaps)
- Add smoke tests for London multipliers, Detroit/Barbados hidden score panel, and India monsoon scenarios
- Make e2e setup resilient with adaptive join/start handling and button polling
- Improve text assertions for React-rendered split text nodes
- Register new suite in e2e runner
Copilot AI review requested due to automatic review settings March 4, 2026 13:21

Copilot AI 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.

Pull request overview

Adds map-specific configuration hooks to customize the in-game player overview breakdown UI (financial + score details) on a per-map basis.

Changes:

  • Introduces new MapViewSettings hooks to supply custom expense/score breakdown items, optionally hide score breakdown, and provide monsoon scenario data.
  • Updates the player overview UI to render custom breakdown rows, map-specific score multipliers, and an optional monsoon scenarios section.
  • Adds unit and E2E tests plus screenshot artifact helpers for the new UI behaviors.

Reviewed changes

Copilot reviewed 23 out of 24 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/maps/view_settings.ts Extends MapViewSettings with optional breakdown/scenario hooks and hide flag.
src/maps/sweden/view_settings.ts Adds Sweden-specific score breakdown items (garbage scoring).
src/maps/new_england/view_settings.ts Adds New England money-based bonus breakdown items.
src/maps/new_england/breakdown_test.ts Adds unit tests related to New England breakdown calculation.
src/maps/montreal_metro/view_settings.ts Adds Montreal-specific expense breakdown item sourced from injected state.
src/maps/london/score_multipliers_test.ts Adds unit tests for London score multiplier methods.
src/maps/london/score.ts Adds multiplier methods to London player helper.
src/maps/india-steam-brothers/view_settings.ts Adds India monsoon scenario hook for the financial panel.
src/maps/india-steam-brothers/monsoon_scenarios_test.ts Adds unit tests intended to validate monsoon scenarios.
src/maps/detroit/view_settings.ts Hides score breakdown for Detroit + adds an expense breakdown item.
src/maps/chicago-l/score_multipliers_test.ts Adds unit tests for Chicago-L score multiplier methods.
src/maps/chicago-l/score.ts Adds multiplier methods to Chicago-L player helper.
src/maps/chesapeake-and-ohio/view_settings.ts Adds computed expense breakdown item (factory maintenance) using grid data.
src/maps/ca-gold-rush/view_settings.ts Adds Gold Rush score breakdown item using injected state.
src/maps/barbados/view_settings.ts Hides score breakdown for Barbados.
src/engine/game/player_multipliers_test.ts Adds unit tests for default/base multipliers in PlayerHelper.
src/engine/game/player.ts Adds default multiplier methods to PlayerHelper.
src/e2e/util/webdriver.ts Adds screenshot helpers for E2E artifact capture.
src/e2e/player_overview_breakdowns_test.ts Adds E2E coverage for map-specific breakdown behaviors + optional screenshots.
src/e2e/e2e_test.ts Registers the new E2E suite.
src/client/game/player_expanded_row.tsx Renders custom expense/score items, multiplier labels, and monsoon scenarios; supports hiding score breakdown panel.
src/client/game/player_expanded_row.module.css Adds styling for monsoon scenarios grid/cards and subsection title.
.vscode/settings.json Adds VS Code workspace settings related to chat/terminal tool auto-approval.
.gitignore Ignores E2E artifacts directory.
Comments suppressed due to low confidence (1)

src/engine/game/player.ts:126

  • getScoreFromIncome still hard-codes 3 * player.income even though getIncomeMultiplier() was added. This duplicates the multiplier in two places and makes it easy for future map overrides of getIncomeMultiplier() to desync the UI label from the actual score calculation; use this.getIncomeMultiplier() (and similarly apply getSharesMultiplier() in getScoreFromShares).
  getScoreFromIncome(player: PlayerData): number {
    if (player.outOfGame) return 0;
    return 3 * player.income;
  }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/e2e/util/webdriver.ts Outdated
Comment thread src/e2e/player_overview_breakdowns_test.ts Outdated
Comment thread src/e2e/player_overview_breakdowns_test.ts
Comment thread .vscode/settings.json Outdated
Comment thread src/client/game/player_expanded_row.tsx
Comment thread src/maps/india-steam-brothers/view_settings.ts Outdated
Comment thread src/maps/india-steam-brothers/monsoon_scenarios_test.ts Outdated
Comment thread src/client/game/player_expanded_row.tsx Outdated
Comment thread src/maps/new_england/breakdown_test.ts
@lordscarlet

Copy link
Copy Markdown
Contributor Author

Addressed the Copilot review note in commit cba25fd:

  • Updated base scoring in src/engine/game/player.ts to use multiplier hooks:
    • getScoreFromIncome now uses getIncomeMultiplier()
    • getScoreFromShares now uses getSharesMultiplier()
  • Removed accidental .vscode/settings.json from the PR scope.
  • Re-ran verification:
    • npm run build-server
    • multiplier-focused unit tests (PlayerHelper/London/Chicago-L), all passing.

No remaining actionable review threads appear open on this PR.

@lordscarlet lordscarlet marked this pull request as draft March 4, 2026 14:29
@lordscarlet lordscarlet marked this pull request as ready for review March 4, 2026 15:41
@lordscarlet

Copy link
Copy Markdown
Contributor Author

Quick update: I fixed the test/build regression introduced during review follow-ups.

Root cause: monsoon_scenarios_test.ts imported india-steam-brothers/view_settings.ts, which pulls in client-side dependencies. That caused npm test to compile client modules and fail on CSS-module resolution in this test context.

Fix applied:

  • Extracted monsoon scenario helper into src/maps/india-steam-brothers/monsoon_scenarios.ts
  • Updated view_settings.ts to import/re-export that helper
  • Updated monsoon_scenarios_test.ts to import from the new helper file

Validation:

  • npm test passes (74 specs, 0 failures)
  • npm run build-server passes

Commit: 3e78d85

1 similar comment
@lordscarlet

Copy link
Copy Markdown
Contributor Author

Quick update: I fixed the test/build regression introduced during review follow-ups.

Root cause: monsoon_scenarios_test.ts imported india-steam-brothers/view_settings.ts, which pulls in client-side dependencies. That caused npm test to compile client modules and fail on CSS-module resolution in this test context.

Fix applied:

  • Extracted monsoon scenario helper into src/maps/india-steam-brothers/monsoon_scenarios.ts
  • Updated view_settings.ts to import/re-export that helper
  • Updated monsoon_scenarios_test.ts to import from the new helper file

Validation:

  • npm test passes (74 specs, 0 failures)
  • npm run build-server passes

Commit: 3e78d85

@JackOfMostTrades JackOfMostTrades left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

My general sense that I've repeated more specifically in a couple of comments is that the new useExpenseBreakdownItems hook feels like it's forcing map implementers to have to implement the same map-specific adjustments in multiple places. Can you see if there's more refactoring that could be done of the base ProfitHelper class so that behaviors like the factory cost in C&O only have to be implemented once and then have that accurately applied both in the player overview breakdown and the net income+expenses game logic?

useScoreBreakdownItems = useCaliforniaGoldRushScoreBreakdown;

getFinalOverviewRows(): RowFactory[] {
return insertAfter(getRowList(), TrackVps, GoldVps);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is there some way to consolidate this a little bit? It feels a touch unfortunate that we have to create view settings for both the final overview rows and the useScoreBreakdownItems now. Feels like there ought to be a way to combine them.

useExpenseBreakdownItems = useChesapeakeExpenseBreakdown;
}

function useChesapeakeExpenseBreakdown(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I get a bit of a "something isn't quite right" sense from seeing this. It seems like map-specific logic is having to be replicated in multiple places now. In this case, this is now present both here and in 'ChesapeakeAndOhioProfitHelper'. Could something about the ProfitHelper interface instead be refactored to have a "getMapSpecificExpenses" that captures this once and then is reused by both the ProfileHelper base class and the expense breakdown view?


getScoreFromIncome(player: PlayerData): number {
if (player.outOfGame) return 0;
return 2 * player.income;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These methods should be dropped since the super method does the right thing with the above override.

Comment thread src/maps/london/score.ts
getSharesMultiplier(): number {
return -2;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same comment as elsewhere, the getScoreFromIncome and getScoreFromShares overrides should be dropped.

: `${formatMoney(endOfTurnMoney)} (needs ${formatMoney(Math.abs(endOfTurnMoney))})`}
</span>
</div>
{monsoonScenarios.length > 0 && (

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Are we able to move this map-specific "monsoon scenarios" behavior into the map and make this a more generic extension point (similar to the custom expense items)? My hope is that that would also let us move the new monsoon-specific CSS into a map-specific CSS module as well.

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.

3 participants