Add important files reminder to AGENTS.md

This commit is contained in:
Thomas
2026-03-01 09:51:17 +00:00
parent 9af9f65aaf
commit dbb507bfd2

174
AGENTS.md Normal file
View File

@@ -0,0 +1,174 @@
# 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 |