Template Structure Contract
This document defines the expected folder structure and contracts for a game integrating the Genius Engine. Strict adherence allows platform tooling and Genies to reliably parse and update your codebase.
1. Expected Structure
A typical Genius-powered game (funday/games/<game-id>/) MUST adhere to the following architecture:
games/<game-id>/
├── funday-plugin.json # Core manifest + Genius metadata
├── README.md # Quickstart and local dev notes
├── client/ # Svelte 5 / Threlte Application
│ ├── src/
│ │ ├── components/ # Dumb UI, bound to unifiedGameState
│ │ ├── state/ # game-mode.svelte.ts, unifiedGameState definitions
│ │ ├── bridge/ # FundayBridge initialization and hooks
│ │ └── lib/ # Shared logic and utilities
├── server/ # Nakama Go Logic
│ ├── match_handler.go # Authoritative match loop
│ ├── rpc_genie.go # genie_ingest_state, genie_inject_event
│ └── bot/ # Server-side AI logic
└── docs/ # Genius Documentation Pack
├── fun-stack.md # The instantiated design stack
├── perspectives.md # Accessibility and UX lenses
└── audits/ # Deep Roast reports2. Boundaries
- The Svelte Boundary: UI components inside
client/src/components/must be utterly ignorant of network status. They map properties purely fromunifiedGameState. - The Server Boundary: The
server/logic must not trust the client. All actions must be validated, and hidden state must be scrubbed before broadcast. - The Docs Boundary:
docs/is the single source of truth for the game’s intent. Code changes should ideally be preceded by updates to the Fun Stack or Perspectives.
3. Acceptance & Verification
- Criteria: The repository physically matches the logical contract.
- Verify: Running
tree games/<game-id>matches the expected folders, andfunday-plugin.jsonaccurately points todocs/fun-stack.md.
- Verify: Running
4. Rationale & Anti-Patterns
Why this specific structure?
The structure forces a decoupled game model. By placing UI components inside client/src/components/ and the network layer in client/src/bridge/ or client/src/nakama/, the visual representation can be mocked easily in isolation.
Common Anti-Patterns
- The God Component: A single
Game.sveltefile that imports Nakama, handles user input, sets state, and renders the WebGL canvas. Why it fails: It cannot be simulated inlocalmode easily. - Hidden State in Components: Storing a player’s
hpaslet hp = $state(100)directly inside aPlayerHUD.sveltecomponent. Why it fails: A Genie observer cannot read this state since it is not bound tounifiedGameState. - Skipping the Docs Directory: Failing to maintain
docs/fun-stack.mdalongside code updates. Why it fails: The codebase drifts from the design intent, making AI-driven audits and cross-team communication significantly harder.
5. Maintenance Best Practices
- Keep the
funday-plugin.jsonup to date with any changes to theentryPointor requestedleaderboards. - Continuously integrate Deep Roast feedback into the
docs/audits/folder. - Review the
perspectives.mdafter every major feature addition to ensure no UX regressions.
6. Directory Naming Conventions
To maintain a predictable workspace, ensure that nested directories also follow strict lower-kebab-case naming.
components/: Pure visual Svelte components. No complex state or network logic.bridge/: Logic that explicitly wraps or interfaces withFundayBridge.nakama/: Client-side Nakama RPC calls, match state parsing, and networking glue.bot/: The offline AI or practice dummy logic, mimicking real player payloads.
Any deviation from this structure makes it significantly harder for automation to locate components, increasing the onboarding friction for new developers.