Bit
Brush
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