- MusicToggle: global floating button (enable/disable music from any screen;
hidden on the table, which has its own audio control in its HUD). Uses
sound-store toggleMusic.
- Card sounds now use a synthesized card-draw "swish" (filtered noise burst with
a downward sweep) for cardPlay (+ soft landing tap) and deal (a flurry),
replacing the old beep tones.
Verified: tsc + next build pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds ~100 new purchasable gifts that are LOCKED until a level/rating gate is met,
then buyable with coins — value scales with the gate:
- 45 gift avatars (types.ts), 35 gift titles + 20 gift card backs (gamification.ts),
all reusing existing renderers. Tier (1-5) encoded in the id (-t<n>-).
- Gate model: GIFT_TIERS (shared) → reqLevel/reqRating on AvatarDef/TitleDef/
CardBackDef + ShopItem. Tiers: t1 free, t2 Lv10, t3 Lv20, t4 Lv35, t5 Rating1700.
- Shop UI: locked cards dim + show the requirement (Lock + "Level 20"), buy
disabled until met; mock buyItem enforces it offline.
- Server enforces generically — ProfileService parses the tier from the id and
checks the player's level/rating (no 100-entry mirror). Mirrors GIFT_TIERS.
- i18n shop.reqLevel/reqRating (fa+en).
Verified: tsc + sim + next build + dotnet build all pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 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>
- Daily reward now routes through the global CelebrationOverlay: new "daily"
variant + coins count-up; claiming closes the daily modal and fires
celebrate({variant:"daily", coins}). Unifies the "you earned X" moment.
- Premium (pro) gold chat is now visible to the OTHER player: ChatMessage gains
senderPro; server resolves each participant's plan once (SocialService.IsPro)
and stamps it on ChatMessageDto; ChatScreen styles incoming bubbles with
.premium-chat when senderPro. Mock marks ~half its friends pro so it's visible
offline too.
Verified: tsc + next build + dotnet build all pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- MatchIntroOverlay: UNO-style pre-game reveal — the 4 seats animate into the
table (with "?" placeholders until each player's data streams in for live
matches), a 3-2-1-GO countdown, then the table shows. Wired via game-store
matchIntroPending/consumeIntro, rendered online-only in GameScreen.
- Fix: intro.found / intro.getReady / intro.go existed only in the Persian dict;
added the English strings (would have shown raw keys to EN users).
- Checkpoint of the in-progress UI/social batch (CoinsPill, shop titles section,
friend-request rate limit, etc.) — all green.
Verified: tsc + next build + scripts/sim.ts + dotnet build server/Hokm.slnx all pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Single source of truth for any agent/session continuing the project: run
instructions (dev + Docker stack), architecture, the client<->server
gamification sync rule, full feature status, CI/CD + Nexus HTTP-mirror cert
workaround, gotchas, and the TODO list.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Forfeit penalty reworked (client + server gamification, in sync):
- Surrendering team loses DOUBLE the entry coins; winner takes the stake.
- Forfeiter earns NO XP. No kot is applied or mentioned anymore.
- MatchSummary/Dto carry a `forfeit` flag; GameRoom.FinalizeForfeit →
ApplyRewardsAsync(team) with Forfeit=true (dropped the kot path).
- Forfeit confirm dialogs now alert the real penalty (double coins, no XP).
End-of-game roster: SeatPlayerDto/ServerSeatPlayer + game-store SeatPlayer gain
userId/isBot. New <MatchPlayersList> lists everyone at the table on the final
screen (PostMatchRewardsModal + AI MatchOverlay) with a tactile "Add" button to
send a friend request to real (non-bot, non-self) players ("Sent" after).
Verified: tsc + sim + dotnet + next build clean; stack rebuilt :1500/:1505.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Lobby: the two hero actions (random / create room) are now tactile press-3d
rounded-3xl with tinted icon chips.
- Matchmaking: seat slots use the Avatar frame with a gold border when filled
(dashed placeholder when empty + spring pop-in); cancel/start/upgrade buttons
are tactile.
- Profile: added a level badge on the avatar (casual-game style).
Verified: tsc + next build clean; web rebuilt :1500.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- New global celebration system: celebration-store (queue) + CelebrationOverlay
(animated: count-up XP, filling bar, level-up pop, achievement cards; plays
levelUp/award sounds; tap or auto-dismiss). Rendered in page.tsx.
- Shop: every purchase now celebrates — XP packs animate XP gain + level-up,
cosmetics show a "purchased!" pop. Newly-unlocked achievements (diffed from
the profile before/after) animate too.
- XP purchases now actually evaluate achievements: gamification.evaluateAchievements
(client) + Gamification.EvaluateAchievements (server, called in ShopBuy xp path)
unlock level milestones + grant their coins.
Verified live: buying XP took L1→L5, unlocked level_5 server-side and credited its
reward. tsc + dotnet + next build clean; images rebuilt :1500/:1505.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Answers "what's in this pack / how much XP": shop items now carry contents
(sticker ids / emojis), xp amount, and a fa/en description. Cards are tactile
(press-3d), show the artwork + name + a quick hint (item count or +XP) + price,
with an owned check badge. Tapping a card opens a detail sheet that shows the
full contents (every sticker/emoji rendered), the XP granted, a description,
and a Buy button (gold when affordable, "need coins" otherwise).
Verified: tsc + next build clean; web rebuilt :1500.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The HTTPS Nexus serves an incomplete cert chain that container trust stores
reject (NU1301 PartialChain / UNABLE_TO_GET_ISSUER), failing CI restore/install.
- NuGet has no strict-ssl flag → point CI + Dockerfile + compose at the plain-HTTP
Nexus (http://171.22.25.73:8081, allowInsecureConnections) — no TLS, no cert check.
- npm: add --strict-ssl=false to the CI web-check install (Dockerfile already had it);
Docker npm registry default also moved to the HTTP Nexus.
- ENV_FILE.example documents NUGET_INDEX/NPM_REGISTRY overrides.
Local dev (Windows trusts the cert) + image base pulls (Docker trusts it) are
unaffected — only in-container package feeds switch to HTTP.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Keep the Persian-luxury palette, adopt casual card-game UX:
- New .press-3d primitive (solid underside that compresses on tap, reduced-motion
aware) for tactile buttons.
- Home: a large glowing hero "Play online" button (Play icon + chevron), a
tactile vs-computer card, and chunkier mode tiles with color-tinted icon chips
(teal/sky/gold/rose). All handlers + i18n unchanged.
Verified: tsc + next build clean; web rebuilt :1500.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Grounded in the two installed design skills:
- Safe-area insets (notch/home-bar): .safe-top/.safe-bottom/.safe-x helpers
applied to the game-table HUD + bottom hand + reaction button, and to
ScreenShell + HomeScreen (covers Profile/Shop/Leaderboard/etc.).
- Touch targets ≥44px: table HUD buttons (mute/forfeit/exit) and the reaction
button now meet the 44/48px minimum.
- HUD readability: seat name/level labels (which float over the felt) get a
text-shadow (.hud-shadow) and stronger contrast.
Verified: tsc + next build clean; web image rebuilt on :1500.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The mock emitted random "a friend is online / event is live" notifications on a
35s timer and the live service forwarded them. Dropped both — only real
notifications now fire (friend requests, achievements, daily reward, payment,
match-ended, and server hub events).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- XP packs in the store (coin-priced, intentionally expensive): xp1 200/5k,
xp2 600/12k, xp3 1500/25k. Consumable (grant XP, can level up) — server
ShopBuy handles kind "xp" via an authoritative XpPacks map + Gamification.GrantXp;
mock mirrors. New shop section + shop.xp/xpHint i18n.
- Every game grants XP and the WINNER earns 2x: matchXp is now
base*(won?2:1)*leagueFactor (was a flat +80 win bonus). Mirrored server-side.
- Premium (pro) perks: 1.5x XP multiplier (applied in applyMatchResult /
ApplyMatch by plan), plus animated shimmering gold chat bubbles for your own
messages (premium-chat CSS; ChatScreen gates on plan).
Verified: tsc + next + dotnet build clean; sim passes; live server — buying xp2
took L1→L3 and deducted 12k coins under the new curve. Images rebuilt :1500/:1505.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cosmetics — many new variants, the rarer ones gated behind higher ranks:
- Card backs: +midnight/jade/onyx (buy) + crimson/aurora/obsidian/imperial
(earned by wins/rating up to Master). Card fronts: +sunset/velvet/onyx (buy)
+ goldleaf/crystal/imperial (earned).
- Titles: +marksman, untouchable, sweeper, ruler, platinum_star, diamond_ace,
immortal, the_one (gated by kots/streak/shutouts/hakem/rating/level/wins),
mirrored on the server so live games grant them.
- Avatars: list expanded + rank/wins-earned tier (robot/wizard/ninja/king/
genie/crown) via new ownedAvatarIds(); profile picker shows earned ones,
shop sells the priced ones.
- Stickers: new Persian-text stamp pack (کوت! / دمت گرم / باریکلا / آخه؟) plus a
rank-earned Victory pack (بردیم!/حکم) — new inline-SVG art.
Leveling: XP per level now grows (100*l + 15*l²) so each level is harder; higher
leagues grant more XP (×1.5 at 500 stake, ×2 at 1000) so you progress by playing
up. Hard cap at level 100. Mirrored in server Gamification (XpForLevel/MatchXp/
AddXp). Sim now tops out lower (level 20 vs 35 over 500 matches) as intended.
Verified: tsc + next build + dotnet build clean; sim passes; images rebuilt :1500/:1505.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Leaderboard: each row now shows the player avatar (photo or emoji) with a level
badge ring and a progress-to-next-level bar (LeaderboardEntry gained
levelProgress + avatarImage; mock fills real XP for you, random for others).
Mobile table: the played-card pile now scales inward on narrow screens so it no
longer overlaps the opponents' side stacks (trickScale by viewport); seat
avatars render above the stacks (z-20) so the side player isn't hidden; side
hands nudged to the edges + top hand raised slightly on phones.
Verified: tsc + next build clean; web image rebuilt on :1500.
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>
Achievements (client + server mirror, metric-driven so the list is one source):
- 37 achievements across 6 categories (Victories, Kot, Streaks, Levels, Ranks,
Veterancy) incl. 7–0 sweeps, kot milestones (1/5/10/25/50/100), win streaks
(3/5/10/15), level milestones every 5 (5..50), rank floors, games/tricks.
- New AchievementsScreen with category tabs, progress bars, coin + sticker-unlock
badges, and unlocked/locked states; summary header (unlocked count + coins).
- Some achievements unlock sticker packs: Seven–Zip→Hokm, 25 Kots→Taunts,
100 Wins→Persian (ownedStickerPackIds now also honors profile.unlocked).
- Prestige titles added: Expert, Professional, Captain, Leader (+ existing).
- Tracks new stat shutoutWins; MatchSummary.shutout (7–0). Profile shows a
6-item preview + "view all" link.
Leagues: 3 ranked entry tiers — Starter (100, lvl1), Pro (500, lvl10),
Expert (1000, lvl20). Higher league stakes more, so wins/losses swing bigger;
kot bonus now scales to the stake (40%). OnlineLobby shows league cards with
level gating.
Profile photo upload gated to level 25 (client button + server Update guard).
Win animation: PostMatchRewardsModal now shows an animated coins-won count-up
hero on a win.
Verified: dotnet build + tsc + next build clean; sim unlocks 26 achievements
over 500 matches; live server grants first_win/first_kot/shutout_1 and pays
2050 coins on an expert-league shutout+kot win. Images rebuilt on :1500/:1505.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Leaving the table (back button, browser/hardware back) no longer resets the
game — it minimizes it and stays resumable:
- game-store: add `paused` + minimize()/resume(). Single-player (AI) matches
pause their local timers so nothing happens while away; live (server-run)
matches keep streaming via the still-active subscription (the .NET GameRoom
already runs the match to completion and re-broadcasts state on reconnect).
- GameScreen: an unmount effect minimizes any in-progress match no matter how
you leave; only a finished match (reward dismissed) tears down.
- ResumeGameBar: floating "return to game" pill shown from any screen while a
match is alive, or while a finished match still has an unseen reward.
- page.tsx: after a full reload, re-enter live mode (minimized) when the server
re-broadcasts state, and notify when a match you left finishes while away.
Verified: tsc + next build clean; web image rebuilt and serving on :1500.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
body is overflow:hidden (to lock the game table), so a min-h-dvh shell just
expands past the viewport and is clipped — its overflow-y-auto never engages.
Make ScreenShell + HomeScreen fixed-height h-dvh scroll containers (with
overscroll-contain + bottom padding). Fixes Profile/Friends/Shop/Leaderboard/
Lobby/BuyCoins/Notifications and the home menu on short viewports.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Issues found bringing the stack up locally and fixed:
- Server was loopback-only inside the container (appsettings "Urls=localhost"
wins over ASPNETCORE_URLS) → published port returned "empty reply". Force the
bind with command-line args: ENTRYPOINT dotnet Hokm.Server.dll --urls 0.0.0.0:5005.
- Web image: npm install crashed on alpine ("Exit handler never called"); root
cause was UNABLE_TO_GET_ISSUER_CERT_LOCALLY — the Nexus mirror serves a partial
chain that Node's CA bundle can't complete. Use npm ci + strict-ssl=false.
- .NET restore hit the same partial chain (NU1301 PartialChain). Both registries
are now build ARGs (NUGET_INDEX / NPM_REGISTRY) defaulting to the HTTPS mirror
(CI runner trusts it); local .env overrides to the plain-HTTP Nexus
(http://171.22.25.73:8081) which has no TLS. NuGet feed is generated inline with
allowInsecureConnections so .NET 10 accepts the HTTP source.
Verified on local Docker (Postgres-backed): db+server+web all healthy; API + web
reachable from host on 1505/1500; auth → profile (1000 coins) → friend add/accept
(bidirectional) → chat (unread) all 200; rows persisted in Postgres
(Profiles=2, Friends=2, Messages=1).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pipeline (.gitea/workflows/ci-cd.yml), all images/packages via Nexus mirror:
- CI api-build: dotnet restore/build server/Hokm.slnx + run Hokm.Sim (rules).
- CI web-check: npm install + tsc --noEmit + next build (static export).
- deploy (self-hosted): pre-deploy pg_dump backup, rollback image tag, build,
bring up db -> server -> web with stop+rm+up --no-deps (no force-recreate,
no bare compose down), health-wait each, prune.
Local stack (docker-compose.yml), ports in 1500-1600 so it coexists with manual
dev on 3000/5005: web :1500 (nginx static) -> server :1505 (.NET) -> db :1510
(postgres, named volume + backups). Dockerfiles: server (.NET, NuGet via
nuget.docker.config, binds 0.0.0.0, busybox wget healthcheck) + web (Next static
export -> nginx, NEXT_PUBLIC_* baked as build args). nginx.conf SPA fallback.
Config: server CORS is now config-driven (Cors__Origins) so the deployed web
origin is allowed without code edits. deploy/ENV_FILE.example documents the
Gitea ENV_FILE secret; DEPLOY.md covers setup/run/LAN-IP/rollback/migrations.
Fonts: switch Vazirmatn + Plus Jakarta Sans from next/font/google (build-time
Google fetch -> fails on the Iran CI runner) to self-hosted @fontsource-variable
packages. Build is offline and ~3x faster; 7 woff2 emitted into out/.
Verified locally: dotnet build slnx + Hokm.Sim (300 matches, exit 0); tsc clean;
next build clean with self-hosted fonts.
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>
- ZarinpalService (request/verify) + /api/coins/pay/request (JWT) and
/api/coins/pay/callback (verify → credit via ProfileService.BuyCoins → redirect
back with ?pay=success); merchant id from config (sandbox default)
- Client buyCoins (live) returns the StartPay redirect URL; BuyCoinsScreen
redirects; page.tsx handles the ?pay return (notify + refresh)
- Verified: sandbox request returns a real StartPay URL
- Documented Cafe Bazaar (Poolakey) / Myket IAB as the required store payment path
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>
- EF Core (SQLite dev / Postgres prod via config); ProfileRow JSON blob +
LedgerRow audit; EnsureCreated at startup
- C# Gamification port (ranks/elo/coins/xp/achievements/titles) → server
computes match rewards; ProfileService (get/update/plan/buyCoins/applyMatch)
- JWT endpoints: profile GET/PUT, plan, coins packs/buy, match/result;
auth upserts the profile
- Tested end-to-end (buy + ranked win+kot persisted & server-computed)
- Client still mock-backed for now (wiring is the next step)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Coins only matter for ranked: free games (vs computer / private friend rooms)
cost nothing; random ranked requires an entry (stake), gated by balance →
routes to buy-coins when short
- Buy Coins page (CoinPack/getCoinPacks/buyCoins; mock credits now, real
Zarinpal/IDPay TODO); TopBar coins → buy; lobby create-room is Free
- Friends: removed instant red ✕ delete; UserMinus → inline confirm before remove
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- AuthScreen: phone+OTP is the only active method; email & Google shown as
disabled "coming soon" buttons (until SMTP/Gmail are configured)
- GameTable responsive: compact scoreboard, smaller seat avatars, and
turn-indicator/timer positions tuned for small screens
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- PlayerHand measures viewport and compresses the fan (responsive card size +
dynamic overlap) so all 13 cards are visible and tappable on phones — no
off-screen cards, no horizontal scroll; added tap feedback
- globals: html/body overflow-x hidden + overscroll-behavior none
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Myket (root) proxies Central + Google/AGP; Abrha
(mirror.abrha.net/repository/maven/) is Central-only → used as fallback
- build.gradle + gradle-mirror.init template list both; APK rebuilds clean
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Myket mirror serves maven2 layout at root https://maven.myket.ir (proxies
Maven Central + Google/AGP); android/build.gradle uses it
- gradle-mirror.init.gradle template injects the mirror into all modules and
pins build-tools 36 + Java 17 (this env lacks build-tools 35 / JDK 21)
- ANDROID.md updated with the exact working build command
- Produces app-debug.apk (~4.5 MB)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Next static export (output: export) wrapped by Capacitor; appId
com.bargevasat.app, appName «برگ وسط»
- android/ native project + @capacitor/app; hardware back handled by
CapacitorBack (back a screen, exit at home)
- npm scripts (cap:sync, android:open, android:apk), ANDROID.md
- Gradle Maven-mirror init-script template (dl.google.com/Maven Central are
blocked in Iran — same reason NuGet is mirrored)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Name + tagline («بازی حکم آنلاین») across i18n (app.title/subtitle),
layout metadata, PWA manifest, app icon, package name, server health
- Gameplay term «حکم» unchanged; repo/folder stay hokm/HokmPlay
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>
- @microsoft/signalr client implementing OnlineService: REST auth, hub
matchmaking, server-driven game state (onState), play/trump, reactions;
delegates not-yet-server-backed features (profile/friends/shop/chat/rooms)
to the mock. Selected via NEXT_PUBLIC_USE_SERVER=1 (NEXT_PUBLIC_SERVER_URL)
- game-store live mode: enterServerMatch + applyServerState (maps server DTO,
hides opponent hands, tally + SFX), inputs route to the hub; no local engine
- MatchmakingScreen auto-enters the live match when the server signals ready
- Verified end-to-end via scripts/live-test.mjs (auth -> hub -> match -> state)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ui-store syncs screens to history (push on go/goGame, hash URLs like #/profile),
back() = history.back(), initHistory anchors a home base + restores deep links
- page.tsx listens to popstate; resolveScreen() guards transient screens
(game/room/chat/matchmaking fall back to home when their state is gone)
- ScreenHeader + ChatScreen back buttons use history back; chat cleans up on unmount
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
HUD mute is a master toggle (sound effects + music) via sound-store.toggleAll;
icon reflects fully-muted state.
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>
Card design:
- Separate cardFront + cardBack (each own/equip independently)
- Fronts: classic (free), ivory/rosegold (buy), parchment/mint (earned)
- Backs: classic (free), sapphire/emerald (buy), ruby/royal (earned)
- PlayingCard `front` prop; table applies front to all faces, back to opponents
- Profile has front + back pickers; shop has both sections
Audio:
- Web Audio synth engine (no asset files): SFX for card/deal/trump/trick,
win/lose, message, notify, award, levelup, purchase, kot + ambient music
- Toggles in profile (Audio) + mute button in game HUD; prefs persisted
- Wired across game-store, rewards, daily, shop, chat
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Reactions/emotes in-game: tray of owned emojis + animated per-seat bubbles
(feature named "شکلک / Sheklak"). Packs: starter (free), champion/legend
(earned by rating/wins), emotions/taunt (purchasable in shop)
- OnlineService.sendReaction/onReaction; mock echoes you + random opponents
- Fix: human hakem's 5 cards were blurred behind the trump-chooser overlay —
raise hand to z-50 during choosing-trump so cards stay readable
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>