5.0 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), custom audio (JailAudio), 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. Uses CMake (minimum 3.10) with C++20.
The executable is output to the project root. The data/ folder must be in the working directory at runtime.
Architecture
Boundary: Original vs New Code
The codebase has a clear separation between the original game and the new modernization layer:
| Path | Owner | Rule |
|---|---|---|
source/core/jail/ |
Original engine | Do not modify gameplay behavior |
source/game/*.cpp/hpp (except options/defines/defaults) |
Original game | Do not modify |
source/core/rendering/ |
New presentation layer | Free to modify |
source/core/input/ |
New input layer | Free to modify |
source/game/options.hpp/cpp |
New config system | Free to modify |
source/game/defines.hpp |
New constants | Free to modify |
source/game/defaults.hpp |
New defaults | Free to modify |
data/*.gif, *.ogg |
Original assets | Do not modify |
data/fonts/, data/ui/ |
New assets | Free to modify |
Original "Jail" Engine (source/core/jail/)
Flat C-style APIs (no classes), prefixed by subsystem. Do not touch gameplay logic.
- JG (
jgame) — Game loop timing: init/finalize, fixed-timestep update viaJG_ShouldUpdate() - JD8 (
jdraw8) — 8-bit paletted software renderer. 320x200 screen buffer (JD8_Surface=Uint8*), palette-indexed blitting with color-key transparency, fade effects.JD8_Flip()converts palette→ARGB and delegates toScreen::present() - JA (
jail_audio) — Custom audio mixing using SDL3 audio streams (OGG via stb_vorbis, WAV) - JI (
jinput) — Input: keyboard state polling, key debouncing, cheat code detection. CallsGlobalInputs::handle()at end of each update - JF (
jfile) — File I/O: filesystem folder mode (data/) or packed resource file (.jrf)
Presentation Layer (source/core/rendering/)
- Screen — Singleton managing SDL_Window, SDL_Renderer, SDL_Texture. Receives ARGB pixel buffer from JD8 and presents it. Handles fullscreen toggle, zoom. Prepared for future SDL3GPU backend
Input Layer (source/core/input/)
- GlobalInputs — Maps configurable function keys to window management actions (F1 zoom-, F2 zoom+, F3 fullscreen). Reads key bindings from
Options::keys_gui
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, including key bindings (
Defaults::KeysGUI,Defaults::KeysGame) - 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/) — Original, Do Not Touch
- ModuleSequence — Non-gameplay screens: intro, menu, slides, banners, credits, death screen (state=1)
- ModuleGame — Core gameplay loop, 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, 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)
Data Assets (data/)
*.gif,*.ogg,crtpi.glsl— Original game assets (do not modify)fonts/— New font assets for overlay/UIui/— New UI graphics for overlay
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.
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/jail/jgame.hpp",#include "game/info.hpp") - Headers use
.hppextension; external third-party headers insource/external/keep.h