jv_JACQUESVAN DEN BERG
CV
All projectsDEVELOPMENT JOURNAL / Local
Web development / Social Casino

Blackjack, hidden state, and the browser I do not trust

A local social-game project exploring rooms, virtual chips and server-managed blackjack.

Explore the stack
THE SHORT VERSION

What I built.

A local social casino project.

  • Server-side blackjack engine and public-state mapping.
  • Room, account and virtual-wallet workflows.
  • Separate game-state and transaction-ledger modules.
TOOLS & RESPONSIBILITIES

Under the hood.

01

Nuxt / Vue

Table UI and server endpoints

02

Pinia

Client application state

03

Supabase

Accounts and persisted game workflows

04

TypeScript modules

Rules, public state and ledger boundaries

CONCEPTUAL IMPLEMENTATION FLOW
  1. Player action
  2. Server game rules
  3. Internal state
  4. Public-state projection
  5. Table UI
BUILD NOTES / 01

A table is a shared-state problem

A card game looks simple until more than one person needs to see the same table. Social Casino is a place to explore that deeper problem: shared state, player actions, room membership and a wallet that stays consistent with the game.

BUILD NOTES / 02

A face-down card is a data problem

The public-state mapper is one of the most interesting parts of this build. During player_turn, when the dealer has at least two cards, it returns the visible card plus an XX placeholder. It does not send the hidden card and ask the interface to cover it with a graphic.

The mapper copies the player cards and returns the phase, bet, doubled flag, outcome and payout. It exposes a remaining-card count when available, rather than the full deck. That gives the UI the information it needs without giving it the next card.

BUILD NOTES / 03

The game and the money-shaped state

The server separates the engine, persisted blackjack state, public-state mapping and ledger into different modules. That makes the boundaries visible: deciding a game result and recording a virtual-chip movement are related responsibilities, but they are not the same calculation.

The harder questions are what happens when requests overlap, a client retries, or persistence fails midway through an action. Module separation alone does not prove those cases are handled. Those are the cases I would put under focused testing before calling this ready for wider use.

BUILD NOTES / 04

Consistency before card animations

This is a local social-game build organised around virtual chips. Some surrounding areas, including leaderboard data, still use mock content. The code review is not a claim of production readiness or real-money functionality.

BUILD NOTES / 05

The lesson in progress

The interesting engineering is the consistency between the table, the player and the ledger. A polished card animation is worth much more when the state underneath it is predictable.

Public-state projection · explanatory reduction
const hideHole = phase === 'player_turn' && dealerCards.length >= 2;
const publicCards = hideHole
  ? [dealerCards[0], 'XX']
  : dealerCards.slice();
// Send the projection, not the internal deck.

Explanatory pseudocode, shortened for readability.

WRITTEN BY JACQUES VAN DEN BERGNext build: Software Platform
↑ ↓ to navigateEnter to selectEsc to close