Collaborative full stack project · Realtime game systems
DuckyArena
Realtime 3v3 Duckie battles where hidden lane strategy and technical answers decide a server-authoritative best-of-three match.
Six authenticated players join a private room, form BLUE and RED teams, select distinct Duckies, secretly claim three lanes and reveal three simultaneous 1v1 matchups. Correctness, response timing and Signature Abilities feed a deterministic combat engine; the first team to win two lanes takes the match.
ReactViteNode.jsExpressSocket.IOPostgreSQLDockerGitHub Actions

Overview
DuckyArena is a competitive realtime 3v3 web game built from a collaborative academic foundation and later taken through a structured professionalization pass.
The current slice connects a snapshot-driven React interface to Express, Socket.IO and PostgreSQL. It covers the complete six-player private-room flow from Duckie selection and hidden TOP, MID and BOTTOM deployment through combat, persisted results and profile statistics.

Challenge and solution
The academic base contained useful full stack pieces, but they did not yet communicate one dependable game experience. The challenge was to connect authenticated identity, hidden pregame decisions, three concurrent combats and durable results without allowing clients to become gameplay authorities.
The professionalization pass established a server-authoritative match lifecycle, separated persistent REST concerns from live Socket.IO gameplay and projected only player-authorized information into each snapshot. A focused presentation pass then gave the flow a coherent farm-arena identity without changing game rules.
Gameplay flow
BLUE and RED each contain three authenticated players. Every team assigns exactly one player to TOP, MID and BOTTOM; rival assignments remain hidden until all lanes are locked and the server reveals the three independent duels. The first team to win two lanes wins the match, and an unresolved third lane becomes CANCELLED.
- Authenticate
- Create or join a private room
- Assemble six players
- Choose a Duckie
- Lock a lane in secret
- Reveal three matchups
- Resolve realtime combat
- Persist result and profile statistics


Server authority and realtime architecture
React renders catalog, room, match and profile projections and sends player intentions. Express handles durable identity, profile and catalog concerns; Socket.IO manages the authenticated live match lifecycle. The backend remains the authority for every gameplay outcome.
React + ViteRenders per-player snapshots and submits player intentions.Express RESTHandles durable identity, profile and catalog concerns.Socket.IOCoordinates authenticated rooms, pregame and live combat.Domain modulesResolve deterministic combat and authoritative match state.PostgreSQLPersists identity, completed results and profile statistics.
- Authenticated player identity is independent from socket IDs.
- Per-player projections preserve rival information before reveal.
- Three isolated lane combats resolve into one best-of-three match.
- Active rooms, timers and combat live in one Node.js process.
My contribution · Professionalization
Built on a collaborative academic foundation, I took the current implementation through a structured professionalization pass spanning:
Realtime backend and domain
Stabilized authenticated Socket.IO identity, private-room and pregame lifecycles, hidden-information projections, three-lane orchestration and deterministic server-authoritative combat.
Data and persistence
Integrated bcrypt/JWT identity with PostgreSQL and transactional, idempotent storage for one match and its six participants, plus authenticated aggregate profile statistics.
Frontend and gameplay integration
Connected the React flow from authentication and room entry through selection, reveal, combat, result and profile, using server snapshots as the source of truth.
Quality and reproducibility
Consolidated regression coverage, GitHub Actions, PostgreSQL initialization and migration checks, Dockerized services, health checks and a stack smoke test.
Visual and game feel
Defined the visual system and presentation layer for four Duckies, hidden lane strategy, matchup reveal, duel combat and match results while keeping gameplay and backend rules frozen.
Engineering decisions
Server authority
Decision: Clients submit intentions; the backend validates and resolves outcomes.
Trade-off: The backend owns more lifecycle complexity and must remain available during a match.
REST and Socket.IO split
Decision: REST serves durable concerns; Socket.IO serves the live match.
Trade-off: Authentication and errors must remain aligned across both boundaries.
Player identity beyond sockets
Decision: Sockets bind to authenticated profiles rather than becoming player identities.
Trade-off: Membership and reconnection require explicit identity reconciliation.
Per-player projections
Decision: Snapshots contain only information each player may know.
Trade-off: Projection code and secrecy regression tests add complexity.
Deterministic combat
Decision: Canonical inputs and explicit rules resolve answers, timing, abilities and sudden death.
Trade-off: Visual feedback must follow authoritative snapshots rather than predict effects.
Live memory, durable results
Decision: Active combat remains in one process; completed results persist in PostgreSQL.
Trade-off: A process restart loses active matches and the live state cannot scale horizontally.
Visual and game-feel professionalization
The functional product initially communicated its quiz mechanics more strongly than its competitive-game structure. The presentation pass introduced four coherent Duckie identities, a fighting-game-inspired character select, an illustrated three-lane farm arena, authoritative matchup reveal, duel-focused combat HUD and a conclusive best-of-three result screen.
Assets describe the world. React describes current state. Backend decides truth. Visual feedback amplifies authoritative events but never changes damage, timing, cooldowns, secrecy or match resolution.
Quality and evidence
The finished slice is supported by automated backend, frontend, database and delivery checks plus one manually verified real six-player flow.
- 64 backend tests covering authentication, pregame, secrecy, combat, abilities, three-lane resolution, reconnect, persistence and statistics.
- Backend lint, frontend lint and production build checks.
- GitHub Actions jobs for backend, frontend, PostgreSQL integration and Docker reproducibility.
- Clean PostgreSQL initialization and explicit historical migration verification.
- Docker Compose health checks and an automated stack smoke test.
- Five captures from one authoritative match verified with six real authenticated players.
- Browser E2E is not automated; the full visual flow was verified through targeted real-client and harness checks.
Outcomes and limits
Outcomes
- Connected the academic components into one coherent end-to-end product slice.
- Established explicit authority and secrecy boundaries for realtime multiplayer interactions.
- Made completed results durable and profile statistics queryable after Node.js restarts.
- Turned local setup and critical validation into reproducible Docker and CI workflows.
Architectural limits
- Matches require exactly six players in private rooms.
- Active live state exists in one Node.js process.
- A process restart loses active matches.
- The realtime layer does not support horizontal scaling.
- No public deployment is available.
