| I've spent the last six months building RPS League, a live browser-based Rock Paper Scissors prediction game where a global match resolves every five seconds and every player predicts the outcome. As your point total grows it evolves through more than 50 animated progression tiers, from thousands to Trequinquagintillion (10^162), while gameplay is driven by streak multipliers, Flash Events, Global Events, cooperative World Boss raids, Player Festivals, collectible relics, over 100 achievements, optional Ascension prestige resets, competitive leaderboards, and Neon Paradise, a bonus stage system with unique interactive challenges, scaling rewards, server-generated outcomes, and sessions that persist through reconnects. Some of the frontend and system design hurdles ended up being just as engaging to solve as building the product itself: Production Infrastructure Migration (Three Managed Services to One VPS) RPS League previously ran across Vercel, Render, and Supabase as separate managed services. The entire production stack now runs on a single self-managed Hetzner Cloud VPS in Helsinki. The migration required containerizing the frontend and backend with production Dockerfiles, configuring a Caddy reverse proxy with automatic TLS certificate provisioning, restoring a live PostgreSQL 17 database from a schema-filtered pg_dump that separated application tables from Supabase-managed internals while preserving all production data, resolving SSL connection handling differences between Supabase's connection pooler and private Docker networking, and establishing automated CI/CD through GitHub Actions deploying via SCP and SSH. The VPS runs Docker Compose with isolated per-application containers, a shared PostgreSQL instance with separate databases per app, automated daily backups, and Caddy handling HTTPS across all domains automatically. The infrastructure is designed to host multiple applications on one server. Adding a new app means creating a database, a compose file, and a Caddy route. Real-Time SSE Buffering & Splicing I bypassed proxy buffering entirely by configuring my Express backend to dispatch the X-Accel-Buffering: no header, ensuring sub-second delivery of match results. To maintain active visual feedback, the main activity feed splices real user predictions and simulated traffic. Real user predictions inject instantly at index 0 of the staging queue, while a weighted generator fills the gaps during low-activity windows to ensure consistent interface motion without burying real actions. The BigInt-First Suffix Engine Because standard IEEE 754 floats lose precision beyond 9 quadrillion, compounding multipliers quickly corrupted calculations. I refactored the entire stack: unconstrained NUMERIC fields in PostgreSQL, native BigInt operations in Node, and a unified string-serialized formatter on the frontend. The engine takes large numbers, converts them to short-scale suffixes (M, B, T, up to Trequinquagintillion and beyond), and maps them directly to animated CSS visual tier classes. High-Frequency UI Ticker (100,000+ Daily Events) Handling a constant stream of ~1.2 events per second posed a risk of state thrashing and main-thread blocking. I engineered a custom event processor using React refs as a high-speed staging buffer and a 50ms interval-based update loop. By utilizing hardware-accelerated CSS (transform: translateX) and will-change: transform, the ticker maintains smooth 60fps by offloading animations to the GPU. Stateful URL Routing & Bulk Leaderboard Queries The leaderboard is a unified ranking engine supporting both Predictor and Player profiles. It maintains a stateful URL link structure, parsing parameters (tab, sort, dir) dynamically on client mount. To prevent N+1 database thrashing when rendering large lists with achievement badges, the system first pulls raw ranks, then executes a single bulk transaction to fetch and map current badge metadata in one round-trip, displaying up to 5 curated badges per row with custom row overrides (rainbow or mythical fluid animations) based on profile accomplishments. Race Conditions in Spectacle Logic (The "UI Exhaustion" Problem) In a live-service environment where matches resolve every 5 seconds, a single win can simultaneously trigger a Flash Event, an Achievement, a Relic Drop, and an Ascension prompt. Initially, these would overlap, creating UI clutter and blocking match results. I engineered a Sequential Spectacle Queue using a Zustand-based state machine that enforces a 1500ms starting gate followed by a priority-sorted execution path, distinguishing between obstructive stages (modals waiting for user action) and non-obstructive stages (achievement notifications), which flush into a vertical stack simultaneously. The main prediction loop is never interrupted for more than 3 seconds. Page Visibility Tab-Guards for Idle Predicting Completing your first prestige lap unlocks an Idle Auto-Predict mode. Because browsers aggressively throttle timeouts and intervals in hidden tabs, leaving the tab open would cause a massive backlog of auto-predictions to fire simultaneously upon tab return, flooding the API. I bound execution directly to document.visibilityState, immediately pausing all prediction handlers on hide and safely resynchronizing with the live server state upon tab focus. PWA Install Support The app ships with full Progressive Web App support. On Android and iOS, players can add it directly to their home screen for a borderless, app-like experience without an app store. Configured via manifest and the Next.js Metadata API with optimized icons and rich metadata. Securing a Low-Latency RAG Pipeline To build the interactive AI game guide, I integrated the Gemini API behind an Express endpoint with several security layers. Each request combines a TypeScript knowledge base covering the entire game system with live SQL metrics before generating a response. The endpoint applies custom local rate limiting, falls back between models if needed, detects financial cashout requests for virtual handling, and uses strict system prompts with input validation to help prevent prompt extraction and SQL injection attempts. Live Game: https://rpsleague.fi/ GitHub Repository: https://github.com/AlexDegerman/rps-league-app/ [link] [留言] |
Frontend
Read original: https://www.reddit.com/r/webdev/comments/1wekz3d/building_a_realtime_sse_app_with_react_node/
Building a real-time SSE app with React + Node: BigInt architecture, VPS migration, leaderboard optimization, PWA support, and a secure RAG pipeline
/u/Bravehood Reddit r/webdev
1 views
← Previous
[Showoff Saturday] I built HallPass to help people find conventions and plan their trips
Next →
Lost job & whole industry but save life (I hope)
Related
Why Static Mock APIs Aren't Enough for Modern Frontend Development
Frontend
1
DEV Community
Haykel Web tool - Comic to HTML5
Frontend
1
Reddit r/webdev
Both verifiers were honest, agreed with each other, and the signatures still failed
Frontend
2
DEV Community
I lost interest in programming, so I built an IMDb for dead mosquitoes
Frontend
2
Reddit r/webdev
Comments0
No comments yet — be the first