Files
projecte_2026/CLAUDE.md

11 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.


Projecte 2026 - Nuevo juego (derivado de JailDoctor's Dilemma)

IMPORTANTE: Este repositorio parte del código de JailDoctor's Dilemma como base, pero es un juego nuevo. projecte_2026 es un nombre placeholder hasta tener el diseño final. Gran parte de la arquitectura documentada más abajo describe el código heredado; varios subsistemas se van a reescribir.

Cambios de diseño previstos respecto al juego original

  1. Habitaciones más grandes — aprovechar el espacio del marcador (scoreboard) para ampliar el área jugable. Esto implica revisar la resolución de canvas, el layout de la HUD y el tamaño de los tilemaps.
  2. Nueva física del jugador HECHO — Player reescrito con pipeline de 6 fases, colisiones tile-based, ~20 métodos eliminados.
  3. Motor de colisiones por tiles HECHOTileCollider con queries directas al grid. Collision tilemap editado desde el editor (tecla 7). Sistema antiguo de superficies preservado pero no usado. Pendiente: tiles kill (5) y conveyor (6).
  4. Transición de pantalla animada HECHO — Scroll con easing cubicInOut (0.5s), ambas rooms visibles, enemigos activos, jugador puede moverse durante la transición.
  5. Paleta Amstrad CPC — subir de la paleta actual (8-bit indexada limitada) a la paleta del Amstrad CPC (27 colores / más colores que la actual). Afecta a PaletteManager y a todos los assets de color.

Estado del renombrado

Se han renombrado las referencias de JailDoctor's DilemmaProjecte 2026 y jaildoctors_dilemmaprojecte_2026 en código, configs, Makefile, CMake, LICENSE, Info.plist, scripts, locales, etc. Copyright actualizado a 2026. Se han mantenido como placeholders:

  • La clave de locale jaildoctor: en data/locale/*.yaml y su uso en source/game/scenes/ending2.cpp (es contenido de juego, pendiente de rediseño).
  • El publisher jailgames (carpeta de config de sistema: ~/.config/jailgames/projecte_2026).
  • Los archivos release/windows/jdd.rc y jdd.res (solo bundlean el icono).

Pendiente

  • PaletteColor enum en utils.hpp sigue con los 16 índices antiguos (ZX Spectrum). Los índices 0-4 coinciden con CPC, pero 5+ mapean a colores diferentes (ej. PaletteColor::BRIGHT_RED=5 ahora renderiza MAGENTA en CPC). stringToColor() y SPECTRUM_REFERENCE en palette_manager.cpp tampoco están actualizados. Falta decidir cómo migrar cuando se vea el resultado visual.
  • Tile 6 (conveyor) no soportado aún en el nuevo motor de Player.
  • next()/previous() en PaletteManager desactivados de facto (solo 1 paleta). Posible futura reutilización para ciclar modos de ordenación.

Overview

Projecte 2026 is a retro-style 2D puzzle platformer game built in C++20 using SDL3 for graphics and audio. The game features 60+ rooms, collectible items, enemies, and an achievement system. It targets multiple platforms (Windows, macOS, Linux) with a focus on retro aesthetics and precise collision detection.

Language: C++20 Graphics: SDL3, OpenGL Audio: SDL3 + custom jail_audio library Build: CMake 3.10+ Game Canvas: 256x192 pixels (retro resolution)


Build Commands

Initial Setup & Build

# From project root
mkdir -p build
cd build
cmake ..
cmake --build .

Rebuild After Changes

# From build directory
cmake --build .

# Or from project root
cmake --build build

Clean Build

# From build directory
cmake --build . --clean-first

# Or from project root
cmake --build build --clean-first

Run the Game

# Executable is placed in project root
./projecte_2026

Important: The build directory is build/ relative to the project root and the output executable is placed in the project root directory.

Testing in Headless Environment (SSH/Remote Server)

IMPORTANT: When working on a remote server via SSH without a physical display, the game MUST be run using Xvfb (X Virtual Framebuffer) to avoid SDL3 display initialization errors.

Required Setup (One-time)

# Install Xvfb
sudo apt-get install xvfb

Running the Game in Headless Mode

Option 1: Using xvfb-run directly (RECOMMENDED)

xvfb-run -a ./projecte_2026

Option 2: Custom display configuration

xvfb-run -a -s "-screen 0 1280x720x24" ./projecte_2026

Why This Is Critical

  • SDL3 requires a display: The game uses SDL3 which requires X11/Wayland display
  • No code changes needed: Xvfb simulates a virtual display without modifying the codebase
  • Full logging: Console output and logs work normally, essential for debugging resource loading
  • Testing resource loading: When modifying asset loading code, running with xvfb-run allows seeing all initialization logs

ALWAYS use xvfb-run when testing on the remote server, especially when:

  • Modifying resource loading code
  • Testing asset initialization
  • Debugging startup issues
  • Verifying configuration changes

Static Analysis Tools (Linters)

This project uses two complementary static analysis tools for code quality:

clang-tidy (Modernization & Best Practices)

Purpose: Detects style issues, modernization opportunities, and potential bugs. Best for refactoring and applying C++20 best practices.

IMPORTANT: Always run on specific files, NOT on the entire project, to avoid long execution times and errors in unrelated files.

# Analyze a specific file (RECOMMENDED)
tools/linter/run_clang-tidy.sh source/game/entities/player.cpp

# Analyze multiple specific files
tools/linter/run_clang-tidy.sh source/game/entities/player.cpp source/game/entities/enemy.cpp

# Apply fixes automatically to a specific file
tools/linter/run_clang-tidy.sh --fix source/game/entities/player.cpp

# Analyze entire project (SLOW, may have errors in defaults.hpp)
tools/linter/run_clang-tidy.sh

Known False Positives:

  • defaults.hpp: May report errors in constant definitions
  • readability-magic-numbers / cppcoreguidelines-avoid-magic-numbers: Acceptable for game constants (block sizes, speeds, etc.)

cppcheck (Bug Detection & Memory Safety)

Purpose: Detects bugs, memory leaks, undefined behavior, and style issues. Complementary to clang-tidy.

# Warning, style, and performance analysis (RECOMMENDED for daily use)
tools/linter/run_cppcheck.sh -w --path source/game/entities/player.cpp

# Exhaustive analysis (slower, more thorough)
tools/linter/run_cppcheck.sh -a --path source/game/entities/

# Detect unused functions (whole project analysis)
tools/linter/run_cppcheck.sh -u

# Analyze entire project with warning level
tools/linter/run_cppcheck.sh -w

Output: Results are saved in tools/linter/cppcheck-result-*.txt

Known False Positives:

  • unusedFunction: May report false positives for callback functions or public API methods
  • passedByValue: Acceptable for small types like SDL_FRect in game code
  • constParameter: Not always applicable for API consistency

When to Use Each Tool

Scenario Tool Reason
Daily refactoring clang-tidy Fast, auto-fixable issues
Before committing Both Comprehensive quality check
After major changes cppcheck -a Deep bug analysis
Hunting memory leaks cppcheck Specialized detection
Code modernization clang-tidy --fix Automatic C++20 upgrades

Integration with Development Workflow

When refactoring code (especially with /refactor-class command):

  1. Make structural changes
  2. Compile to verify syntax
  3. Run clang-tidy (without --fix) to identify issues
  4. Run cppcheck -w to catch bugs
  5. Review and fix legitimate issues
  6. Apply automatic fixes if appropriate
  7. Recompile and test

Note: The /refactor-class command automatically runs both linters after compilation and provides intelligent analysis of results.


Important Code Consistency Rules

  1. Forward Declarations: Always use class for forward declarations of classes defined with class (not struct). The Surface class is defined as class Surface in surface.hpp:57, so all forward declarations must use class Surface;

  2. Singleton Pattern: When creating new singletons, follow the existing pattern:

    • Private static instance pointer
    • Private constructor/destructor
    • Public init(), destroy(), and get() methods
  3. Delta Time: Always use DeltaTimer for frame-rate independent physics calculations

  4. Memory Management: Prefer std::shared_ptr for shared resources (Surfaces, Sprites) and std::unique_ptr for sole ownership

  5. Room file format — single source of truth: Cualquier cambio al formato data/room/*.yaml (añadir/quitar/renombrar campos) se hace exclusivamente en source/game/gameplay/room_format.cpp. Esa clase es la única autoridad: combina parser (loadYAML), serializer (saveYAML, debug-only) y createDefault para rooms nuevas. Cuando añadas un campo nuevo:

    • Añade el field a Room::Data en source/game/gameplay/room.hpp.
    • Actualiza parseRoomConfig/buildContent/createDefault en room_format.cpp (los tres en el mismo módulo).
    • Nunca escribas yaml a pelo con std::ofstream desde otro sitio (especialmente desde MapEditor::createNewRoom, que ya delega en RoomFormat::createDefault + RoomFormat::saveYAML). El editor solo manipula Room::Data; el formato yaml es invisible para él. Saltarse esta regla causa bugs como el del crash de 06.yaml (formato hardcoded en createNewRoom que se desincroniza del parser real).
  6. Nuevas entidades de room — soporte completo en editor y consola: Cuando añadas un tipo nuevo de entidad a las rooms (al estilo de enemies, items, platforms, keys, doors), no basta con el parser/serializer y el manager runtime. Debes implementar también su contrapartida en el editor y en la consola, en paridad con los tipos existentes:

    • Selección visual en MapEditor (click sobre la entidad → selection_ con su tipo y índice).
    • Drag & drop para mover la entidad por el grid (con autosave al soltar).
    • Entry en la statusbar del editor cuando la entidad está seleccionada (mostrar id, animación, etc).
    • Comandos de consola: add <tipo>, delete, set <propiedad> <valor> para esa entidad (ver el bloque setEnemyProperty / setItemProperty / setPlatformProperty en map_editor.cpp y cmdSet en console_commands.cpp).
    • Renderizado de hitbox/boundary en renderEntityBoundaries cuando esté seleccionada o cuando el jugador active el overlay de debug.
    • EntityType enum en map_editor.hpp extendido con el nuevo tipo.

    Pendiente histórico: las llaves (Key) y puertas (Door) se añadieron al sistema de rooms en su día sin esta contrapartida en el editor. Hay que migrarlas siguiendo este patrón. Cualquier entidad nueva debe nacer ya con soporte completo, no diferirlo "para después".


Last Updated: April 2026 Original Author: JailDesigner Repository: Gitea (internal)