227 lines
9.5 KiB
Markdown
227 lines
9.5 KiB
Markdown
# Game States & Substates
|
|
|
|
Documentation technique pour le testing et debugging du flow de jeu.
|
|
|
|
## Vue d'ensemble
|
|
|
|
```
|
|
intro ──► bike ──► pylone ──► ferme ──► outro
|
|
```
|
|
|
|
---
|
|
|
|
## Main States
|
|
|
|
| State | Description |
|
|
| -------- | ------------------------------------------------------------------ |
|
|
| `intro` | Séquence d'introduction (cinématique, naming, premier déplacement) |
|
|
| `bike` | Mission de réparation du vélo |
|
|
| `pylone` | Quête du pylone (alert → searching → helped → manipulation) |
|
|
| `ferme` | Mission de réparation de la ferme |
|
|
| `outro` | Fin du jeu |
|
|
|
|
---
|
|
|
|
## Intro (GameStep)
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ intro.currentStep │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
|
intro ──► sequence_video ──► naming ──► start-move ──► bike
|
|
```
|
|
|
|
### Étapes
|
|
|
|
| Step | Trigger | Action | Passage vers |
|
|
| ---------------- | -------- | ---------------------------------------------- | ------------------------------------------------ |
|
|
| `intro` | Initial | État initial | Auto → `sequence_video` quand `sceneReady: true` |
|
|
| `sequence_video` | GameFlow | Déclenche la cinématique dans `GameCinematics` | Fin cinématique → `naming` |
|
|
| `naming` | IntroUI | Affiche l'input pour le prénom | Submit → `start-move` |
|
|
| `start-move` | GameFlow | Active le mouvement (`canMove: true`) | Via zone "fabrikExit" → `bike` |
|
|
|
|
### Transition vers bike
|
|
|
|
- **Trigger**: Zone `fabrikExit` dans `zones.ts`
|
|
- **Action**: `advanceGameState()` dans `ZoneDetection.tsx`
|
|
- **Résultat**: `mainState: "bike"`, `intro.hasCompleted: true`
|
|
|
|
---
|
|
|
|
## Bike (MissionStep)
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ bike.currentStep (MissionStep) │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
|
locked ──► waiting ──► inspected ──► fragmented ──► scanning ──► repairing ──► reassembling ──► done
|
|
```
|
|
|
|
### Transition vers pylone
|
|
|
|
- **Trigger**: `bike.currentStep: "done"`
|
|
- **Action**: `completeBikeState()` dans useGameStore
|
|
- **Résultat**: `mainState: "pylone"`, `pylone.currentStep: "locked"`
|
|
|
|
---
|
|
|
|
## Pylone (PyloneStep)
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ pylone.currentStep (PyloneStep) │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
|
locked (bypass) ──► alert ──► searching ──► helped ──► manipulation ──► outro
|
|
```
|
|
|
|
### Étapes
|
|
|
|
| Step | Trigger | Action | Passage vers |
|
|
| -------------- | ---------------------------------- | ---------------------------------- | --------------------------------------------------------- |
|
|
| `locked` | Initial (après bike) | État initial | **Bypass automatique** → `alert` via `advanceGameState()` |
|
|
| `alert` | `advanceGameState()` | Affiche l'alerte (à implémenter) | Via `advanceGameState()` |
|
|
| `searching` | `advanceGameState()` | Déclenché par zone "searchingZone" | Via `advanceGameState()` |
|
|
| `helped` | Interaction avec `NPCHelper` | Dialogue avec le villageois | Via interaction 3D |
|
|
| `manipulation` | Interaction avec `PyloneDestroyed` | Interaction avec l'objet central | Via `advanceGameState()` → `outro` |
|
|
|
|
### Bypass automatique
|
|
|
|
```typescript
|
|
// useGameStore.ts - advancePyloneStep()
|
|
if (state.pylone.currentStep === "locked") {
|
|
return { pylone: { ...state.pylone, currentStep: "alert" } };
|
|
}
|
|
```
|
|
|
|
### Transition vers outro
|
|
|
|
- **Trigger**: `pylone.currentStep: "manipulation"` + `advanceGameState()`
|
|
- **Action**: `advancePyloneStep()` détecte fin de la séquence
|
|
- **Résultat**: `mainState: "outro"`
|
|
|
|
---
|
|
|
|
## Ferme (MissionStep)
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ ferme.currentStep (MissionStep) │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
|
locked ──► waiting ──► inspected ──► fragmented ──► scanning ──► repairing ──► reassembling ──► done
|
|
```
|
|
|
|
### Transition vers outro
|
|
|
|
- **Trigger**: `ferme.currentStep: "done"`
|
|
- **Action**: `completeFermeState()` dans useGameStore
|
|
- **Résultat**: `mainState: "outro"`, `ferme.irrigationFixed: true`
|
|
|
|
---
|
|
|
|
## Outro
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ outro.hasStarted │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
|
waiting ──► started
|
|
```
|
|
|
|
---
|
|
|
|
## Debug Panel
|
|
|
|
Le debug panel permet de tester toutes les transitions :
|
|
|
|
### Utilisation
|
|
|
|
1. Ouvrir le jeu en mode debug (`Debug: true` dans `Debug.ts`)
|
|
2. Le panneau "Game State" apparaît en bas à gauche
|
|
3. **Main state**: Sélectionner le state principal
|
|
4. **Sub state**: Sélectionner le sub-state
|
|
5. **Previous/Next step**: Avancer ou reculer d'un step
|
|
6. **Reset**: Remettre à l'état initial
|
|
|
|
### Raccourcis clavier
|
|
|
|
| Action | Clavier |
|
|
| ------- | ------------------ |
|
|
| Avancer | Debug panel button |
|
|
| Reculer | Debug panel button |
|
|
| Reset | Debug panel button |
|
|
|
|
---
|
|
|
|
## Comment tester chaque section
|
|
|
|
### Tester l'intro
|
|
|
|
1. Vérifier que `sceneReady: false` au démarrage
|
|
2. Attendre que le loader termine (`sceneReady: true`)
|
|
3. Vérifier `intro.currentStep: "intro"` → auto vers `sequence_video`
|
|
4. Si cinématique fonctionne : `sequence_video` → `naming`
|
|
5. Entrer un prénom : `naming` → `start-move`
|
|
6. Vérifier `canMove: true` après `start-move`
|
|
7. Entrer dans la zone `fabrikExit` → `mainState: "bike"`
|
|
|
|
### Tester bike
|
|
|
|
1. Via debug panel, avancer jusqu'à `done`
|
|
2. Vérifier `mainState: "pylone"`
|
|
|
|
### Tester pylone
|
|
|
|
1. Via debug panel, avancer (bypass `locked` → `alert`)
|
|
2. Vérifier `pylone.currentStep: "alert"`
|
|
3. Avancer : `alert` → `searching` → `helped` → `manipulation`
|
|
4. Après `manipulation`, vérifier `mainState: "outro"`
|
|
|
|
### Tester ferme
|
|
|
|
1. Via debug panel, avancer dans bike jusqu'à `done`
|
|
2. Vérifier `mainState: "pylone"` → `ferme` (après pylone)
|
|
3. Avancer jusqu'à `done`
|
|
4. Vérifier `mainState: "outro"`
|
|
|
|
---
|
|
|
|
## Fichiers clés
|
|
|
|
| Fichier | Rôle |
|
|
| ------------------------------------------------- | ------------------------------------- |
|
|
| `src/managers/stores/useGameStore.ts` | Store Zustand avec toutes les actions |
|
|
| `src/types/game.ts` | Définition de `GameStep` |
|
|
| `src/types/gameplay/pylone.ts` | Définition de `PyloneStep` |
|
|
| `src/types/gameplay/repairMission.ts` | Définition de `MissionStep` |
|
|
| `src/components/game/GameFlow.tsx` | Logique de transition de l'intro |
|
|
| `src/components/zone/ZoneDetection.tsx` | Déclenchement des zones |
|
|
| `src/components/ui/debug/GameStateDebugPanel.tsx` | Outil de debug |
|
|
|
|
---
|
|
|
|
## État initial
|
|
|
|
```typescript
|
|
{
|
|
mainState: "intro",
|
|
isCinematicPlaying: false,
|
|
sceneReady: false,
|
|
missionFlow: {
|
|
activityCity: true,
|
|
canMove: false,
|
|
dialogMessage: null,
|
|
playerName: "",
|
|
},
|
|
intro: { currentStep: "intro", dialogueAudio: null, hasCompleted: false, isBikeUnlocked: false },
|
|
bike: { currentStep: "locked", dialogueAudio: null, isRepaired: false },
|
|
pylone: { currentStep: "locked", dialogueAudio: null, isPowered: false },
|
|
ferme: { currentStep: "locked", dialogueAudio: null, irrigationFixed: false },
|
|
outro: { dialogueAudio: null, hasStarted: false },
|
|
}
|
|
```
|