Files
aee/CLAUDE.md
2026-04-04 17:20:28 +02:00

4.4 KiB
Raw Blame History

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 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 <20><> Game-wide constants (window title, version, screen dimensions)
  • defaults.hpp — Default values for all persistent options (audio, game)
  • options.hpp/cppOptions 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