All files / web/src/lib/arcade/game-sdk define-game.ts

0% Statements 0/84
0% Branches 0/1
0% Functions 0/1
0% Lines 0/84

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85                                                                                                                                                                         
/**
 * Game definition helper
 * Provides type-safe game registration
 */

import type {
  GameComponent,
  GameConfig,
  GameDefinition,
  GameMove,
  GameProviderComponent,
  GameState,
  GameValidator,
} from './types'
import type { GameManifest } from '../manifest-schema'

/**
 * Options for defining a game
 */
export interface DefineGameOptions<
  TConfig extends GameConfig,
  TState extends GameState,
  TMove extends GameMove,
> {
  /** Game manifest (loaded from game.yaml) */
  manifest: GameManifest

  /** React provider component */
  Provider: GameProviderComponent

  /** Main game UI component */
  GameComponent: GameComponent

  /** Server-side validator */
  validator: GameValidator<TState, TMove>

  /** Default configuration for the game */
  defaultConfig: TConfig

  /** Optional: Runtime config validation function */
  validateConfig?: (config: unknown) => config is TConfig
}

/**
 * Define a game with full type safety
 *
 * This helper ensures all required parts of a game are provided
 * and returns a properly typed GameDefinition.
 *
 * @example
 * ```typescript
 * export const myGame = defineGame({
 *   manifest: loadManifest('./game.yaml'),
 *   Provider: MyGameProvider,
 *   GameComponent: MyGameComponent,
 *   validator: myGameValidator,
 *   defaultConfig: {
 *     difficulty: 'easy',
 *     maxTime: 60
 *   }
 * })
 * ```
 */
export function defineGame<
  TConfig extends GameConfig,
  TState extends GameState,
  TMove extends GameMove,
>(options: DefineGameOptions<TConfig, TState, TMove>): GameDefinition<TConfig, TState, TMove> {
  const { manifest, Provider, GameComponent, validator, defaultConfig, validateConfig } = options

  // Validate that manifest.name matches the game identifier
  if (!manifest.name) {
    throw new Error('Game manifest must have a "name" field')
  }

  return {
    manifest,
    Provider,
    GameComponent,
    validator,
    defaultConfig,
    validateConfig,
  }
}