UNPKG

@hiddentao/clockwork-engine

Version:

A TypeScript/PIXI.js game engine for deterministic, replayable games with built-in rendering

87 lines (67 loc) 5.29 kB
# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. This project is a browser-based game engine focused on deterministic, replayable games. The `./docs/engine.md` file contains a high-level overview of the engine and coding guidelines that should be adhered to for anyone building games with this engine. ## Project Overview Clockwork is a TypeScript game engine focused on deterministic, replayable games with platform-agnostic rendering. It provides deterministic game loops, recording/replay functionality, spatial collision systems, and a complete 2D rendering system with GameCanvas, AbstractRenderer, and BaseRenderer classes. ## Build System & Commands - **Package manager**: Bun - **Build**: `bun run build` - Compiles TypeScript to dist/ - **Development**: `bun run dev` - Watch mode compilation - **Testing**: `bun test` (watch with `bun test --watch`) - **Linting**: `biome check .` (fix with `biome check --write .`) - **Demo**: `bun run demo` - Runs Vite dev server in demo/ directory ## Architecture Overview ### Core Systems - **GameEngine**: Abstract base class providing game state management (READY/PLAYING/PAUSED/ENDED), object registration, and deterministic updates - **GameRecorder**: Captures user inputs and object updates for later replay (recording only - does not execute) - **ReplayManager**: Handles playback of recorded game sessions with frame-accurate determinism - **InputManager**: Abstracts input handling between live and recorded sources via InputSource interface - **PRNG**: Seeded random number generator using 'alea' package for deterministic behavior - **Timer**: Frame-based timer system with async callbacks (replaces setTimeout/setInterval) - **Serializer**: Universal serialization with type registration for all parameter types ### Rendering System The rendering system uses a platform-agnostic rendering layer that abstracts the underlying graphics implementation. The current implementation uses PIXI.js through the WebPlatformLayer, but the design supports alternative rendering backends. The system provides three main components: - **GameCanvas**: Abstract canvas class that manages: - Platform layer integration for rendering, audio, and input - Game engine integration with automatic update loops - Event handling for user interactions - Viewport management (drag, zoom, pan) with configurable limits - Canvas resizing and responsive behavior - Game layer initialization through `setupRenderers()` method - **AbstractRenderer<T>**: Generic base class for rendering game objects, providing: - Platform-agnostic DisplayNode management (add/update/remove/setItems methods) - Generic typing for specific game object types (T extends GameObject) - Helper methods: `createRectangle()`, `createCircle()`, `createPolygon()`, `createBorderRectangle()`, `createStandardNode()` - Abstract methods: `create()` for initial setup, `getId()` for object identification - Optional `repaintNode()` method for dynamic updates with needsRepaint optimization - **BaseRenderer**: TypeScript interface defining the renderer contract: - Standard methods: `add()`, `update()`, `remove()`, `setItems()` - Ensures consistent renderer API across implementations ### Key Patterns - Frame-based deterministic updates (not delta-time based) - GameObject type registry: objects self-register by type string, engine manages groups automatically - Manual recording requirement: developers must explicitly call recordObjectUpdate() for direct object changes - Strict separation of recorded inputs vs live inputs via InputSource abstraction - Event-driven architecture with GameEventType enum (USER_INPUT, OBJECT_UPDATE) - Universal serialization supporting primitives, arrays, objects, and custom classes with serialize/deserialize methods ### Directory Structure - `src/` - Main engine source code - `src/geometry/` - Vector math, collision detection, spatial utilities - `src/enums/` - Game state and event type definitions - `src/rendering/` - GameCanvas, AbstractRenderer, BaseRenderer classes - `demo/` - Example implementation using SnakeGameCanvas and renderer classes - `tests/` - Unit tests for core systems ### Dependencies - **Runtime**: pixi.js (2D graphics through WebPlatformLayer), pixi-viewport (viewport/camera), alea (seeded PRNG) - **Development**: TypeScript, Biome (linting/formatting), Bun (runtime/testing) ## Development Guidelines - All game objects must extend abstract GameObject class and implement getId(), getType(), serialize() - Objects self-register with engine in constructor: engine.registerGameObject(this) - Custom classes need serialization support: serialize() method and static deserialize() method - Tests use Bun's built-in test runner. Run specific test files with `bun test path/to/file.test.ts`. - Pixi.js - .devdocs/pixi.txt - Always use bun as the package maanger - don't auto-run demo and/or engine dev server - never bypass pre-commit hooks when doing a git commit - always check for package.json for lint and format commands and use the commands defined in there - use "bun run lint" to lint, "bun run lint:fix" to fix lint errors, and "bun run format" to format code, look in package.json for other scripts