Skip to content

Add Leaderboard modal UI, visual-state leaderboard projection, and wiring#35

Merged
KonH merged 5 commits into
mainfrom
codex/add-leaderboard-ui-in-map
Jul 20, 2026
Merged

Add Leaderboard modal UI, visual-state leaderboard projection, and wiring#35
KonH merged 5 commits into
mainfrom
codex/add-leaderboard-ui-in-map

Conversation

@KonH

@KonH KonH commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Motivation

  • Provide an in-game fullscreen Leaderboard window accessible from the map HUD so players can compare organization and country scores without leaving the map.
  • Expose leaderboard data through the existing VisualState projection so the UI updates via normal visual-state refreshes and remains compatible with the resource-collector pipeline migration (country scores read via the stable CountryScoreSystem.GetScore).
  • Integrate the modal into the scene/DI like other modal documents so it is injectable and follows existing lifecycle/modal semantics.

Description

  • Added a new Leaderboard modal UI under Assets/UI/Modal/LeaderboardWindow/ including LeaderboardWindow.uxml and LeaderboardWindow.uss, and added UI strings to Assets/Localization/en.asset and Assets/Localization/ru.asset.
  • Implemented Unity-side view/document classes LeaderboardWindowView and LeaderboardWindowDocument and hooked them into HUD via HUDDocument (added btn-leaderboard, click handler, and localized text refresh logic).
  • Extended core visual state with LeaderboardEntryState and LeaderboardState in src/Game.Main/VisualState.cs, and implemented leaderboard projection and country-score population in VisualStateConverter (uses CountryScoreSystem.GetScore and OrgScoreSystem.GetScore, sorts entries, assigns place numbers, and uses CountryConfig for display-name fallback).
  • Wired GameLogic to provide CountryConfig to the converter, registered LeaderboardWindowDocument in GameLifetimeScope, added the leaderboard UIDocument to Assets/Scenes/Map.unity, and updated DI/scene assets and metadata accordingly.
  • Added unit tests VisualStateConverterLeaderboardTests that validate sorting, place numbering, tie-breaking, and that country score state uses the country-score query; also added AssemblyInfo to expose internals to tests.

Testing

  • Ran unit tests with dotnet test (project tests including VisualStateConverterLeaderboardTests); all added tests passed.
  • Executed the new VisualStateConverterLeaderboardTests which assert sorting/place numbering, deterministic tie-breaking, and country score population through the converter, and they succeeded.
  • No Unity editor/play-mode automated tests were run as part of this change; UI assets and scene modifications were added for manual verification in the Unity editor.

Codex Task

KonH and others added 4 commits July 20, 2026 14:45
# Conflicts:
#	src/Game.Main/VisualStateConverter.cs
The leaderboard modal was rendering behind the HUD/map because its
UIDocument shared sortingOrder 0 with every other document and relied
on scene-authoring order to win ties. Give it an explicit sortingOrder
in code instead, per this project's own guidance not to rely on scene
ordering for stacking.

The table header wasn't scaling with the panel because .gs-panel uses
align-items: center, so header children shrank to content size instead
of stretching to the panel width — only the table header needed the
fix, the title bar stays centered by design.

Also moves the leaderboard button next to the player org panel,
fixes org/country flag aspect ratio, disables map zoom while the
window is open (full scroll-forwarding into the list is deferred),
and formats scores with thousands separators.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The close button lived inside the centered title row, so it sat next
to the title instead of at a fixed corner. Move it out to its own
absolutely-positioned element inset by the panel's own padding,
independent of the title, which stays centered.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Game.Main and Game.Configs.Loader each carried an AssemblyInfo.cs
whose only purpose was granting Game.Tests blanket access to internal
members. That's an invisible, all-or-nothing escape hatch rather than
a deliberate API decision, and it hides which members tests actually
depend on.

Flip just the members Game.Tests calls (VisualStateConverter's
constructor and Update/UpdateCountryScore/UpdateLeaderboards; Program
.ApplyPreservedFields; ProvinceProcessor.Process, plus their
containing types) to public instead, and drop both AssemblyInfo.cs
files now that nothing needs InternalsVisibleTo. Document the
preference in code_style.md so future test-only access follows the
same pattern.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@KonH
KonH merged commit 7913898 into main Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant