roast2d 0.4.0

Roast2D is a homebrew 2D game engine
Documentation
# AGENTS

Roast2D Game Engine - LLM Agent Guide

This document provides project structure, conventions, and workflows for AI agents working on Roast2D.

## Core Rules

- **TDD**: Write tests before fixing bugs
- **Coordinate System**: XY plane, X increases left→right, Y increases bottom→up, origin at (0.0, 0.0)
- **Version Consistency**: Always check version numbers in skills/ match Cargo.toml
- **Skills First**: Use skills/ documentation for implementation details before guessing
- **Update Agent and skill**: Update AGENTS.md and skills/ when making changes, especially new features

## Project Structure

```
roast2d/
├── src/lib.rs              # Root crate (re-exports from roast2d_internal)
├── crates/
│   ├── roast2d_internal/   # Core engine implementation
│   ├── roast2d_macro/      # Proc-macros (hotreload macro)
│   └── roast2d_dylib/     # Dynamic linking for hotreload
├── examples/
│   ├── 2d/                 # 2D examples (breakout, shapes, text, etc.)
│   └── 3d/                 # 3D examples (cube, pbr, skybox, gltf, instancing, etc.)
├── assets/                 # Shared assets (fonts, textures)
├── benches/                # Benchmarks
├── tools/                  # Maintenance scripts
│   ├── check.sh           # Full CI check
│   ├── check-examples.sh  # Run all examples
│   └── validate-skills.sh # Skills format validation
├── skills/                 # LLM agent knowledge (basic-usage, egui, hot-reload)
└── AGENTS.md              # This file
```

## Naming Conventions

- **Camera2D** / **Camera3D** — 2D and 3D cameras respectively
- **Draw2D** / **Draw3D** / **Draw3DPbr** / **Draw3DSkinned** — 2D, 3D, PBR, and skinned draw commands
- **Material3D** / **PbrMaterial** — Blinn-Phong and PBR materials
- **InstancedDraw3D** — GPU instanced 3D rendering
- **SkinnedMesh3D** / **AnimationPlayer** — Skeletal animation

## Rendering Architecture

Core rendering in `crates/roast2d_internal/src/renderer/`:

- **shader2d/** — 2D pipelines (`default.rs`, `solid.rs`, `circle.rs`, `line.rs`), batching (`render.rs`), 2D runner (`runner.rs`)
- **shader3d/** — 3D mesh draw types (`draw3d.rs`), 3D runner (`runner.rs`)
- **post/** — Post-processing pipelines (`screen.rs`, `retro.rs`)
- **driver.rs**`RenderDriver`: orchestrates frame (Skybox → 3D → Instanced → PBR → Skinned → 2D world/UI → post)
- **traits.rs**, **resource.rs** — Shared shader traits, texture cache/upload

3D-specific modules in `crates/roast2d_internal/src/`:
- **mesh3d.rs**`Mesh3D`, `SkinnedMesh3D`, `Mesh3DShader`, `Mesh3DInstancedShader`, `Mesh3DPbrShader`, `SkinnedMesh3DShader`
- **skeleton.rs**`Skeleton`, `Bone`, `Animation`, `AnimationPlayer`, `BoneTransform`
- **light3d.rs**`Light3D`, `LightKind`, `Material3D`, `PbrMaterial`
- **skybox.rs**`Skybox`, cubemap rendering

High-level engine presentation state: `crates/roast2d_internal/src/render.rs`

## Key Workflows

### Development Cycle

1. **Explore Code**: Use examples/ as reference for patterns
2. **Check Skills**: Consult skills/ for domain knowledge (egui, hotreload, etc.)
3. **Write Tests**: Follow TDD - tests before implementation
4. **Validate Locally**:
   ```bash
   cargo check --all
   cargo test --workspace
   ./tools/validate-skills.sh  # If editing skills/
   ```
5. **Run Full Check**:
   ```bash
   ./tools/check.sh  # Format + tests + clippy + WASM build
   ```

### Running Examples

```bash
# 2D examples
cargo run --example breakout              # 2D game (examples/2d/)

# 3D examples
cargo run --example shapes3d              # 3D primitive shapes with lighting
cargo run --example pbr                   # PBR materials (metallic-roughness)
cargo run --example skybox                # Cubemap skybox
cargo run --example gltf_loading          # glTF/GLB model loading
cargo run --example skeletal_animation    # Skeletal animation from glTF
cargo run --example instancing            # GPU instanced rendering

# Feature examples
cargo run --example egui_showcase --features egui  # UI examples
cargo run --example hotreload --features hotreload  # Live code editing
```

### When to Use Skills

- **basic-usage.md**: Scene lifecycle, core API, coordinate system, basic drawing
- **3d-rendering.md**: 3D meshes, cameras, lighting, PBR materials, skybox, glTF loading, instancing, skeletal animation
- **egui.md**: Immediate-mode UI panels, widgets, customization
- **hot-reload.md**: Dynamic library swapping, live code editing setup

**Note**: Skills contain implementation details. AGENTS.md contains project structure and workflows.

## Essential Commands

| Command | Purpose |
|---------|---------|
| `cargo fmt --all` | Format code |
| `cargo check --all` | Quick type check |
| `cargo test --workspace` | Run tests |
| `cargo clippy --workspace --all-targets` | Linter checks |
| `./tools/check.sh` | Full CI check (format + tests + clippy + WASM) |
| `./tools/check-examples.sh` | Run all examples to verify they work |
| `./tools/validate-skills.sh` | Validate skills/ format |

## Feature Flags

- `egui` — Enable egui immediate-mode UI integration
- `hotreload` — Enable dynamic library hot reloading (pulls in `dynamic_linking`)
- `dynamic_linking` — Internal flag for hotreload support

## Common Patterns

### Adding a New Example

1. Create `examples/2d/new_feature.rs` or `examples/3d/new_feature.rs`
2. Implement `Scene` trait
3. Add entry in `Cargo.toml` under `[[example]]` with correct path
4. Document in skills/ if it introduces new patterns

### Adding a New Skill

1. Use `skills/.template.md` as base
2. Include "Use this skill when" trigger statement
3. Link to relevant examples/
4. Add cross-references to related skills
5. Run `./tools/validate-skills.sh` to verify

### Fixing a Bug

1. Write a failing test demonstrating the bug
2. Run test to confirm it fails
3. Fix the issue
4. Verify test passes
5. Run `./tools/check.sh` before committing

## Platform-Specific Notes

- **WASM**: Build target is `wasm32-unknown-unknown`, no dynamic linking
- **Desktop**: Supports hotreload on macOS (.dylib), Windows (.dll), Linux (.so)
- **Assets**: Located at project root `assets/`, loaded via `Engine.assets`