- One running game per player: server rejects a 2nd matchmake while in a live
room (re-syncs the existing game); client guards Home vs-computer + Lobby
random/create — resumes the running match + notifies instead of starting another
(game-store hasActiveMatch()).
- Background music is now selectable: santoor (سنتی, calm Persian loop) and
playful (bouncy UNO-like) — sound.ts TRACKS + setMusicTrack (persisted),
sound-store musicTrack, picker in Profile → Audio. i18n added.
- Production config for bargevasat.ir (prepare-only; no live deploy):
appsettings.Production.example (CORS + ZarinPal + IAB to the domain),
docker-compose.caddy.yml + Caddyfile (auto-HTTPS reverse proxy
bargevasat.ir→web, api.bargevasat.ir→server), ENV_FILE PRODUCTION block,
PRODUCTION.md go-live + Cafe Bazaar publish/IAB checklist. Fixed IAB package
name to match Capacitor appId (com.bargevasat.app).
Verified: tsc + next build + dotnet build all pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Achievements: generator-driven, now 100+ across 7 categories (added Rulership)
mirrored client + server with identical ids/goals/coins. New tracked stats:
hakemRounds (be the hakem — incl. "7× Hakem"), roundsWon, plus losses metric.
Custom achievement-only sticker packs (Rulership 👑, Firestorm 🔥) with new
inline-SVG art (crown-gold, seven-zip, streak-fire), unlocked by hakem_7 /
streak_10. Server GameRoom tallies hakem rounds per seat + rounds won per team;
client tallies the same for vs-computer/private games (dealId-deduped).
Forfeit (surrender): a player can request forfeit; if the teammate is a bot it
auto-confirms, otherwise the human teammate gets a confirm/decline prompt
(20s timeout). Result: forfeiting with ≥1 round won = normal loss; 0 rounds = Kot.
Wired client↔server over the hub (RequestForfeit/ConfirmForfeit/DeclineForfeit
+ "forfeit" event); offline/vs-computer ends immediately in the store. Flag
button + confirm dialogs in the table.
Online count: never shows below 50 — live service floors the real count with a
drifting believable number (mock base lowered to ~50–170).
Matchmaking: real players get a longer priority window (9s) before bots fill;
bots now occasionally react after winning a trick (humanize).
Coins: starter pack is 95,000 Toman (50k coins); packs rescaled up (server + mock).
Verified: dotnet build + tsc + next build clean; sim unlocks 57 achievements/500
matches; live server: starter=95000, a 7-hakem win unlocks hakem_7 + wins_1 with
hakemRounds/roundsWon persisted. Images rebuilt on :1500/:1505.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Social: EF-backed friends graph + chat (SocialService/SocialModels);
REST endpoints (friends add/accept/decline/remove/list/requests,
chat conversations/messages/send) with real-time hub events
(friendRequest/social/chat). GameManager tracks online users for presence.
- Client SignalrService: friends + chat now hit the server and react to
hub events (refetch + emit); no longer delegated to the mock.
- IAB: /api/coins/iab/verify endpoint + IabVerifyReq for Cafe Bazaar/Myket
(token verification is a documented TODO pending store accounts/SKUs).
- Persistence: EF Core Design package + DesignTimeDbContextFactory (Postgres),
Program auto-migrate/EnsureCreated, appsettings.Production.json.example
with Supabase connection + live ZarinPal template.
Verified end-to-end (two users, SQLite dev): request -> accept ->
bidirectional friends, chat send with per-user fromMe, unread count +
read-on-fetch. Server + client builds clean (dotnet build, tsc, next build).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Server:
- daily (/api/daily, /api/daily/claim) + shop (/api/shop/buy) + ChargeEntry
- GameRoom (via IServiceScopeFactory) deducts ranked entry at match start and
applies match rewards at match-over, broadcasting profile + reward over the hub
- tested: daily, shop (owned-guard), ranked entry deduction pushed over hub
Client:
- SignalrService routes profile/coins/plan/daily/shop/match to the server (Bearer);
onProfile/onReward hub events; guest/offline fall back to local
- session-store syncs profile from hub; game-store serverReward; GameScreen shows
live ranked reward from hub (no double submit), submits client-run games
- single source of truth in live mode (no economy divergence)
Postgres-ready via config (Provider=postgres); EnsureCreated for now.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- OnlineService.getOnlineCount(); mock random-walks a believable number,
SignalrService reads GET /api/stats/online (server tracks hub connections)
- Home screen badge with pulsing dot, polls every 8s, localized digits
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- server/ monorepo: Hokm.Engine (C# port of TS engine+AI, validated by sim),
Hokm.Server (SignalR GameHub, in-memory matchmaking/rooms, server-side turn
timers + bot fill + disconnect handling, per-seat state broadcast), Hokm.Sim
- JWT dev auth (OTP 1234 + email); CORS for the Next client; /hub/game
- NuGet restored from mirrors (Soroush Nexus + Liara); NuGetAudit off
- README + .NET .gitignore; static class Engine renamed Rules (namespace clash)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>