Commit Graph

11 Commits

Author SHA1 Message Date
funman300 2cfbc32715 docs: add UI-first design principle
Every player-triggered action (new game, undo, draw, pause, open any
overlay, switch mode, etc.) must be reachable from a visible UI
control. Keyboard shortcuts are optional accelerators only — never
the sole entry point. New gameplay features ship with the UI control
alongside the system that backs it.

- ARCHITECTURE.md §1 (Design Principles): add UI-first bullet.
- ARCHITECTURE.md §5 plugin table: rename "Key" column to
  "Shortcut" and add a note that the column lists optional
  accelerators, not primary entry points.
- CLAUDE.md (Bevy Conventions): add a matching hard rule.

Surfaced during smoke testing: the N+N "press again to confirm"
toast collides with the ConfirmNewGameScreen modal because the
keyboard flow is the only entry point. Adding a visible New Game
button (next commit) makes the modal the single source of truth for
the confirm flow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 21:59:38 +00:00
funman300 3ffde038c5 docs: switch asset pipeline notes to AssetServer model
CI / Test & Lint (push) Failing after 23s
CI / Release Build (push) Has been skipped
Card faces, card backs, board backgrounds, and the UI font are loaded
via Bevy's AssetServer at startup (see commit fbe984c). The CLAUDE.md
hard rule still claimed cards/backgrounds were rendered procedurally
with no AssetServer, and ARCHITECTURE.md §14 / §20 still described
PNGs and TTFs as embedded via include_bytes!(). Update both docs:

- CLAUDE.md hard rule lists which assets ship in assets/ and notes the
  Option<Res<AssetServer>> fallback used under MinimalPlugins (tests).
- ARCHITECTURE.md §2/§3/§5/§14 rewritten to describe the AssetServer
  loaders for CardImageSet, BackgroundImageSet, and FontResource, and
  the Text2d / solid-colour fallbacks.
- ARCHITECTURE.md §20 decision log replaces the two reversed
  embed-via-include_bytes!() entries with a single entry covering the
  switch to AssetServer plus a note that audio remains embedded.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 21:14:48 +00:00
funman300 0f40e717e1 docs(arch): update CardImageSet and asset pipeline for 52-face PNG system
Replace the stale single-face placeholder description with the live 52-PNG
system: CardImageSet.faces is now [[Handle<Image>; 13]; 4] indexed by
[suit][rank], face images are generated by solitaire_assetgen using ab_glyph
with rank/suit baked in, and Text2d overlays are fallback-only. Remove the
now-completed "Future art pass / texture atlas upgrade" note from Section 14.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 01:25:30 +00:00
funman300 66695683eb chore(workspace): upgrade rand 0.9, edition 2024, expand server tests
- rand "0.8" → "0.9": StdRng/SliceRandom API unchanged; 142 core tests pass
- edition "2021" → "2024" workspace-wide: no gen keyword conflicts found;
  204 tests (core + sync) pass clean with zero warnings
- ARCHITECTURE.md: Edition 2021 → Edition 2024 in header
- solitaire_server tests: add 5 new integration tests covering
  refresh-with-garbage-token, expired-refresh-token, push-without-token,
  delete-account-without-token, and leaderboard-authenticated-but-empty

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 00:36:12 +00:00
funman300 18ac5adef5 feat(engine): art pass — PNG assets, custom font, and keyring v4 upgrade
Art pass (Phase 4):
- Generate placeholder PNG assets: face.png, back_0–4.png, bg_0–4.png via
  solitaire_assetgen gen_art binary (16×16 RGBA, embedded via include_bytes!)
- Add FiraMono-Medium font (assets/fonts/main.ttf) embedded at compile time
- Add FontPlugin: loads font at startup, exposes FontResource; gracefully
  falls back to default handle when Assets<Font> absent (MinimalPlugins tests)
- Wire CardImageSet into card_plugin: face/back PNGs replace solid-colour
  sprites when available; tests continue using colour fallback via MinimalPlugins
- Wire BackgroundImageSet into table_plugin: bg PNGs replace solid-colour
  background; empty set inserted when Assets<Image> absent in tests
- Fix hint highlight system (input_plugin): tint sprite.color directly instead
  of replacing the whole Sprite (which would discard the image handle)
- Export FontPlugin, FontResource, CardImageSet from solitaire_engine::lib
- Register FontPlugin in solitaire_app before other plugins

Dependency upgrades (latest releases):
- keyring "2" → keyring "4" + keyring-core "1" (v4 split architecture into
  separate core library crate)
- auth_tokens.rs: Entry::new now returns Result; delete_password →
  delete_credential; NoDefaultStore error variant handled
- solitaire_app: add keyring::use_native_store(true) at startup for Linux
  Secret Service / macOS Keychain / Windows Credential Store selection

