Files
jaildoctors_dilemma/docs/BUGS_PLAYER_REWRITE.md
2025-10-31 22:58:37 +01:00

142 lines
5.8 KiB
Markdown

# 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