4.4 KiB
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
# 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 viaJG_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 <20><> Game-wide constants (window title, version, screen dimensions)
- defaults.hpp — Default values for all persistent options (audio, game)
- options.hpp/cpp —
Optionsnamespace 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 decoderstb_vorbis.h— stb single-header OGG decoderfkyaml_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.oggetc.) trick.inipresence enables the secret character- Includes use absolute paths from
source/(e.g.,#include "core/jgame.hpp",#include "game/info.hpp") - Headers use
.hppextension; external third-party headers insource/external/keep.h