# 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

---

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