# AGENTS.md — JNR Engine

## Important Files

Before starting any task, always read:
- **DESIGN.md** — Game design document with vision, mechanics, and level plans
- **TODO.md** — Current roadmap and next tasks to implement

## Project Overview

2D side-scrolling platformer (run-and-gun) written in C11 using SDL2, SDL2_image, and SDL2_mixer.
Binary: `jnr`. Targets Linux (native), WebAssembly (Emscripten), Windows (MinGW cross-compile).

## Build Commands

```bash
make              # Release build (Linux) → ./jnr
make run          # Build + run
make debug        # Debug build: -g -O0 -DDEBUG
make DEBUG=1      # Alternative debug flag
make web          # WASM build → dist-web/
make web-serve    # WASM build + HTTP server on :8080
make windows      # Cross-compile → dist-win64/
make clean        # Remove all build artifacts
```

Compiler flags: `-Wall -Wextra -std=c11 -I include -I src`

There are no test or lint targets. Verify changes by building with `make` and confirming zero warnings.

### Cross-platform prerequisites

- **WASM builds** require the Emscripten SDK. The `emsdk/` directory in the project root is
  gitignored; source the environment before building:
  ```bash
  source ~/emsdk/emsdk_env.sh   # or wherever emsdk is installed
  make web
  ```
- **Windows cross-compilation** requires MinGW (`x86_64-w64-mingw32-gcc`) and vendored
  SDL2 development libraries in `deps/win64/` (also gitignored).

## Project Structure

```
include/             Global headers (config.h)
src/
  engine/            Engine subsystems (.c/.h pairs): physics, tilemap, entity, camera, etc.
  game/              Game logic (.c/.h pairs): player, enemy, level, levelgen, editor, etc.
  util/              Header-only utilities: vec2.h, darray.h
  main.c             Entry point, game mode switching, level transitions
assets/
  levels/            .lvl level files (plain text)
  sounds/            .wav/.ogg audio
  sprites/           PNG spritesheets
  tiles/             Tileset PNGs
web/                 Emscripten HTML shell
```

Engine code lives in `src/engine/`, game code in `src/game/`. Each subsystem is a `.c`/`.h` pair.
Header-only utilities use `static inline` functions.

## Code Style

### Formatting
- **4 spaces** for indentation (no tabs in source; Makefile uses tabs)
- **K&R brace style**: opening brace on same line
- Pointer declaration: `Type *name` (space before `*`)
- `const` for input-only pointer params: `const Tilemap *map`
- No-parameter functions use `void`: `void physics_init(void)`
- Unused parameters: `(void)param;`

### Naming Conventions
| Kind | Convention | Example |
|------|-----------|---------|
| Functions | `snake_case`, module-prefixed | `player_update()`, `tilemap_load()` |
| Types/Structs | `PascalCase` | `Entity`, `PlayerData`, `Tilemap` |
| Enums | `PascalCase` type, `UPPER_SNAKE` values | `EntityType` / `ENT_PLAYER` |
| Macros/Constants | `UPPER_SNAKE_CASE` | `MAX_ENTITIES`, `TILE_SIZE` |
| Static (file-scope) vars | `s_` prefix | `s_gravity`, `s_renderer` |
| Global vars | `g_` prefix | `g_engine`, `g_spritesheet` |
| Local vars | Short `snake_case` | `dt`, `pos`, `em`, `tx` |
| Function pointer types | `PascalCase` + `Fn` | `EntityUpdateFn` |

### Includes
Order within each file:
1. Own module header (`"game/player.h"`)
2. Other project headers (`"engine/physics.h"`, `"game/sprites.h"`)
3. Standard library (`<stdlib.h>`, `<string.h>`, `<math.h>`)
4. SDL headers (`<SDL2/SDL.h>`)
5. Platform-conditional (`#ifdef __EMSCRIPTEN__`)

Paths are forward-slash, relative to `src/` or `include/`: `"engine/core.h"`, `"config.h"`.

### Comments
- **Section headers**: `/* ═══...═══ */` box-drawing block
- **Subsections**: `/* ── Name ──────── */` light-line style
- **Inline/doc comments**: `/* ... */` (C89-style, not `//`)
- **Struct field comments**: trailing, aligned with whitespace padding

### Header Guards
```c
#ifndef JNR_MODULE_H
#define JNR_MODULE_H
...
#endif /* JNR_MODULE_H */
```

### Types
- `float` for positions, velocities, timers, physics (not `double`)
- `Vec2` (float x, y) for all 2D quantities
- `bool` from `<stdbool.h>`
- `uint16_t` for tile IDs; `uint32_t` for bitfield flags and seeds
- `SDL_Color` for colors; `SDL_Rect` for integer rectangles

### Error Handling
- Return `bool` for success/failure
- Return `NULL` from creation functions on failure
- Errors to `stderr` via `fprintf(stderr, "...")`
- Info to `stdout` via `printf(...)`
- Warnings use `"Warning: ..."` prefix
- Early return on failure; no goto-based cleanup

### Memory Management
- `calloc(1, sizeof(T))` for entity data (zero-initialized)
- `free(ptr); ptr = NULL;` in destroy callbacks
- `memset(ptr, 0, sizeof(*ptr))` for struct re-initialization
- Fixed-size arrays for most collections (entity pool, tile defs)
- Dynamic allocation only for tile layers (`uint16_t *`)
- `snprintf` / `strncpy` with explicit size limits for strings
- `ASSET_PATH_MAX` (256) for path buffers

## Architecture Patterns

### Entity System
- Fixed pool of `MAX_ENTITIES` (512) in `EntityManager`
- Dispatch tables: `update_fn[type]`, `render_fn[type]`, `destroy_fn[type]`
- `void *data` for type-specific data (cast in callbacks)
- Each entity type: `_register()` sets callbacks, `_spawn()` creates instances
- Entity registry maps string names to spawn functions for level loading

### Module Pattern
- Public API: declared in header, module-prefixed (`camera_init`, `camera_follow`)
- Private helpers: `static` in `.c` only
- File-scope state: `static` variables with `s_` prefix
- Forward declarations to break circular includes

### Level System
- `.lvl` files: plain-text directives + tile grid data
- `level_load()` for handcrafted levels from files
- `level_load_generated()` for procedural levels from `Tilemap` structs
- Exit zones trigger transitions; target strings: file path, `"generate"`, `"generate:station"`, or empty (victory)
- Procedural generator: segment-based, theme-driven, difficulty-scaled

### Rendering
- Sprite batching: submit to queue via `renderer_submit()`, flush layer-by-layer
- Draw layers: BG → entities → FG → particles → HUD
- Camera transforms world coords to screen coords

## Commit Messages
- Imperative mood, concise
- No co-authored-by or AI attribution
- Example: "Add in-game level editor with auto-discovered tile/entity palettes"

## Key Constants (config.h)
| Constant | Value | Notes |
|----------|-------|-------|
| `SCREEN_WIDTH` | 640 | Logical resolution |
| `SCREEN_HEIGHT` | 360 | |
| `TILE_SIZE` | 16 | Pixels per tile |
| `TICK_RATE` | 60 | Fixed timestep Hz |
| `DEFAULT_GRAVITY` | 980.0f | px/s² |
| `MAX_ENTITIES` | 512 | Entity pool size |
| `MAX_ENTITY_SPAWNS` | 128 | Per-level spawn slots |
| `MAX_EXIT_ZONES` | 8 | Per-level exit zones |
