BitBrush

Multiplayer pixel canvas

under the hood

scroll to explore
Browser REST Controller @RestController WebSocket STOMP broker Services Pixel · Banking Postgres

Architecture

  • Painted locally first for instant feedback, then persisted and broadcast server-side
  • Full canvas state delivered on first subscribe — late joiners never miss a pixel
  • Anonymous multiplayer via client-generated UUID — no sign-up required
  • Cloudflare Turnstile blocks bots without interrupting painters
placement log — pixel (12, 7)
placed 2:01 pm
placed 2:03 pm
× erased 2:05 pm
placed 2:08 pm ← now
MAX(placed_at) → derives current state

Append-only canvas

  • Every pixel placement appended to the log — no updates, no deletes
  • Current state derived via MAX(placed_at) — last writer wins
  • Eraser writes palette index 0 — erasing without destroying history
  • Full history enables stats, author tracking, and future canvas replay
+1
Earn
Every 3 seconds
Max 25 banked
Connected only
−1
Spend
Per pixel placed
Atomic deduction
Partial batch OK

Thread-safe banking

  • ConcurrentHashMap.compute() — atomic balance check-and-deduct, no locks
  • Immutable BankState record eliminates partial-mutation bugs
  • Drag-painting with low balance: partial batch placed, not rejected outright
  • Per-user balance pushed via WebSocket — bank bar always in sync