- Fix: UIScene n'était jamais lancée (active: false, jamais scene.launch)
donc l'event 'game-over' du serveur n'était jamais affiché — la partie
semblait ne pas avoir de fin. Remplacé par un panneau Vue dans GameView
(vainqueur, classement trié, bouton Quitter via vue-router). UIScene.js
supprimée (code mort).
- Extraction de client/src/utils/hudUtils.js (constantes ATTRS/couleurs et
gaugePercent) depuis GameView.vue pour les rendre testables isolément.
- Tests unitaires client (Vitest) : store Pinia (game.js) et hudUtils
(24 tests, client/test/unit/).
- Tests d'intégration E2E (Playwright, e2e/) avec de vrais clients
Socket.io et rendu Phaser réel dans Chromium :
* game-flow.spec.js : lobby → démarrage → main de 4 cartes → résolution
* item-shop.spec.js : boutique, bouton désactivé si jauge insuffisante,
achat retire l'objet pour tous + effet appliqué + affiché sur la table
* game-over.spec.js : partie complète (12 tours) → panneau de fin
webServer démarre automatiquement client+serveur ; ajout d'une route
GET /health côté Express pour permettre à Playwright de détecter un
serveur déjà démarré.
- README : documentation des 3 niveaux de tests (unitaires serveur,
unitaires client, intégration E2E) et de la nouvelle arborescence.
136 lines
5.0 KiB
Markdown
136 lines
5.0 KiB
Markdown
# Regnum
|
|
|
|
Jeu de cartes en ligne multijoueur (2-4 joueurs). Collecte des points en jouant des cartes de royaume simultanément pendant X tours.
|
|
|
|
## Stack
|
|
|
|
- **Frontend** : Vue 3 + Phaser 3 + Pinia
|
|
- **Backend** : Node.js + Express + Socket.io
|
|
- **Temps réel** : WebSockets
|
|
|
|
## Structure
|
|
|
|
```
|
|
regnum/
|
|
├── client/ # Vue 3 + Phaser 3
|
|
│ ├── src/
|
|
│ │ ├── views/ # HomeView, LobbyView, GameView
|
|
│ │ ├── game/ # Scènes Phaser (Boot, Game) + objets + items
|
|
│ │ ├── stores/ # Pinia store
|
|
│ │ ├── services/# Socket.io client
|
|
│ │ └── utils/ # Fonctions pures partagées (HUD, etc.)
|
|
│ └── test/unit/ # Tests unitaires Vitest (store, utils)
|
|
├── server/ # Node.js
|
|
│ ├── src/
|
|
│ │ ├── game/ # Room, RoomManager, cards, items
|
|
│ │ └── index.js # Serveur Express + Socket.io
|
|
│ └── test/game/ # Tests unitaires node:test (moteur de jeu)
|
|
└── e2e/ # Tests d'intégration Playwright (client+serveur réels)
|
|
└── tests/
|
|
```
|
|
|
|
## Lancement
|
|
|
|
### Serveur
|
|
```bash
|
|
cd server
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
### Client
|
|
```bash
|
|
cd client
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
Ouvrir `http://localhost:5173`
|
|
|
|
## Tests
|
|
|
|
Le projet a 3 niveaux de tests, à exécuter indépendamment :
|
|
|
|
### 1. Tests unitaires — serveur (moteur de jeu)
|
|
|
|
Logique pure de `Room.js` / `cards.js` / `items.js` (règles, gains, achats, effets permanents), avec le test runner natif de Node.js :
|
|
|
|
```bash
|
|
cd server
|
|
npm test # exécution unique
|
|
npm run test:watch # mode watch
|
|
```
|
|
|
|
### 2. Tests unitaires — client (store, utilitaires)
|
|
|
|
Store Pinia et fonctions pures du HUD (`hudUtils.js`), avec Vitest :
|
|
|
|
```bash
|
|
cd client
|
|
npm run test:unit # exécution unique
|
|
npm run test:unit:watch # mode watch
|
|
```
|
|
|
|
### 3. Tests d'intégration E2E (client + serveur réels)
|
|
|
|
Parcours complets (créer/rejoindre une salle, jouer des tours, acheter un objet, fin de partie) pilotés dans un vrai navigateur Chromium via Playwright, avec de vrais clients Socket.io. `webServer` dans `e2e/playwright.config.js` démarre automatiquement le serveur et le client si besoin.
|
|
|
|
```bash
|
|
cd e2e
|
|
npm install # première fois seulement
|
|
npx playwright install chromium # première fois seulement, si besoin
|
|
npm test # exécution unique
|
|
npm run test:ui # mode interactif (debug)
|
|
```
|
|
|
|
## Règles
|
|
|
|
### Principe général
|
|
|
|
- 2 à 4 joueurs par partie, chacun avec son propre deck des mêmes 12 personnages (seule la couleur d'équipe change).
|
|
- Chaque joueur commence avec une main de 4 cartes ; le reste du deck (8 cartes) est pioché une carte par tour.
|
|
- La partie dure **12 tours**. Elle se termine avant si tous les joueurs n'ont plus ni carte en main ni carte à piocher.
|
|
- Chaque tour, tous les joueurs choisissent **simultanément** une carte (cachée), puis les cartes sont révélées et résolues en même temps.
|
|
|
|
### Les 4 jauges
|
|
|
|
Chaque personnage possède 4 attributs (valeurs de 1 à 6), qui correspondent à 4 jauges cumulées par le joueur pendant toute la partie :
|
|
|
|
| Jauge | Icône |
|
|
|---|---|
|
|
| Nourriture | 🟡 |
|
|
| Guerre | 🔴 |
|
|
| Santé | 🟢 |
|
|
| Diplomatie | 🔵 |
|
|
|
|
### Résolution d'un tour
|
|
|
|
Pour chaque attribut, un joueur compare la valeur de sa carte jouée à celle de son **voisin de gauche** (ordre des joueurs dans la partie, en boucle) :
|
|
|
|
```
|
|
gain = max(0, ma_valeur - valeur_du_voisin_de_gauche)
|
|
```
|
|
|
|
Le gain (jamais négatif) est ajouté à la jauge correspondante du joueur. Le score total d'un joueur est la somme de ses 4 jauges.
|
|
|
|
### Les 12 personnages
|
|
|
|
Reine, Prince, Boucher, Médecin, Apothicaire, Fou du Roi, Assassin, Paysan, Bourreau, Chevalier, Marchand, Évêque — chacun avec un profil d'attributs différent (ex : le Paysan est fort en Nourriture mais faible en Diplomatie, l'Assassin est très fort en Guerre mais faible partout ailleurs).
|
|
|
|
### Objets achetables
|
|
|
|
Pendant la phase de sélection, un joueur peut dépenser des points d'une jauge pour acheter un objet, qui procure un **effet permanent** pour le reste de la partie tant qu'il le possède. Chaque objet coûte 3 points et n'existe qu'en **un seul exemplaire** pour toute la partie (premier arrivé, premier servi) :
|
|
|
|
| Objet | Jauge liée | Effet |
|
|
|---|---|---|
|
|
| Trébuchet | 🔴 Guerre | Double le gain de Guerre à chaque tour |
|
|
| Charrue | 🟡 Nourriture | Double le gain de Nourriture à chaque tour |
|
|
| Trousse du Médecin | 🟢 Santé | Garantit +2 en Santé à chaque tour, quel que soit le résultat |
|
|
| Sceau Royal | 🔵 Diplomatie | Copie le meilleur gain de Diplomatie parmi tous les autres joueurs |
|
|
|
|
En cas de conflit (plusieurs joueurs achètent le même objet le même tour), c'est le joueur le plus proche du **"premier joueur"** du tour (rôle qui tourne entre les joueurs à chaque tour) qui l'obtient ; les autres conservent leurs points.
|
|
|
|
### Fin de partie
|
|
|
|
Le joueur avec le score total (somme des 4 jauges) le plus élevé après 12 tours remporte la partie.
|