# AI Agent Instructions for TS-Games This document provides guidelines for AI agents working with the TS-Games project. ## Project Overview TS-Games is a custom framework/build system for creating simple single-file TypeScript games. All games compile into one standalone HTML file with no external dependencies—all assets are inlined as data URLs. ## Key Concepts ### Two Types of Applications 1. **Games** - Interactive applications with game loops - Located in `src/games//` - Entry point: `index.ts` or `index.tsx` - Default export: `runGame()` function - Use `gameLoop()` from `@common/game` for structured game development 2. **Apps** - More complex applications (like AI-Story) - Also located in `src/games//` - Entry point: `index.tsx` - Default export: `main()` function - May use Preact components and complex state management ### Single HTML File Architecture - All games build into a single `.html` file in `dist/` - No external dependencies at runtime - All assets (images, audio, fonts, WASM) are inlined as base64 data URLs - Build process uses Bun's plugin system to transform assets ## Creating a New Game ### Step 1: Create Directory Structure ```bash mkdir -p src/games//assets ``` ### Step 2: Create Entry Point Create `src/games//index.ts` or `index.tsx`: ```typescript // Simple game example (index.ts) import { gameLoop } from "@common/game"; import Input from "@common/input"; const setup = () => { // Initialize game state return { x: 0, y: 0 }; }; const frame = (dt: number, state: ReturnType) => { // Update game state state.x += Input.getHorizontal() * dt; state.y += Input.getVertical() * dt; }; export default gameLoop(setup, frame); ``` ```tsx // Preact component example (index.tsx) import { render } from "preact"; import App from "./components/app"; export default function main() { render(, document.body); } ``` ### Step 3: Add Assets (Optional) Place assets in `src/games//assets/`: - **Images**: `.png`, `.jpg`, `.jpeg` → Import as `HTMLImageElement` - **Audio**: `.wav`, `.mp3`, `.ogg` → Import as `HTMLAudioElement` - **CSS**: `.css`, `.module.css` → Import as styles - **Fonts**: `.font.css` → Import font faces - **WASM**: `.c`, `.cpp`, `.wasm` → Import as WASM module - **Icons**: `favicon.ico` → Auto-used as page icon - **PWA**: `pwa_icon.png` → Used for PWA manifest ### Step 4: Import Assets ```typescript // Import image import spritesheet from './assets/spritesheet.png'; console.log(spritesheet); // // Import audio import heal from './assets/heal.ogg'; heal.play(); // Import CSS import './assets/styles.css'; // Import CSS modules import styles from './assets/styles.module.css';
// Import WASM (C/C++) import wasmModule from './assets/game.c'; // Access exports: wasmModule.memory, wasmModule.functionName() // Import GLSL shader import shader from './assets/shader.glsl'; ``` ## Development Workflow ### Running Development Server ```bash bun start ``` Navigate to `http://localhost:3000` to see the game list. Games rebuild on each page reload. To run a specific game: ```bash bun start --game= ``` ### Building for Production Build a specific game: ```bash bun run build ``` Or select from interactive list: ```bash bun run build ``` Output: `dist/.html` ### Building with Options - `--local`: Build for local testing (no PWA, different index) - `--production`: Minify JS/CSS/HTML (default for build) ## Project Structure ``` tsgames/ ├── src/ │ ├── games/ # All games/apps live here │ │ ├── / # Individual game directory │ │ │ ├── index.ts # Entry point (required) │ │ │ └── assets/ # Game assets │ │ └── index/ # Special: game list page │ ├── common/ # Shared utilities │ │ ├── game.ts # Game loop helper │ │ ├── input.ts # Input handling │ │ ├── dom.ts # DOM utilities │ │ ├── utils.ts # General utilities │ │ ├── errors.ts # Error formatting │ │ ├── components/ # Shared Preact components │ │ ├── hooks/ # React-like hooks │ │ ├── display/ # Canvas/graphics utilities │ │ └── physics/ # Physics utilities │ └── types.d.ts # Global type definitions ├── build/ │ ├── build.ts # Build script │ ├── server.ts # Dev server │ ├── html.ts # HTML generation │ ├── isGame.ts # Game detection │ ├── imagePlugin.ts # Image bundler plugin │ ├── audioPlugin.ts # Audio bundler plugin │ ├── fontPlugin.ts # Font bundler plugin │ ├── wasmPlugin.ts # WASM bundler plugin │ └── filePlugin.ts # Generic file plugin ├── dist/ # Built HTML files └── test/ # Tests ``` ## Technical Details ### Bun Configuration - Use `bun` for all package management and script running - `.env` files are automatically loaded (no dotenv needed) - Use `Bun.serve()` for servers (not express) - Use `Bun.file()` for file operations (not fs) - Use `Bun.$` for shell commands (not execa) ### TypeScript Configuration - JSX: `react-jsx` with Preact - Module resolution: `bundler` - Path aliases: `@common/*` → `./src/common/*` - Strict mode enabled ### Asset Processing All asset processing happens at build time via Bun plugins: 1. **Images** (`.png`, `.jpg`, `.jpeg`): - Converted to base64 data URLs - Return `HTMLImageElement` that's ready to use 2. **Audio** (`.wav`, `.mp3`, `.ogg`): - Converted to base64 data URLs - Return `HTMLAudioElement` with loaded source 3. **CSS**: - Bundled and inlined in `