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_CONFIGS entries.
  • 31 matchProviders map 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-114 hardcodes DB/socket/session/refresh/runtime/console credentials in ConfigMap and args.
    • gitops/platform/base/nakama/configmap.yaml:21-71,82-87 hardcodes 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 at nakama-modules/index.ts:403; no Tetris GAME_CONFIGS entry; find_match_v3 rejects missing registry at find_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-153 lists and returns the first match with no reservation; the socket joins later. Generic matchJoinAttempt rechecks 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 sends create; RPC comments/types specify quick/host/ai, but unknown strings fall into the create path. BFF does NOT forward maxPlayers. 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.

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). SDK MatchStartPayload/handler omit settings (games/_sdk/funday-bridge.ts:62-67,342-358) and BridgeOptions has no settings/error callbacks (:81-101). Shell posts funday:lobby-state host->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. Host JSON.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 postMessage itself.

6. Operations SSOT (Single Source of Truth)

  • Type: Confirmed source fact.
  • Observation:
    • gitops/apps/nakama-config.yaml: namespace funday-platform, replicas 1, hostPath modules, /healthcheck.
    • gitops/apps/full_deploy.yaml: separate namespace nakama deployment.
    • gitops/platform/base/nakama/deployment.yaml: namespace nakama, replicas 3, hostPath /home/usr/funday/nakama-modules, probe /.
    • HPA in namespace nakama targets Deployment/nakama 2-10.
    • Base kustomization includes nakama-modules-configmap but 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 in arcomage, 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 200 with 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-matchmaking unimported; no manifest selects dedicated-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_match uses matchmakerAdd and 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-platform definitions, Vault/ESO resources, and source policy checks are present and validated locally.
  • 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

IssueTarget ComponentValidation Evidence Required
Static CredentialsGitOps configsExternal secrets system implemented; historical secrets rotated.
Tetris ReachabilityRegistry & ModulesGAME_CONFIGS syncs with manifest.
Quick-match TOCTOUUI / ModulesE2E test verifying concurrent retry success.
Payload FidelityBridge / HostTyped arrays correctly dispatched over Nakama WebSocket.
Operations SSOTGitOpsRemoval of duplicate deployment definitions.

Source Index

  • nakama-modules/index.ts
  • nakama-modules/find_match_rpc.ts
  • nakama-modules/generic_match.ts
  • frontend/src/routes/api/matches/+server.ts
  • frontend/src/lib/components/games/bridge.svelte.ts
  • frontend/src/lib/components/games/drawer/messageHandlers.ts
  • games/_sdk/funday-bridge.ts
  • games/_sdk/funday-auth.js
  • gitops/apps/nakama-config.yaml
  • gitops/apps/full_deploy.yaml
  • gitops/platform/base/nakama/
  • Various funday-plugin.json manifests

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.

IssueCommit/SourceTest NameRuntime EvidenceStatus
Static credentialsVault/ESO definitions and plaintext scannernpm run check:plaintext-secretsFinal credential rotation and redacted production history/log scan are pendingSource complete / production blocked
GitOps ownershipCanonical funday-platform Nakama basenpm run check:nakama-gitopsCanonical image deployment and service/socket health are pendingSource complete / production blocked
Registry reachability and capacityManifest-generated GAME_CONFIGSnpm run check:game-registry, npm run test:integration:nakamaIsolated Nakama creates and joins a Tetris host matchSource complete
Request policy, list failures, and join raceShared contract, BFF, RPC, and admission checkFocused frontend tests; npm run test:integration:nakamaIsolated malformed/mode/list-outage/last-slot scenarios passSource complete
Bridge and identityGenerated bridge and platform session injectionnpm run check:bridge, npm run check:multiplayer-driftFinal browser reconnect proof remains pendingSource complete / production blocked
Lifecycle and dedicated handoffRuntime lifecycle and allocator pathsFocused lifecycle testsFleet allocation/release and retained session-mode smoke paths remain pendingSource 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.

Ask Docs

AI assistant to help answer questions about the documentation. Answers are read-only and cite docs/source.

Hi! How can I help you with the documentation today? Answers are read-only and cite docs/source.

Ctrl+Enter to send