14 KiB
status, source, date, verified-by
| status | source | date | verified-by |
|---|---|---|---|
| reverse-documented | Assets/Game/Scripts/ | 2026-08-16 | Usuario |
Arquitectura — Ajedrez Purgatorio
Nota: Este documento fue generado mediante
/reverse-documenta partir de la implementación existente. Captura el comportamiento actual del código y la intención de diseño aclarada con el usuario. Las secciones marcadas como INCOMPLETAS corresponden a partes cuya integración aún no está terminada.
1. Resumen Ejecutivo
Ajedrez Purgatorio es un juego de ajedrez clásico con campaña narrativa de 3 capítulos, piezas con identidad, sistema de Purgatorio (dados contra la Muerte) y sistemas meta (Dead Kings y guardado). Desarrollado en Unity 6 (6000.3.13f1) con URP 17.3.0.
Estado actual:
- Código: 100% implementado en 5 sprints (Foundation, Chess+AI, Purgatorio, Narrative, Meta+Polish).
- Escenas:
MainMenu.unityyChapter1.unityensambladas en el editor (trabajo sin commitear). - Pendiente: Chapter2/3, cableado de GameStateManager/IA/Dead Kings UI, audio, tests.
2. Stack Tecnológico
| Capa | Tecnología |
|---|---|
| Engine | Unity 6.3 (6000.3.13f1) |
| Render | URP 17.3.0 (2D) |
| Lenguaje | C# (.NET Standard 2.1) |
| Persistencia | JSON (JsonUtility) en Application.persistentDataPath |
| Datos | ScriptableObjects + JSON en Resources/ y Data/ |
| Tests | Unity Test Framework (Tests/) |
3. Vista de Capas
La estructura se formaliza aquí como orgánica: creció a lo largo de los sprints y no fue una decisión deliberada de arquitectura. Sin embargo, el resultado es funcional y respeta razonablemente la separación presentación/lógica/datos.
Assets/Game/Scripts/
├── Mono/ # Presentation + Logic (MonoBehaviours)
│ ├── Core/ # Orquestadores y estado global
│ │ ├── GameManager.cs # Motor de partida (reglas, turnos, eventos)
│ │ ├── BoardManager.cs # Tablero runtime + SetupBoard(CampaignState)
│ │ ├── CampaignManager.cs # Campaña (singleton DontDestroyOnLoad)
│ │ ├── DialogueSystem.cs # Motor de diálogos (branching, JSON)
│ │ ├── GameStateManager.cs # Máquina de estados global ⚠️ SIN CABLEAR
│ │ ├── PieceIdentityManager.cs # Asigna identidades a piezas
│ │ ├── SceneTransitionManager.cs# Fades de transición
│ │ └── Services/ # Lógica POCO testable
│ │ ├── CheckDetector.cs # Jaque / jaque mate
│ │ ├── DrawDetector.cs # Tablas (50 movs, triple repetición, ahogado)
│ │ └── MoveValidator.cs # Legalidad de movimientos
│ ├── Gameplay/ # Feedback visual (PieceSelectionFeedback)
│ ├── Pieces/ # Piece + 6 tipos (King, Queen, Rook, Bishop, Knight, Pawn)
│ ├── AI/ # AIController + IAIStrategy + Easy/Medium/Hard
│ ├── Purgatory/ # DiceSystem, PurgatoryManager + 3 UIs
│ ├── UI/ # MainMenuController, GameHUD, PauseMenu, DialogueUI,
│ │ # PromotionUI, PieceTooltip, DeadKingInput/Reveal
│ ├── Meta/ # DeadKingPool, SaveSystem
│ ├── Audio/ # AudioManager (SFX + música)
│ └── Data/ # CampaignConfig, ChapterData, DialogueData
├── Data/ # Modelos serializables (CampaignState, CampaignStats,
│ # DeadKingData, SpeakerDatabase, BalanceConfig)
├── ScriptableObjects/ # PieceIdentity, AIPositionTables
└── Editor/ # Herramientas de setup/reparación
Editor tools (Assets/Editor/ + Assets/Game/Scripts/Editor/):
ProjectSetup.cs— automatiza ensamblado ⚠️ referenciaCameraFollowinexistente (no compila)VerifySetup.cs— valida el cableado de escenasFixErrors.cs— repara referencias rotas (p. ej. fade de transición)FixDialogueLayout.cs— corrige layout de diálogosPurgatorySetupValidator.cs— ventana Tools/Ajedrez Purgatorio
4. Patrones Dominantes
Cada patrón se documenta como mini-ADR con contexto, decisión y consecuencias.
4.1 Service Layer POCO — ADR-001
Contexto: GameManager concentraba 8 responsabilidades (~475 líneas) y era imposible
de testear sin instanciar una escena Unity completa.
Decisión: Extraer la lógica a POCOs (CheckDetector, DrawDetector, MoveValidator)
sin dependencia de MonoBehaviour, inyectados en GameManager.Awake(). MoveValidator
depende de CheckDetector (dependency injection con validación null).
Razón confirmada: testabilidad — los servicios son 100% testeables sin Unity.
Consecuencias: GameManager redujo a 3 responsabilidades; la lógica es reutilizable por IA y futuros sistemas (hints, variantes de reglas).
Código: Assets/Game/Scripts/Mono/Core/Services/*.cs, GameManager.cs
4.2 Strategy Pattern — IA — ADR-002
Contexto: 3 dificultades de IA que deben poder escalarse por capítulo.
Decisión: Interfaz IAIStrategy con AIStrategyEasy (random con prioridad a capturas),
AIStrategyMedium (1-ply evaluation) y AIStrategyHard (minimax alpha-beta depth 2, timeout
5s). AIController selecciona la estrategia.
Consecuencias: Extensible a nuevas dificultades sin tocar el controlador. ⚠️ INCOMPLETO:
la selección de dificultad por capítulo desde CampaignManager está como TODO (S4-005) y
AIController no está instanciado en ninguna escena.
4.3 Event-Driven — ADR-003
Contexto: UI y sistemas (Purgatorio, HUD) necesitan reaccionar a eventos del juego sin acoplamiento directo.
Decisión: Eventos Action<T> en GameManager (OnCheckmate, OnDraw, OnPieceMoved,
OnTurnChanged, OnCheck). PurgatoryManager se suscribe a capturas; la UI escucha eventos.
Consecuencias: Desacople UI ↔ lógica. ⚠️ Faltan OnPieceCaptured y OnCheckResolved
que GameHUD espera (suscripciones comentadas como TODO).
4.4 Singleton dual — ADR-004
Contexto: Managers globales accesibles desde cualquier script.
Decisión: Dos variantes:
MonoBehaviourconDontDestroyOnLoad—CampaignManager,SaveSystem,AudioManagerScriptableObjectsingleton —DeadKingPool(persistencia + configuración en un asset)
Consecuencias: Acceso global simple. El patrón singleton añade acoplamiento implícito, aceptado para el alcance del proyecto.
4.5 ScriptableObject como data container — ADR-005
Contexto: Datos de diseño (identidades de 16-20 piezas, tablas de posición IA, balance) que deben editarse sin recompilar.
Decisión: PieceIdentity, AIPositionTables, BalanceConfig, CampaignConfig como
ScriptableObjects; CampaignState y DeadKingPool cargados desde Resources/.
Consecuencias: Data-driven y editable en editor. La serialización de CampaignState
requiere capa JSON propia para Save/Load (limitación de JsonUtility con objetos anidados).
4.6 Overlay UI en lugar de escenas separadas — ADR-006
Contexto: El Purgatorio debe interrumpir la partida sin perder el contexto del tablero.
Decisión: El flujo del Purgatorio (oferta → dados → resultado) son Canvas overlay sobre la escena de juego, no escenas separadas.
Consecuencias: Mejor UX y menor overhead de carga. Requiere pausar/resumir gameplay.
4.7 Time.timeScale para pausas — ADR-007
Contexto: Promoción y Purgatorio necesitan pausar el juego.
Decisión: Time.timeScale = 0 con coroutines que usan WaitForSecondsRealtime.
Consecuencias: Simple y sin estado global adicional. Riesgo: cualquier coroutine con
WaitForSeconds normal se congela.
4.8 Position hashing FEN-like — ADR-008
Contexto: Detección de repetición triple.
Decisión: Hash de posición tipo FEN-string en lugar de Zobrist hashing.
Consecuencias: Suficiente para el volumen de partidas del juego; no óptimo para
rendimiento extremo (irrelevante aquí). La repetición se rastrea en DrawDetector.
5. Flujos Principales
5.1 Partida (ajedrez)
GameManager ──▶ BoardManager (tablero runtime)
│ └── SquareClick (por casilla)
├──▶ MoveValidator (legalidad) → CheckDetector (jaque/mate) → DrawDetector (tablas)
├──▶ Turnos (OnTurnChanged) → GameHUD
└──▶ IA: AIController → IAIStrategy (Easy/Medium/Hard)
5.2 Campaña
MainMenuController (Nueva Campaña / Continuar)
→ CampaignManager.LoadChapter(index)
→ BoardManager.SetupBoard(CampaignState) // piezas vivas
→ DialogueSystem (intro de capítulo)
→ Spawn de Dead King (ShouldSpawnDeadKing + GetRandomDeadKing)
→ Victoria: OnChapterVictory → autosave (SaveSystem)
→ Derrota: DeadKingInputUI (inscribir Rey Muerto) → pool → menú
5.3 Purgatorio
Captura de pieza blanca (GameManager)
→ PurgatoryManager.OnPieceCaptured
→ PurgatoryOfferUI ("¿Desafiar a la Muerte?")
→ DiceRollUI (2d6 + modificadores) → DiceResultUI
→ Muerte gana = pieza se pierde; jugador gana = se salva
→ Límite: 3 visitas por tablero
5.4 Meta
Derrota → DeadKingInputUI → DeadKingPool.AddDeadKing (JSON, filtro profanity, FIFO 100)
Victoria → SaveSystem.SaveGame (3 slots, autosave)
Nueva partida → DeadKingPool.ShouldSpawnDeadKing(chapter) → Rey enemigo como Dead King
6. Escenas y Cableado Actual
Estado verificado contra el working tree (NO commiteado).
Assets/Scenes/.
MainMenu.unity (en Build Settings)
| GameObject | Componentes | Estado |
|---|---|---|
| GameController | MainMenuController (_firstChapterSceneName: Chapter1) |
✅ cableado |
| CampaignManager | CampaignConfig + CampaignState | ✅ cableado |
| SaveSystem | 3 slots | ✅ |
| AudioManager | SFX/música clips | ⚠️ todos null |
| SceneTransitionManager (Core) | FadeCanvas + FadeImage | ✅ cableado |
Chapter1.unity (en Build Settings)
| Sistema | Estado |
|---|---|
| BoardManager | ✅ todos los prefabs asignados (12 piezas, casillas, MoveIndicator) |
| GameManager | ✅ _pieceTooltip, _promotionUI asignados |
| PurgatoryManager + DiceSystem | ✅ _diceSystem, _campaignState, 3 UIs asignados |
| DialogueSystem | ✅ _campaignState + 6 TextAssets |
| PieceIdentityManager | ✅ _campaignState |
| CampaignManager | ✅ |
| SceneTransitionManager (UI) | ⚠️ sin referencias de fade (versión duplicada) |
| GameHUD | ⚠️ _pauseButton, _capturedPieceIconPrefab null |
| DialogueUI | ⚠️ _speakerPortrait, _speakerDatabase, _advanceDialogueAction null |
| PauseMenuController | ⚠️ _canvasGroup null |
Ausentes de escena (scripts existen)
- ❌
GameStateManager— previsto, pendiente de cablear - ❌
AIController— IA no juega hasta instanciarlo - ❌
DeadKingInputUI/DeadKingRevealUI - ❌ Chapter2/3 scenes (no existen)
Build Settings
MainMenu + Chapter1 habilitadas. SampleScene.unity huérfana (no referenciada).
7. Problemas Conocidos
- SceneTransitionManager duplicado —
Core/SceneTransitionManager.cs(usado en MainMenu) yUI/SceneTransitionManager.cs(usado en Chapter1, sin fade). Decisión: consolidar en una sola clase;FixErrors.csasume campos que solo existen en la versión Core. ProjectSetup.csno compila — referenciaCameraFollow, clase inexistente en el repo.- Objetos basura en Chapter1 — GameObject suelto con SquareClick fuera del tablero (-43.98, -0.72); GameManager/board en posiciones extrañas (34, 30); BoardParent vacío.
- Audio mudo — AudioManager sin clips en ambas escenas.
- GameHUD incompleto — sin botón de pausa conectado ni iconos de capturadas.
- SaveSystem restore parcial —
TotalPiecesLost/LastChapterWasVictoryno se restauran (props read-only en CampaignState).
8. Integraciones Pendientes
- Cablear
GameStateManageren escenas (transiciones de estado protegidas con null-check hoy) - Instanciar
AIControllery aplicar dificultad por capítulo (TODO S4-005) - Conectar
DeadKingRevealUI/DeadKingInputUIal flujo de campaña (TODO en CampaignManager) - Añadir eventos
OnPieceCaptured/OnCheckResolveda GameManager y suscribir GameHUD - Completar stats en
DeadKingInputUI.GatherCampaignStats() - Restore completo de SaveSystem
BalanceConfig.LoadFromJSON()real (hoy placeholder con valores default)- Asignar AudioClips y referencias de UI faltantes (GameHUD, DialogueUI, PauseMenu)
- Crear Chapter2/3 scenes y agregarlas a Build Settings
9. Estado de Testing
- ✅
Tests/Unit/Campaign/CampaignStateTests.cs(18 tests) - ✅
Tests/Unit/Dialogue/DialogueSystemBranchingTests.cs(17 tests) - ✅
Tests/Unit/Meta/DeadKingPoolTests.cs(17 tests) - ❌ Pendientes: SaveSystem, servicios POCO (CheckDetector/DrawDetector/MoveValidator), integración
- ❌ Sin test plan de Sprint 5 ni playtest documentado
10. Follow-Up Work
Inmediato:
- Consolidar SceneTransitionManager (eliminar duplicado UI/)
- Reparar
ProjectSetup.cs(CameraFollow inexistente) - Commit del trabajo sin commitear (escenas, prefabs, editor tools, assets movidos)
- Actualizar
PROJECT_STATUS.md/roadmap.md(estado real: escenas ya existen)
Corto plazo:
- Cablear GameStateManager + AIController en escenas
- Escribir tests de SaveSystem y servicios POCO
- Crear Chapter2/3 y playtest completo documentado
Largo plazo:
- Generar ADRs formales (ADR-001..008 aquí son el borrador base)
- Llenar
docs/architecture/tr-registry.yamlcon TR-IDs por sistema - Control Manifest a partir de ADRs aceptados
Referencias
Código principal: Assets/Game/Scripts/Mono/ (GameManager, CampaignManager, BoardManager),
Assets/Game/Scripts/Mono/Core/Services/, Assets/Game/Scripts/Mono/Purgatory/, Meta/.
Documentos de diseño: design/gdd/ (game-concept, systems-index, dice-system, ai-system,
dialogue-system, dead-kings, piece-identity, campaign-system), design/ux/.
GDDs y registro: design/registry/entities.yaml, docs/registry/architecture.yaml.