Files
projecte_2026/CLAUDE.md

231 lines
11 KiB
Markdown

# 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**~~**HECHO**`TileCollider` 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 Dilemma``Projecte 2026` y `jaildoctors_dilemma``projecte_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
```bash
# From project root
mkdir -p build
cd build
cmake ..
cmake --build .
```
### Rebuild After Changes
```bash
# From build directory
cmake --build .
# Or from project root
cmake --build build
```
### Clean Build
```bash
# From build directory
cmake --build . --clean-first
# Or from project root
cmake --build build --clean-first
```
### Run the Game
```bash
# 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)
```bash
# Install Xvfb
sudo apt-get install xvfb
```
#### Running the Game in Headless Mode
**Option 1: Using xvfb-run directly (RECOMMENDED)**
```bash
xvfb-run -a ./projecte_2026
```
**Option 2: Custom display configuration**
```bash
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.
```bash
# 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.
```bash
# 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)