feat: leader et suiveurs en exploration (#52) #62

Merged
Reliodas merged 1 commit from feature/52-leader-followers into develop 2026-06-22 06:11:23 +00:00
Owner

Closes #52.

Rend l'exploration jouable avec plusieurs membres présents : un leader contrôlé et au moins un compagnon qui le suit. Quatrième pierre du jalon 0.16.0, à la suite de #49/#50/#51. Les positions individuelles sont désormais distinctes, persistées et prêtes à alimenter le combat (#53). Le suivi repose sur un modèle pur et déterministe, testable sans rendu.

Changements

  • PartyFormation (scripts/party/party_formation.gd, modèle pur) : suivi « en train » déterministe. step_followers() garantit qu'un suiveur n'entre que dans une case qu'un membre vient de libérer (donc jamais un mur ni un coin interdit), que deux membres ne se superposent jamais, et qu'un suiveur bloqué tient sa position en bloquant en cascade ceux derrière lui.
  • Follower (scenes/exploration/follower.gd) : jeton visuel d'un compagnon présent, distinct du jeton Player (leader). Sa case logique est pilotée par World, il ne lit aucune entrée.
  • World : marque le groupe actif présent à l'entrée sur la carte (le groupe voyage ensemble), place un jeton suiveur par compagnon présent (_spawn_followers, position mémorisée ou case libre proche du leader), et fait suivre les compagnons à chaque pas du leader (notify_leader_movedadvance_followers, isolé pour les tests). Player._try_move notifie World à chaque pas réussi.
  • Positions individuelles : GameState.member_pos_by_map (+ set_member_pos / member_start_for / member_positions_for), persistées dans GameSave.member_pos_by_map, restaurées au chargement et alimentant le prochain combat. player_pos_by_map reste la source de la position du leader.
  • Changement de leader : GameState.set_leader() délègue à Party — un id inconnu/non actif est refusé, sans duplication ni perte de membre.

Critères d'acceptation

  • le leader reçoit les entrées d'exploration ;
  • au moins un compagnon suit sans occuper la même case ;
  • aucun suiveur ne traverse les murs ou les coins interdits ;
  • changer de leader ne duplique ni ne perd de membre ;
  • les positions courantes alimentent le prochain combat ;
  • tests couvrent déplacement, obstacle, changement de leader et restauration.

Tests

Suite GUT complète verte : 241 tests / 778 assertions (depuis 230 / 758).

  • tests/unit/test_party_formation.gd : suivi dans la case libérée, file de deux suiveurs sans superposition, blocage en cascade, leader immobile, file vide.
  • tests/unit/test_world_followers.gd : apparition d'un jeton suiveur distinct + présence à l'entrée, suivi de la case libérée (positions mémorisées pour le combat), obstacle (suiveur qui tient sa position), changement de leader sans duplication/perte, persistance des positions individuelles par carte.

Validation manuelle (différée au #58)

Le ressenti temps réel — caméra centrée sur le leader, fluidité des tweens de suivi, entrées clavier — n'est pas vérifiable en GUT headless. Conformément à ta décision, il sera validé manuellement dans Godot au #58 (parcours d'intégration). Le cœur logique (modèle de suivi, positions, présence, changement de leader) est couvert par la suite automatisée.

Closes #52. Rend l'exploration jouable avec plusieurs membres présents : un leader contrôlé et au moins un compagnon qui le suit. Quatrième pierre du jalon 0.16.0, à la suite de #49/#50/#51. Les positions individuelles sont désormais distinctes, persistées et prêtes à alimenter le combat (#53). Le suivi repose sur un modèle pur et déterministe, testable sans rendu. ## Changements - **`PartyFormation`** (`scripts/party/party_formation.gd`, modèle pur) : suivi « en train » déterministe. `step_followers()` garantit qu'un suiveur n'entre que dans une case qu'un membre **vient de libérer** (donc jamais un mur ni un coin interdit), que deux membres ne se superposent jamais, et qu'un suiveur **bloqué tient sa position** en bloquant en cascade ceux derrière lui. - **`Follower`** (`scenes/exploration/follower.gd`) : jeton visuel d'un compagnon présent, distinct du jeton `Player` (leader). Sa case logique est pilotée par `World`, il ne lit aucune entrée. - **`World`** : marque le groupe actif **présent** à l'entrée sur la carte (le groupe voyage ensemble), place un jeton suiveur par compagnon présent (`_spawn_followers`, position mémorisée ou case libre proche du leader), et fait suivre les compagnons à chaque pas du leader (`notify_leader_moved` → `advance_followers`, isolé pour les tests). `Player._try_move` notifie `World` à chaque pas réussi. - **Positions individuelles** : `GameState.member_pos_by_map` (+ `set_member_pos` / `member_start_for` / `member_positions_for`), persistées dans `GameSave.member_pos_by_map`, restaurées au chargement et alimentant le prochain combat. `player_pos_by_map` reste la source de la position du leader. - **Changement de leader** : `GameState.set_leader()` délègue à `Party` — un id inconnu/non actif est refusé, sans duplication ni perte de membre. ## Critères d'acceptation - [x] le leader reçoit les entrées d'exploration ; - [x] au moins un compagnon suit sans occuper la même case ; - [x] aucun suiveur ne traverse les murs ou les coins interdits ; - [x] changer de leader ne duplique ni ne perd de membre ; - [x] les positions courantes alimentent le prochain combat ; - [x] tests couvrent déplacement, obstacle, changement de leader et restauration. ## Tests Suite GUT complète verte : **241 tests / 778 assertions** (depuis 230 / 758). - `tests/unit/test_party_formation.gd` : suivi dans la case libérée, file de deux suiveurs sans superposition, blocage en cascade, leader immobile, file vide. - `tests/unit/test_world_followers.gd` : apparition d'un jeton suiveur distinct + présence à l'entrée, suivi de la case libérée (positions mémorisées pour le combat), obstacle (suiveur qui tient sa position), changement de leader sans duplication/perte, persistance des positions individuelles par carte. ### Validation manuelle (différée au #58) Le ressenti temps réel — caméra centrée sur le leader, fluidité des tweens de suivi, entrées clavier — n'est pas vérifiable en GUT headless. Conformément à ta décision, il sera validé manuellement dans Godot au #58 (parcours d'intégration). Le cœur logique (modèle de suivi, positions, présence, changement de leader) est couvert par la suite automatisée.
feat: leader et suiveurs en exploration (#52)
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
6085743894
Ajoute PartyFormation (scripts/party/), modèle pur de suivi « en train »
déterministe : chaque suiveur n'entre que dans une case qu'un membre vient
de libérer (jamais un mur), deux membres ne se superposent jamais, et un
suiveur bloqué tient sa position en cascade.

World place un jeton Follower distinct par compagnon présent, marque le
groupe actif présent à l'entrée sur la carte, et fait suivre les
compagnons à chaque pas du leader (notify_leader_moved / advance_followers,
appelés par Player). Les positions individuelles sont mémorisées par carte
(GameState.member_pos_by_map + set_member_pos/member_start_for), persistées
(GameSave.member_pos_by_map) et alimentent le prochain combat.
GameState.set_leader change de leader sans dupliquer ni perdre de membre.

Tests : test_party_formation.gd (suivi, file, blocage, leader immobile) ;
test_world_followers.gd (apparition, suivi de la case libérée, obstacle,
changement de leader, persistance des positions). Suite 241 tests.

Note : le ressenti temps réel (caméra/suiveurs) sera validé manuellement au #58.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reliodas merged commit 31fa2a7e86 into develop 2026-06-22 06:11:23 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: jeux/beaulieu-sur-brume#62
No description provided.