See the timeless reference in the Lobby, Matchmaking & Nakama.
Scope and Audit Limits
This document represents a point-in-time implementation audit of the Funday multiplayer stack, focusing on the Nakama runtime, bridge protocols, and matchmaking mechanics. Observations were made against the source repository using static analysis and control flow inspection on 2026-07-15. No deployment, live load testing, or packet-loss tests were executed.
Evidence Standard
Findings in this audit are categorized strictly as:
- Confirmed source fact: Verifiable code or configuration state present in the repository.
- Inferred impact: The logical consequence of a confirmed source fact (e.g., race conditions, reachability issues).
- Coverage gap: Missing implementations, tests, or configurations.
Note: Credential values are intentionally redacted from all findings.
Executive Scorecard
- Overall Confidence: High confidence in source findings and identified code anomalies (e.g., unvalidated RPC bounds, quick-match race conditions, and payload serialization defects). Low operational confidence because no live E2E, load, or network tests were run to observe actual runtime behavior.
Exact Inventory
- 75 game manifests.
- 36
GAME_CONFIGSentries. - 31
matchProvidersmap entries (nakama-modules/index.ts:372-405); only registry-referenced unique handlers are registered (:407-425). - 35 manifests declare
backend.nakamaProxy. - Only Agar and SisterBrawl explicitly declare
session.mode. - At least two competing Nakama GitOps families (
gitops/apps/nakama-config.yaml,gitops/apps/full_deploy.yaml,gitops/platform/base/nakama/).
Architecture Diagram
graph TD Client[Frontend Shell] --> BFF[SvelteKit BFF] Client --> Socket[Nakama WebSocket] BFF --> API[Nakama RPC API] API --> Modules[Nakama Modules] Socket --> Match[Authoritative Match] Match --> Modules
Positive Controls
The following controls are present and correctly scoped in inspected source paths, while live behavior remains unverified:
- Central socket
- Server session resolution + correlation ID
ctx.userId- Registry handler resolution
- Authoritative capacity/start/settings checks
- Source/origin bridge validation
- Session policy layer
Detailed Findings
P0: Hard Failures & Security
1. Static Credentials
- Type: Confirmed source fact / Coverage gap.
- Observation:
gitops/apps/nakama-config.yaml:20-40,103-114hardcodes DB/socket/session/refresh/runtime/console credentials in ConfigMap and args.gitops/platform/base/nakama/configmap.yaml:21-71,82-87hardcodes a second set including Redis.
- Remediation Acceptance: Require credential rotation, implement Kubernetes Secrets / external secret workflow, and conduct history/log scans. Do not expose values in configuration files.
2. Tetris Canonical Multiplayer Reachability
- Type: Confirmed source fact / Inferred impact.
- Observation: Tetris manifest declares
tetris_match; provider exists atnakama-modules/index.ts:403; no TetrisGAME_CONFIGSentry;find_match_v3rejects missing registry atfind_match_rpc.ts:39-45; registration is registry-driven. - Correct Impact: Tracked multiplayer request unsupported / provider not registered by loop. This does NOT cause an entire game launch failure.
P1: Contract & Reliability Flaws
1. Quick-Match TOCTOU (Time-Of-Check to Time-Of-Use)
- Type: Confirmed source fact / Inferred impact.
- Observation:
find_match_rpc.ts:84-153lists and returns the first match with no reservation; the socket joins later. GenericmatchJoinAttemptrechecks capacity (generic_match.ts:194-217), preventing overfill. - Correct Impact: One concurrent caller gets a late join failure; no transparent retry. (Note: Never claim over-capacity acceptance).
2. Request Policy / Schema
- Type: Confirmed source fact / Coverage gap.
- Observation: BFF accepts
matchMode ?? mode,withAI, queue, and arbitrary settings without a schema (+server.ts:210-243). Drawer sendscreate; RPC comments/types specify quick/host/ai, but unknown strings fall into the create path. BFF does NOT forwardmaxPlayers. Direct authenticated RPC can pass it; RPC uses caller value instead of registry (find_match_rpc.ts:45-47,156-170); generic init only enforces minimum (generic_match.ts:176-184).
3. Parity Drift
- Type: Confirmed source fact.
- Observation:
- Manifest vs registry
maxPlayers: Hometown 16 vs 8; Racing 8 vs 4; Merge & Defend 2 vs 4. - Merge & Defend and Settlers of Open Source are registry-only multiplayer ownership claims (no manifest proxy).
- Tetris proxy exists but registry absent.
- Overlapping handler names otherwise match.
- Manifest vs registry
4. Bridge Lifecycle / Schema Parity
- Type: Confirmed source fact.
- Observation: Host schema has match-start settings, match-settings, match-error (
bridge.svelte.ts:20-62). SDKMatchStartPayload/handler omit settings (games/_sdk/funday-bridge.ts:62-67,342-358) andBridgeOptionshas no settings/error callbacks (:81-101). Shell postsfunday:lobby-statehost->game although central schema declares it game->host. Host accepts request-match, SDK has no helper; host maps every non-AI request (including quick) to create (messageHandlers.ts:298-319).
5. Binary Payload Fidelity
- Type: Confirmed source fact / Inferred impact.
- Observation: SDK accepts
Record|string|Uint8Array(funday-bridge.ts:511-530). Structured clone supports typed arrays. HostJSON.stringifys every non-string before socket send (messageHandlers.ts:280-297), converting bytes into numeric-key JSON. - Correct Impact: The host corrupts typed arrays upon socket transmission, NOT the
postMessageitself.
6. Operations SSOT (Single Source of Truth)
- Type: Confirmed source fact.
- Observation:
gitops/apps/nakama-config.yaml: namespacefunday-platform, replicas 1, hostPath modules,/healthcheck.gitops/apps/full_deploy.yaml: separate namespacenakamadeployment.gitops/platform/base/nakama/deployment.yaml: namespacenakama, replicas 3, hostPath/home/usr/funday/nakama-modules, probe/.- HPA in namespace
nakamatargets Deployment/nakama 2-10. - Base kustomization includes
nakama-modules-configmapbut deployment mounts hostPath instead.
- Impact: State repository cannot identify one deployable truth. (Do not claim HPA is broken because an alternate Deployment exists in namespace
nakama).
7. Direct Game Authentication
- Type: Confirmed source fact / Inferred impact.
- Observation: Confirmed
authenticateDevice()source inarcomage,battle-cards,crypto-bro-empire,evolution,yazzy,_sdk/funday-auth.js, plus legacy Racing HTML. State production reachability varies and must be traced from manifests. - Impact: Split identity/session/socket risk.
P2: Architecture Drift & Test Gaps
- Match-list Error Conflation: Match-list upstream failure returns
200with empty array, conflating outage/no matches (+server.ts:112-187). - Ranked Queue Permissiveness: Ranked queue is generic but ±200 rating is only SisterBrawl; malformed/missing rating permissive (
find_match_rpc.ts:64-75,84-145). - Dedicated Routing Incompleteness: Five session modes; only two explicit; BFF allocation is active; registered Agones RPCs have no frontend caller found;
enhanced-matchmakingunimported; no manifest selectsdedicated-lobby-proxy. - Test Gaps: Real last-slot concurrency, browser offline/online authoritative resync, stale/finished invite, token expiry/refresh mid-match, match ending while away, all bridge events + typed arrays, dedicated allocation cleanup.
- Legacy Registration: Legacy
memory_find_matchusesmatchmakerAddand is registered; no active frontend caller found.
Corrective Acceptance Criteria
Phased Checklist
- Repository remediation: contracts, reachability, bridge, and policy
- Generated manifest registry reaches Tetris through the ordinary provider path.
- Typed request parsing, bounded quick-match retry, bridge byte fidelity, and direct-auth source policy have focused test coverage.
- Repository remediation: GitOps and secret-consumer definitions
- Canonical
funday-platformdefinitions, Vault/ESO resources, and source policy checks are present and validated locally.
- Canonical
- Production secret-plane migration (Blocked)
- Provision durable Vault storage, initialize/unseal Vault out-of-band, install ESO, materialize consumer Secrets, then rotate every exposed credential with health gates.
- Production Nakama cutover and retirement (Blocked)
- Deploy and validate the immutable canonical image, route traffic, remove legacy resources, and record the required live evidence.
Original acceptance matrix
This matrix preserves the 2026-07-15 audit criteria. Refer to Implementation Evidence (Local Verification) for the current repository/provisioning split.
Closure Matrix
| Issue | Target Component | Validation Evidence Required |
|---|---|---|
| Static Credentials | GitOps configs | External secrets system implemented; historical secrets rotated. |
| Tetris Reachability | Registry & Modules | GAME_CONFIGS syncs with manifest. |
| Quick-match TOCTOU | UI / Modules | E2E test verifying concurrent retry success. |
| Payload Fidelity | Bridge / Host | Typed arrays correctly dispatched over Nakama WebSocket. |
| Operations SSOT | GitOps | Removal of duplicate deployment definitions. |
Source Index
nakama-modules/index.tsnakama-modules/find_match_rpc.tsnakama-modules/generic_match.tsfrontend/src/routes/api/matches/+server.tsfrontend/src/lib/components/games/bridge.svelte.tsfrontend/src/lib/components/games/drawer/messageHandlers.tsgames/_sdk/funday-bridge.tsgames/_sdk/funday-auth.jsgitops/apps/nakama-config.yamlgitops/apps/full_deploy.yamlgitops/platform/base/nakama/- Various
funday-plugin.jsonmanifests
Implementation Evidence (Local Verification)
The repository remediation has source and isolated integration evidence as recorded below. This is not a production cutover declaration: credential rotation, ESO/Vault runtime health, immutable-image deployment, fleet allocation/release, production-safe smoke paths, and removal of old workloads require an authorized operational change window.
| Issue | Commit/Source | Test Name | Runtime Evidence | Status |
|---|---|---|---|---|
| Static credentials | Vault/ESO definitions and plaintext scanner | npm run check:plaintext-secrets | Final credential rotation and redacted production history/log scan are pending | Source complete / production blocked |
| GitOps ownership | Canonical funday-platform Nakama base | npm run check:nakama-gitops | Canonical image deployment and service/socket health are pending | Source complete / production blocked |
| Registry reachability and capacity | Manifest-generated GAME_CONFIGS | npm run check:game-registry, npm run test:integration:nakama | Isolated Nakama creates and joins a Tetris host match | Source complete |
| Request policy, list failures, and join race | Shared contract, BFF, RPC, and admission check | Focused frontend tests; npm run test:integration:nakama | Isolated malformed/mode/list-outage/last-slot scenarios pass | Source complete |
| Bridge and identity | Generated bridge and platform session injection | npm run check:bridge, npm run check:multiplayer-drift | Final browser reconnect proof remains pending | Source complete / production blocked |
| Lifecycle and dedicated handoff | Runtime lifecycle and allocator paths | Focused lifecycle tests | Fleet allocation/release and retained session-mode smoke paths remain pending | Source complete / production blocked |
Remaining operational closure
Do not declare this audit operationally closed until the authorized cutover runbook records the required live evidence: rotated credentials rejected, ESO/Vault restart healthy, canonical deployment/socket health, fleet allocation and release, retained session-mode smoke paths, old workload removal, and a final redacted secret/history/log scan.
Observed cutover blockers (2026-07-16): the live cluster has no
externalsecrets.external-secrets.io CRD, no Vault workload, and only one
node. Its sole local-path StorageClass has Delete reclaim policy, which
cannot meet the plan’s HA/durable Vault storage requirement. The
funday-platform/nakama Deployment is still the legacy
heroiclabs/nakama:3.32.0 image and has the legacy nakama-config and
nakama-modules ConfigMaps. Therefore applying the new secret-consumer
configuration, rotating credentials, or removing the legacy workload would be
unsafe until durable storage, Vault, and ESO are provisioned, then a separately
authorized migration window supplies the required live checks.