# BUGS DETECTADOS - Reescritura Player

**Fecha:** 2025-10-30
**Commit funcional de referencia:** `7cd596a0b9876c75ff75efc13708a2ca00c8cfcd`
**Estado:** La reescritura según PLAYER_MECHANICS.md ha introducido múltiples regresiones

---

## 🐛 BUGS CRÍTICOS DETECTADOS

### 2. **Salto recto en rampa: atraviesa la rampa al caer**
- **Descripción:** Si el jugador salta verticalmente (sin movimiento horizontal) estando en una rampa, al caer atraviesa la rampa
- **Estado esperado:** Salto recto (vx_ == 0) debería pegarse a la rampa al descender
- **Regla violada:** PLAYER_MECHANICS.md líneas 386-391 - "JUMPING con vx_ == 0 se PEGA a la rampa"
- **Posible causa:** Lógica en `moveVerticalDown()` no detecta correctamente el caso vx_ == 0

---

### 4. **No suena al saltar**
- **Descripción:** Los sonidos de salto no se reproducen
- **Estado esperado:** Sonidos progresivos basados en distancia vertical
- **Posible causa:**
  - `y_prev_` no se inicializa correctamente
  - Sistema de detección de cambio de índice no funciona
  - `last_grounded_position_` no se actualiza en el momento correcto

---

### 5. **No suena al caer**
- **Descripción:** Los sonidos de caída no se reproducen
- **Estado esperado:** Sonidos progresivos basados en distancia vertical caída
- **Posible causa:** Similar al bug #4, sistema distance-based no detecta cambios

---

### 6. **Caer desde precipicio con inercia sobre rampa: resbala en estado FALLING**
- **Descripción:** Al caer con inercia horizontal sobre una rampa, el jugador resbala en lugar de pegarse
- **Estado esperado:** FALLING siempre debe tener `vx_ = 0` y pegarse a rampas
- **Regla violada:** PLAYER_MECHANICS.md línea 147 - "FALLING se PEGA a TODAS las rampas"
- **Posible causa:** `vx_` no se establece a 0 correctamente en transición a FALLING, o se ejecuta después del movimiento horizontal

---

### 7. **No muere al caer desde gran altura**
- **Descripción:** El jugador puede caer desde cualquier altura sin morir
- **Estado esperado:** Caída > 32 píxeles (4 tiles) debería matar al jugador
- **Regla violada:** PLAYER_MECHANICS.md líneas 158-178
- **Posible causa:**
  - La verificación de muerte en `moveVerticalDown()` no se ejecuta
  - `previous_state_` no es FALLING cuando debería
  - Cálculo de `FALL_DISTANCE` es incorrecto

---

### 8. **No muere al caer sobre conveyor belt desde altura**
- **Descripción:** El jugador puede caer sobre una conveyor belt desde cualquier altura sin morir
- **Estado esperado:** Caída > 32 píxeles sobre conveyor belt también debería matar
- **Regla violada:** PLAYER_MECHANICS.md líneas 158-178
- **Posible causa:**
  - La verificación de muerte solo está en la rama de suelo normal (`checkTopSurfaces`)
  - Posiblemente necesita estar también cuando aterriza en `checkAutoSurfaces`
  - Podría ser un subcaso del bug #7

---

## 🔍 ANÁLISIS PRELIMINAR

### Problema raíz principal: **Orden de ejecución**

El orden actual es:
```cpp
move() {
    y_prev_ = y_;
    applyGravity();
    updateStateAndVelocity();  // ← Cambia estado y DEBERÍA cambiar vx_
    moveHorizontal();           // ← Aplica vx_ (que puede ser incorrecto)
    moveVertical();
    updateColliderGeometry();
}
```

**Problema:** `updateStateAndVelocity()` puede cambiar el estado a FALLING y establecer `vx_ = 0`, pero esto ocurre DENTRO del switch que solo se ejecuta DESPUÉS de que `previous_state_` ya esté establecido. En el código actual, cuando se hace la transición STANDING → FALLING, `setState()` NO establece `vx_ = 0` (se supone que lo hace `updateStateAndVelocity()`), pero esto puede no ejecutarse hasta el siguiente frame.

### Problema raíz secundario: **setState() incompleto**

En el commit funcional (`7cd596a0b9876c75ff75efc13708a2ca00c8cfcd`), `setState()` probablemente establecía TODAS las variables necesarias inmediatamente. En la reescritura actual, se delegó parte de esta responsabilidad a `updateStateAndVelocity()`, creando una desincronización.

---

## 📋 PLAN DE SOLUCIÓN

### Opción A: Volver al commit funcional y refactorizar con cuidado
1. Hacer `git diff` entre commit funcional y actual
2. Identificar QUÉ funcionaba en el original
3. Aplicar solo los cambios necesarios (eliminar `jumping_time_`, unificar variables)
4. Mantener la lógica de setState() completa

### Opción B: Corregir bugs uno por uno en código actual
1. Arreglar `setState()` para que establezca TODAS las variables inmediatamente
2. Revisar orden de ejecución en `move()`
3. Depurar sistema de sonidos
4. Probar cada bug individualmente

### Opción C: Híbrido
1. Extraer lógica funcional del commit 7cd596a
2. Aplicar solo las correcciones de PLAYER_MECHANICS.md que no rompen funcionalidad:
   - Cambiar `jump_init_pos_` → `last_grounded_position_` (con cuidado)
   - Eliminar `jumping_time_` (secundario, no crítico)
   - Implementar sistema de sonidos distance-based (después de que todo funcione)

---

## 🎯 RECOMENDACIÓN

**Opción C (Híbrido)** parece la más sensata:

1. Revertir a un punto funcional
2. Aplicar cambios incrementales uno por uno
3. Testear después de cada cambio
4. No hacer cambios arquitecturales grandes (mantener `updateState()` y `updateVelocity()` separados si funcionaba así)

---

## 📝 NOTAS ADICIONALES

- El commit `7cd596a` funciona perfecto según el usuario, aunque el código sea "caótico"
- **Lección aprendida:** Refactorizar código funcional sin tests automáticos es peligroso
- La sincronización estado-velocidad es más sutil de lo que parecía
- PLAYER_MECHANICS.md puede tener asunciones incorrectas sobre el orden de ejecución óptimo

---

## ✅ PRÓXIMOS PASOS

1. Comparar código actual vs commit 7cd596a
2. Identificar diferencias críticas en:
   - `setState()`
   - `move()`
   - `updateState()`/`updateVelocity()`
   - Transiciones de estado
3. Decidir estrategia: revertir completo, revertir parcial, o corregir in-place
