funman300 7a3032b74c fix(engine): scroll the modals whose content overflows the viewport
Smoke-test report: the Achievements list isn't scrollable. With 19
achievements the panel overflows the modal at the 800x600 minimum
window and the bottom rows are clipped. The same problem applies to
several other modals whose content has grown over the v0.13–v0.15
rounds.

Mirrors the existing SettingsPanelScrollable pattern from
settings_plugin: each modal's body Node gets Overflow::scroll_y()
plus a max_height (Val::Vh(70.0) for most, Val::Vh(50.0) for the
leaderboard's variable-length ranking section), a marker component
so the scroll system can find it, and a sibling system that routes
MouseWheel events into the body's ScrollPosition.

Five modals fixed:
- Achievements: 19 rows clearly overflow; AchievementsScrollable +
  scroll_achievements_panel.
- Help: ~28 reference rows overflow at 800x600; HelpScrollable +
  scroll_help_panel.
- Stats: 8-cell primary grid + per-mode bests + progression +
  weekly goals + unlocks + Time Attack readout + replay caption is
  enough content to overflow once the player has any progress;
  StatsScrollable + scroll_stats_panel.
- Profile: Sync + Progression + 14-day calendar + up to 18
  unlocked achievements + Stats summary overflows once a few
  achievements unlock; ProfileScrollable + scroll_profile_panel.
- Leaderboard: 10-row cap is at the edge of overflow on 800x600
  with long display names; LeaderboardScrollable +
  scroll_leaderboard_panel (max_height = 50vh — the ranking section
  is the only variable-length part).

Home modal NOT scrolled — five mode cards plus a Cancel button
were sized to fit at 800x600 by design and adding scroll there
would clutter the launcher.

Five new tests pin the contract: each modal's body has the
scrollable marker, a non-default max_height, and Overflow::scroll_y.

Defer-list (small UX nits surfaced during the sweep, not fixed
here):
- Modal close-on-click-outside is missing across the board; would
  need Interaction on ModalScrim in ui_modal.
- ModalButton hover doesn't set a pointer cursor.
- Tab focus on modal open is initialised on the next frame instead
  of the same frame; first Tab press selects rather than focus
  already being on the primary.

These are bigger touches than the scroll fix and don't fit a
30-LOC budget; surfacing for a follow-up round.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 23:30:04 +00:00
2026-04-29 21:59:38 +00:00

Solitaire Quest

A cross-platform Klondike Solitaire game written in Rust, with a card-theme system, full progression (XP / levels / achievements / daily challenges), and optional self-hosted sync so your stats follow you across machines.

Features

  • Klondike Solitaire — Draw One and Draw Three modes; foundations are unlocked (any Ace lands in any empty slot, the slot then claims that suit)
  • Card themes — bundled hayeah/playing-cards-assets default plus user-installable themes (drop a directory under the data dir or import a zip from Settings → Cosmetic)
  • Modern HUD — reserved top band keeps cards from crowding the score readout; the action bar auto-fades when the cursor leaves it so it can't compete with the play surface
  • Drag feel — every legal drop target is highlighted in green during drag; cards cast a soft drop shadow that lifts when picked up; the stock pile shows a remaining-count chip so you can see how close you are to a recycle
  • Keyboard navigation — Tab cycles focus through buttons, arrow keys move within picker rows, Enter activates; works across every modal and the HUD action bar
  • Progression — XP, levels, unlockable card backs and backgrounds
  • 19 Achievements — including secret ones
  • Daily Challenge — server-seeded so every player worldwide gets the same deal
  • Leaderboard — opt-in, powered by your own self-hosted server
  • Special Modes (unlocked at level 5): Zen, Time Attack, Challenge
  • Sync — pull/push stats across devices via a self-hosted server
  • Color-blind mode — blue tint on red-suit cards alongside the suit glyph

Building

Prerequisites

  • Rust stable toolchain (rustup install stable)
  • Linux: libasound2-dev libudev-dev libxkbcommon-dev
  • macOS: Xcode Command Line Tools
# Fast development build
cargo run -p solitaire_app --features bevy/dynamic_linking

# Release build
cargo build -p solitaire_app --release
./target/release/solitaire_app

Controls

Every action also has a visible UI button — keyboard shortcuts are optional accelerators.

Key Action
Left click / drag Move cards
Double click Auto-move card to its best legal destination
Right click Highlight legal moves for a card
Space / D Draw from stock
U Undo
H Hint (highlight a legal move)
N New game
Z Zen mode
G Forfeit (during pause)
Tab / Shift+Tab Cycle keyboard focus
Enter Activate focused button / auto-complete (when badge is lit)
Esc Pause / dismiss modal
F1 Help / controls
F11 Toggle fullscreen
S / A / P / O / L / M Stats / Achievements / Profile / Settings / Leaderboard / Menu

Card themes

The default theme ships embedded in the binary, so the game runs self-contained with no external assets. To install another theme, drop a directory containing a theme.ron manifest plus 53 SVG files (52 faces + 1 back) under the platform data dir's themes/ folder, or import a zip from Settings → Cosmetic. The picker chip lights up the moment a new theme is registered. Themes are SVG-based, so they rasterise cleanly at whatever resolution the window happens to be.

Sync Server (optional)

To sync stats across machines, run the self-hosted server. See README_SERVER.md for setup instructions.

Once the server is running, open Settings → Sync Backend, enter the server URL and your username, and register an account from within the game.

Running Tests

# All tests (982 passing as of v0.11.0)
cargo test --workspace

# Just game logic (no display required)
cargo test -p solitaire_core -p solitaire_sync -p solitaire_data -p solitaire_server

# Lint
cargo clippy --workspace --all-targets -- -D warnings

Credits

Built on Bevy and the wider Rust ecosystem (Tokio, Axum, sqlx, Serde, kira, and many more). Card faces come from hayeah/playing-cards-assets (MIT, derived from the public-domain vector-playing-cards library); the default card back is original work; the UI font is FiraMono-Medium (OFL). All audio is synthesized programmatically by this project. See CREDITS.md for the full list and license details.

Changelog

See CHANGELOG.md.

License

MIT — see LICENSE.

S
Description
A Klondike solitaire game built in Rust with Bevy, targeting Android and Linux desktop. Features classic card rendering, draw-one/draw-three modes, score tracking, undo/redo, daily challenges, and auto-complete detection.
https://klondike.aleshym.co/
Readme MIT 45 MiB
v0.39.0 Latest
2026-05-19 23:58:42 +00:00
Languages
Rust 95.7%
JavaScript 1.9%
HTML 1.3%
CSS 0.5%
Shell 0.4%
Other 0.2%