# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview **Aventures En Egipte (AEE)** — a retro-style 2D game written in C++ using SDL3. The game uses a software-rendered 8-bit paletted graphics engine (320x200, 256 colors) with an OpenGL CRT shader pass, custom audio (JailAudio replacing SDL_Mixer), and GIF-based assets. The codebase and commit messages are in Valencian/Catalan. ## Build ```bash # Linux cmake -B build cmake --build build # Windows (MinGW) cmake -B build -G "MinGW Makefiles" cmake --build build ``` Dependencies: SDL3, OpenGL. Uses CMake (minimum 3.10) with C++20. The executable is output to the project root. The `data/` folder contains runtime assets (GIF images, OGG music, GLSL shader) and must be in the working directory at runtime. ## Architecture ### Custom "Jail" Engine Libraries (prefix: J) All engine modules are flat C-style APIs (no classes), prefixed by subsystem: - **JG** (`source/core/jgame`) — Game loop timing: init/finalize, fixed-timestep update via `JG_ShouldUpdate()` - **JD8** (`source/core/jdraw8`) — 8-bit paletted software renderer. 320x200 screen buffer (`JD8_Surface` = `Uint8*`), palette-indexed blitting with color-key transparency, fade effects. `JD8_Flip()` converts the indexed buffer to ARGB, uploads to SDL texture, and renders through the CRT shader - **JA** (`source/core/jail_audio`) — Custom audio mixing using SDL3 audio streams directly (OGG via stb_vorbis, WAV). Manages music and sound channels independently - **JI** (`source/core/jinput`) — Input: keyboard state polling, key debouncing, cheat code detection - **JF** (`source/core/jfile`) — File I/O: supports loading from filesystem folder or a packed resource file (`.jrf`). Currently uses folder mode (`data/`) - **shader** (`source/core/jshader`) — OpenGL post-processing shader (CRT effect) applied to the back buffer ### Configuration System (`source/game/`) Follows the pattern from `jaildoctors_dilemma`: - **defines.hpp** �� Game-wide constants (window title, version, screen dimensions) - **defaults.hpp** — Default values for all persistent options (audio, game) - **options.hpp/cpp** — `Options` namespace with structs, inline globals, and YAML load/save API. Config persists to `~/.config/jailgames/aee/config.yaml` (Linux), `%APPDATA%/jailgames/aee/` (Windows) ### Game Modules (`source/game/`) - **ModuleSequence** — Non-gameplay screens: intro, menu, slides, banners, credits, death screen. State machine entry point (state=1) - **ModuleGame** — Core gameplay loop. Owns and orchestrates all game objects. State=0 - **Sprite** — Base class for animated entities (frame/animation data via `Entitat`) - **Prota** — Player character ("Sam"), extends Sprite - **Mapa** — Level map with tomb grid (16 tombs), items (treasure, keys, pharaoh, mummy, scroll, diamond), door logic - **Momia** — Enemy: mummies - **Bola** — Enemy: projectile ball - **Marcador** — HUD/scoreboard - **info** — Global game state namespace (room number, pyramid, money, diamonds, lives, etc.) ### External Libraries (`source/external/`) - `gif.h` — Header-only GIF decoder - `stb_vorbis.h` — stb single-header OGG decoder - `fkyaml_node.hpp` — Header-only YAML parser (fkYAML v0.4.2) ### Main Loop (`source/main.cpp`) A state machine alternates between `ModuleSequence` (state 1) and `ModuleGame` (state 0). Each module's `Go()` returns the next state (-1 to quit). Modules are allocated/freed each transition. ### Golden Rule: Do Not Touch Gameplay The original game logic (gameplay, entities, map, scoring, collisions, animations) must remain untouched. All modernization work targets the presentation layer and infrastructure only: window management, configuration/persistence, rendering pipeline (overlay/UI), and build system. Any new feature (save states, options menu, etc.) must be implemented as an overlay on top of the existing game, never by modifying the original gameplay code. ### Key Conventions - All surfaces are 320x200 = 64000 bytes. Pixel coordinates assume this fixed resolution - Graphics loaded from GIF files, palettes extracted from GIF headers - Music files are numbered OGG files (`00000001.ogg` etc.) - `trick.ini` presence enables the secret character - Includes use absolute paths from `source/` (e.g., `#include "core/jgame.hpp"`, `#include "game/info.hpp"`) - Headers use `.hpp` extension; external third-party headers in `source/external/` keep `.h`