Add important files reminder to AGENTS.md
This commit is contained in:
174
AGENTS.md
Normal file
174
AGENTS.md
Normal 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 |
|
||||||
Reference in New Issue
Block a user