Changelog
What's new in Gazino.
π° v0.9.2Chips Move Again2026-06-15
Fixes
- β’CI: make the Postgres service container correct under the self-hosted runner and safe for concurrent jobs. The `verify` job connects by service name (`postgres:5432`), so the host `ports: 5432:5432` publishing is unnecessary and would collide when multiple CI jobs run at once on the shared runner β removed it. Added a `pg_isready` service health-check so the job waits for the database before `db:migrate` (avoids an early-connect race).
- β’Build: load Geist from the local `geist` package instead of `next/font/google`. `next build` was fetching Geist + Geist Mono from Google Fonts at build time, which failed intermittently under concurrent CI (the self-hosted runner builds several projects from one egress IP and Google throttled the burst). The `geist` package self-hosts the same fonts and keeps the same `--font-geist-sans` / `--font-geist-mono` CSS variables, so the build is now hermetic (no network) and faster.
- β’Fixed a bug where bets on the public Blackjack and Roulette tables stopped moving chips: because rounds were numbered with an in-memory counter that resets when the relay restarts (or a table empties and refills), a fresh round 1 on a stable table id reused a previous round's ledger key, and the idempotent ledger correctly dropped it as a duplicate β so neither the bet nor the payout posted. Each game host now carries a unique per-instance nonce in its ledger keys, so every round is settled exactly once. (Slots and Poker already used per-spin/per-sit unique keys and were unaffected.)
β οΈ v0.9.1No Loose Chips2026-06-15
Features
- β’Engine simulation/soak harness (0.10.0 hardening): bot players drive every game β Blackjack, Roulette, Slots, and Poker β through thousands of bets, payouts, timeouts, and disconnects against an in-memory double-entry ledger and a virtual clock, continuously asserting chip conservation, per-key idempotency, and poker escrow-vs-rake accounting. Runs as a fast `node --test` invariant gate (`lib/sim`) and a configurable load runner (`npm run sim`).
Fixes
- β’Money-path hardening (0.10.0): a paid order credits chips only to the Polar customer linked at signup (never mutable order metadata); Premium now lapses on `currentPeriodEnd` even if a revoke webhook is missed; and a misconfigured billing boundary (Polar enabled without `POLAR_WEBHOOK_SECRET`) warns loudly at startup instead of silently dropping purchases. Adds a Polar-boundary test covering server-authoritative amounts and idempotent re-delivery.
- β’Blackjack and Roulette rounds in flight when the realtime relay restarts or crashes are no longer orphaned: the relay now tracks open rounds and, on boot, automatically refunds any debited stake that never settled, so chips are never silently lost. (#47)
β οΈ v0.9.0All In2026-06-15
Features
- β’Poker tables now show your recent results: each settled hand appears in the table's history panel with your net win, loss, or push. Because poker keeps per-hand results out of the chip ledger (only buy-ins and cash-outs post there), these come from the immutable hand audit, so they're accurate to the chip even across rebuys. A basic anti-collusion guard also refuses a second seat at the same table from the same connection.
- β’Texas Hold'em foundation (0.9.0): a provably-fair hand evaluator and full betting engine (blinds, four streets, side pots, rake, all-in run-outs), plus an authoritative cash-table host wired into the realtime relay β buy in for a stack, play in turn with auto-fold timers, and cash out, with each hand recorded for history and provably-fair verification. Includes reconnect grace, rebuys, and per-table stakes for private tables.
- β’Poker is now playable: Texas Hold'em cash tables are live in the lobby. The table shows the community board and pot, every seat's stack and bet, the dealer button, and a per-turn countdown; you buy in for a stack, get your hole cards privately, and act in turn with fold / check / call and a bet-or-raise slider plus one-tap all-in. Winners and rake are shown at showdown (where contested hands reveal), and you can rebuy or top up between hands and leave to cash out.
π v0.8.2Reconnect & Proxy Fixes2026-06-14
Fixes
- β’Keep your Blackjack seat across a dropped connection: the realtime client now re-claims your seat when the socket reconnects, instead of silently leaving you standing (which made bets fail at the table even though it still showed "Connected"). Roulette and Slots are seatless and were unaffected.
- β’Fixed every Server Action (daily-bonus claim, creating/joining private tables, β¦) failing with a 500 behind the production reverse proxy. The edge proxy rewrites the forwarded host, which no longer matched the browser origin, so Next.js rejected the requests as cross-origin. The app now trusts its own public origin (derived from `BETTER_AUTH_URL`) for Server Actions.
β¨ v0.8.1Table Polish2026-06-14
Features
- β’Every table now shows live countdown timers: the betting and insurance windows display a numeric countdown, and the active Blackjack seat gets a depleting turn-timer bar. Driven by the server clock β the client only renders the remaining time β so they stay accurate across reconnects and can't be gamed.
- β’The Roulette wheel now spins during betting and decelerates to land on the drawn number, and the slot reels animate to their result β purely visual, the server still decides every outcome. A new profile toggle disables game animations (defaulting off when your system requests reduced motion).
- β’Every table (Blackjack, Roulette, Slots) now shows a "Your recent results" panel listing your last rounds as win/loss/push with the signed chip delta, newest first. It's derived live from the chip ledger β no new game state β and refreshes automatically whenever your balance changes (i.e. a round settles).
- β’Private-table owners can now tune their table: per-table min/max bet and turn/betting timers (clamped server-side and applied between rounds), enforced by the game engines. Invited friends get a live join prompt in the lobby, owners can close a table on demand, a user owns at most one table (creating a new one replaces the old), and idle tables are reaped automatically.
Fixes
- β’Stabilize the realtime end-to-end test suite: cap CI parallelism so the specs no longer overload the single shared game relay, widen timing windows for bet settlement and presence, and surface a clear "Connection error" state at the table when the relay is unreachable instead of a perpetual "Connectingβ¦".
Other
- β’Wire the Kubernetes deploy for the cindevk3s cluster: ArgoCD-managed via GitOps into its own `gazino` namespace, with web + realtime exposed through an edge-nginx identity split (public `gazino.us` / `realtime.gazino.us` β internal Traefik hosts). Adds image pull secrets, fixes the migrate Job to run as a Sync hook after Postgres, and pins non-root pod security.
π v0.8.0Friends in High Places2026-06-14
Features
- β’Claim a free daily chip bonus from the lobby. Claiming on consecutive days builds a streak that grows the reward (1,000 up to 4,000 chips), and a missed day resets it. One claim per day, settled through the ledger. (Slice 2 of 0.8.0 Social & Premium.)
- β’Add friends and online presence. Search players by name, send and accept friend requests, and see which friends are online in real time. A header badge shows incoming requests. (Slice 3 of 0.8.0 Social & Premium.)
- β’A new Leaderboard page ranks players three ways β top chip balance, lifetime net winnings, and biggest single win β derived live from the ledger. Reach it from the trophy in the header; your own row is highlighted. (Slice 5 of 0.8.0 Social & Premium.)
- β’Create private invite-only tables. Premium members spin up a persistent table for any game, share its invite code or invite friends, and only members can join β enforced server-side at the relay. The first real Premium unlock. (Slice 4 of 0.8.0 Social & Premium.)
- β’Profiles are now editable: pick a display name, a preset avatar, and an accent color. Your look follows you across the app β header, lobby, and at the table in the seat list and chat. (First slice of 0.8.0 Social & Premium.)
π° v0.7.2Slots Take the Floor2026-06-14
Features
- β’Slots now runs as a live, server-authoritative game in the realtime relay (not just a core engine). Each spin debits the stake, draws the reels from the provably-fair RNG, settles the payout to the ledger, and returns a private outcome to the player; notable wins land on a shared big-win feed for the whole table. The reel UI + lobby card land in a follow-up.
- β’Slots is now playable in the app: two machines in the lobby, a 3-reel board you spin against the house, an immediate win/no-win outcome, and a shared "recent big wins" feed at the table. This completes the 0.7.0 Slots milestone (engine + host + UI).
Fixes
- β’Release tooling: the changelog's per-release commit list no longer includes the entire project history. `release.mjs` derived commits via `git describe`, but the release tag lives on `main` (the promote merge) and isn't reachable from `devel`, so it found no tag and listed everything from genesis. It now falls back to the newest tag's merge-base with HEAD.
- β’Release pipeline: fixed the GitOps image-tag bump on `main`. `release.yml` cloned with a GitHub-style `x-access-token` username, which Forgejo doesn't recognize β auth fell back to anonymous and the private repo 404'd ("Repository not found"), so `deploy/kustomization.yaml` `newTag` never auto-bumped. Now passes the token as the username (Forgejo's HTTPS token form).
π° v0.7.0Grand Opening2026-06-14
Features
- β’Accounts and the lobby shell: email/password sign-up & sign-in via BetterAuth on Postgres/Drizzle, a session-gated lobby and profile, and a header user menu. Postgres is wired into CI (with the auth E2E) and shipped as a deploy StatefulSet with a forward-only migration Job.
- β’Blackjack game core (`lib/games/blackjack`): the pure, authoritative rules engine β 6-deck shoe, soft/hard hand evaluation, and a full state machine (betting β deal β insurance β player turns with hit/stand/double/split β dealer stands on soft 17 β settlement, 3:2 naturals). Money moves are returned as ledger effects; exhaustively unit-tested. The realtime host and table UI build on this next.
- β’Blackjack is now hosted authoritatively in the realtime relay: server-clocked betting/turn windows drive the engine, the shoe is shuffled provably-fair via the table seed lifecycle, and every bet/payout posts to the double-entry ledger (balanced houseβplayer, idempotent per round β an unaffordable bet is rejected with no state change). New `bj:bet` / `bj:act` / `bj:insurance` intents and a redacted `bj:state` view (dealer hole card and the shoe are never sent). The table UI lands next.
- β’Blackjack polish: your chip balance now updates live at the table (pushed over the socket on join and after every settlement β no refresh needed), table stakes are enforced server-side (min 50 / max 5,000), and the realtime connection survives ticket expiry by fetching a fresh ticket on every (re)connect.
- β’Blackjack is playable: the table now renders the live hand β your cards and the dealer (hole card hidden until reveal), with bet controls and Hit / Stand / Double / Split / Insurance wired to the authoritative relay game. Sit down, bet, and play a full hand against the dealer in real time. Completes the first game (0.5.0).
- β’An in-app Changelog page at /changelog (linked from the footer version), generated from the same release data as CHANGELOG.md β `scripts/release.mjs` now also emits `lib/changelog-data.ts`, and CI checks the committed data stays in sync.
- β’A public provably-fair verifier at /fair: paste a revealed server seed (plus client seed and nonce) and the page recomputes the sha256 commitment and the exact shuffled shoe β entirely in your browser via Web Crypto, nothing sent to the server. A test guards that the browser derivation stays byte-identical to the engine's. Linked from each table's fairness panel.
- β’The lobby now lists joinable Blackjack tables (Blackjack shows "Live now"; other games show their target version), so the playable game is reachable in two clicks. Your chip balance is also app-wide and live: shown in the header on every page, seeded server-side, refreshed on focus, and updated the instant a hand settles β no refresh needed.
- β’Provably-fair RNG core (`lib/rng`): commit-reveal randomness (server-seed hash committed up front, plus client seed and nonce) deriving deterministic, verifiable outcomes via HMAC-SHA256 β floats, bounded ints, and a deterministic deck shuffle. The fairness foundation every game's RNG runs through.
- β’Realtime multiplayer: a standalone Socket.io relay with ticket-authenticated connections and live table rooms β sit at a seat, see other players arrive, and chat in real time at `/table/[id]`. Ships as a second container role with its own Deployment and a `useTable` client hook; Redis-adapter-ready for horizontal scale. The multiplayer transport the games sit on.
- β’Anti-abuse: the realtime relay now rate-limits each connection with token buckets β chat (~5 burst, 1/s) and game actions like seat/bet/play (~10 burst, 5/s). Excess events are dropped with a "Slow down." notice, so a flooding client can't spam the room or hammer the game loop.
- β’Roulette game core (`lib/games/roulette`): a pure European single-zero engine β colors, the full bet set (straight, red/black, even/odd, low/high, dozens, columns) with correct payouts (35:1, even-money, 2:1), and a provably-fair spin via the RNG core. Exhaustively unit-tested; the relay host and wheel UI build on it next.
- β’Roulette is now hosted authoritatively in the relay: a synchronous betting window collects bets (debited to the ledger as they're placed, balance-checked), then one provably-fair spin settles everyone and credits the winners. Tables are routed by id prefix (`roulette-*`), with new `rt:bet` intents and a public `rt:state` view. The wheel UI lands next.
- β’Roulette is playable: a betting board with the full outside-bet grid (red/black, even/odd, low/high, dozens, columns) plus straight-up numbers, a live result display, and the round's bets shown on the table. Two Roulette tables are joinable from the lobby. Completes the second game (0.6.0).
- β’Slots game core (`lib/games/slots`): a pure 3-reel, single-payline engine β a fixed 32-stop reel strip, three-of-a-kind and two-cherry payouts, and a provably-fair spin via the RNG core. Exact ~90.4% RTP, verified exhaustively over all outcomes in unit tests; the relay host and reel UI build on it next.
- β’Per-table provably-fair seed lifecycle: each table commits to a hashed server seed (with a client seed and incrementing nonce), persisted and shown in the table room; rotating the seed reveals the previous one so players can verify past outcomes. Wires the RNG core to tables β the randomness foundation the games draw from.
- β’Token economy: a double-entry chip ledger (balanced, idempotent, non-negative user wallets) with a 10,000-chip signup bonus, chip balance in the header and profile, and a `/store` for Polar token packs + Premium. Polar billing is env-guarded β webhooks credit purchases to the ledger and project Premium status; with billing unset the app runs pre-monetization with gates open.
Fixes
- β’Mobile/responsive layout: card rows at the table now wrap, page padding tightens on small screens, and the table fits a phone viewport without horizontal scrolling.
- β’The realtime relay URL is now runtime config (`REALTIME_URL`, injected per request) instead of being baked into the client bundle at build time, so one image runs in any environment without a rebuild. The table client also surfaces a clear error when it can't reach the relay, instead of hanging on "Connectingβ¦" forever.
- β’Landing page reflects reality: the game cards are data-driven, so Blackjack and Roulette show "Live now" and the rest show their target version (no more blanket "Coming soon"). Dev: a LAN IP can be allowlisted via `ALLOWED_DEV_ORIGINS` so the client hydrates when testing from another device like a phone β otherwise forms silently fall back to a non-interactive reload.
π° v0.1.0Foundation2026-06-13
Features
- β’Project foundation: Next.js 16 + Shadcn (base-nova) + Tailwind v4 + motion app that builds, lints, typechecks, and serves a casino landing page.
- β’CI/CD on Forgejo Actions (ci, build, release, security) mirroring the cs-demo pipeline, with Trivy image scanning and OSV + npm-audit dependency scanning (report-only baseline).
- β’Kubernetes deploy via Argo CD GitOps: hardened web Deployment, kustomize base, and the Argo Application/Project bootstrap.
- β’Test harness seeded: node --test unit tests and a Playwright E2E smoke, both wired into the CI gate.