ARCHITECTURE.md: fix Edition 2025→2021, update asset pipeline section,
add FontPlugin/CardImageSet/BackgroundImageSet to plugin and resource tables,
update Section 14 to reflect actual include_bytes!() rendering approach,
add Decision Log entries for embedded PNG and font decisions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 00:30:55 +00:00
funman300 4997356cb5 docs(project): add README, CI workflow, migration guide, and fix asset docs
- README.md: player-facing install, controls, features, and test instructions
- .github/workflows/ci.yml: clippy + headless tests + release build on push/PR
- solitaire_server/migrations/README.md: naming convention and workflow for
  adding future schema migrations
- ARCHITECTURE.md §14: rewrite Asset Pipeline to reflect procedural rendering
  (no image files used; audio only, embedded via include_bytes!)
- ARCHITECTURE.md §2 / §13: fix workspace structure and audio file listing
- CLAUDE.md: clarify asset embedding rule (audio only; visuals are procedural)
- server_tests.rs: add auth_rate_limit_returns_429_on_11th_request test using
  build_router() (rate limiting ON) to verify the GovernorLayer is wired correctly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:41:16 +00:00
funman300 4bd562671e chore(data,engine,docs): remove Google Play Games Services sync backend
Deletes the solitaire_gpgs crate and all GPGS references from settings,
sync client, profile plugin, CLAUDE.md, and ARCHITECTURE.md. The
self-hosted server covers all sync needs without the Android-only backend.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:22:25 +00:00
funman300 735d8766a2 docs(engine): add missing doc comments on layout, ProgressPlugin; fix audio format in ARCHITECTURE.md
- Add field-level doc comments to Layout::card_size and Layout::pile_positions
- Add struct-level doc comment to ProgressPlugin
- Fix ARCHITECTURE.md Section 14: .ogg → .wav throughout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 22:37:07 +00:00
funman300 03227f8c77 feat(engine): playability improvements — rounds 7–9 (#40–#64)
Round 7 — Input & feedback
- H key cycles hints; F1 opens help (conflict resolved)
- N key cancels active Time Attack session
- Hint text distinguishes "draw from stock" vs "recycle waste"
- Forfeit (G) clears AutoCompleteState so chime does not bleed into new deal
- Zen mode timer clears immediately on Z press
- HUD shows recycle count in both draw modes
- Settings scroll position persisted across open/close

Round 8 — Polish & clarity
- Undo unavailable fires "Nothing to undo" toast
- Streak-break toast on forfeit/abandon when streak > 1
- F11 fullscreen toggle with toast; documented in help and home screens
- H-after-win, new-game countdown expiry, Tab-no-cards toasts
- Win cascade duration/stagger scales with animation speed setting
- Draw-Three cycle counter HUD ("Cycle: N/3")
- Forfeit requires G×2 confirmation within 3 s (mirrors N key)

Round 9 — Game feel & information
- Escape dismisses game-over/stuck overlay (PausePlugin skips Escape when overlay visible)
- Shake animation on rejected drag before snap-back
- Forfeit countdown cancels when any other key is pressed (U/H/D/Z/Space)
- Tab wrap-around fires "Back to first card" toast
- HUD selection indicator shows active Tab-selected pile in yellow
- Challenge time-limit HUD turns orange < 60s, red < 30s
- Win summary shows XP breakdown (+50 base, +25 no-undo, +N speed)
- Game-over overlay: "No more moves available" with clear N/Escape/G instructions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 02:35:15 +00:00
root 34ba4dc6ed feat(workspace): full server + sync implementation, all tests green
- solitaire_server: Axum auth, sync push/pull, leaderboard, daily
  challenge, account deletion, JWT middleware, rate limiting via
  tower_governor, SQLite migrations, health endpoint
- solitaire_server: expose build_test_router (no rate limiting) so
  integration tests work without a peer IP in oneshot requests
- solitaire_sync: SyncPayload, merge logic, shared API types
- solitaire_data: SyncProvider trait, LocalOnlyProvider,
  SolitaireServerClient, auth_tokens keyring integration, blanket
  Box<dyn SyncProvider> impl
- solitaire_data/settings: derive Default on SyncBackend (clippy fix)
- .sqlx/: offline query cache so server compiles without a live DB
- sqlx: removed non-existent "offline" feature flag
- keyring v2: fixed Entry::new() returning Result<Entry>
- sqlx 0.8: all SQLite TEXT columns wrapped in Option<T>
- Integration tests: max_connections(1) on in-memory pool so all
  connections share the same schema

All 191 tests pass; cargo clippy -D warnings clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 23:32:56 +00:00
Solitaire Quest 684f07746d feat(workspace): initialize all seven crates with stubs and blank Bevy window
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 11:00:42 -07:00