Files
TetaRdPG/SPRINT2.md
Tetardtek 6d1230d16a feat: Sprint 2 — moteur de combat PvE TetaRdPG
Moteur combat stateless (POST /api/combat/start résout le combat complet).
Formules GDD : Mêlée/Distance/Magie × 1.5, critique (5% + Chance×0.2%), esquive (5% + Chance×0.1%).
5 monstres seedés (Têtard Vase → Golem de Boue, level 1–9).
Level up : XP → seuil atteint → level++, +5 statPoints.
Persiste combat_logs (jsonb rounds). Validé : victoire, défaite, 401, 400, 404.
2026-03-15 06:10:06 +01:00

127 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TetaRdPG — Brief Sprint 2
> Statut : 🔄 En cours
> Objectif : Moteur de combat PvE + retours textuels (logs)
> Stack : NestJS · PostgreSQL · TypeORM (synchronize dev)
> Prérequis : Sprint 1 livré ✅
---
## Scope Sprint 2
### ✅ In scope
- Entité `monsters` (5 monstres seedés, level 18)
- Moteur de combat PvE — résolution stateless côté serveur (un POST = combat complet)
- Formules GDD : Mêlée/Distance/Magie × 1.5 | Critique | Esquive
- Fin de combat : Victoire (XP + Or + +10% PV) / Défaite (20% PV + 50 endurance + perte or)
- Persistance des combats (`combat_logs`)
- Mise à jour character post-combat : hpCurrent, endurance, xp, gold, level, statPoints
- Level up basique : XP → seuil atteint → level++, +5 statPoints
- API : `GET /api/monsters`, `POST /api/combat/start`, `GET /api/combat/history`
### ❌ Out of scope
- Interactivité tour par tour (choix action par round) — Sprint 3
- Équipement / armure / arme → défense joueur = 0 Sprint 2
- Forge, artisanat, boutique
- Twitch, PvP
- Frontend React
---
## Décisions de design (game-designer)
| Décision | Valeur Sprint 2 | Justification |
|----------|----------------|---------------|
| Dégâts joueur | `Math.floor(stat × 1.5)` | Arme = 0 (pas d'équipement) |
| Défense joueur | 0 | Pas d'armure Sprint 2 |
| Crit | `5% + Chance × 0.2%` → dégâts ×1.5 | GDD |
| Esquive | `5% + Chance × 0.1%` → annule dégâts | GDD |
| Crit/Esquive monstres | Non (Sprint 2) | Simplification, fairness joueur |
| Défaite HP | 20% hpMax (retour auberge) | GDD "retour auberge" |
| Coût combat défaite | 10 (start) + 50 (peine) = 60 | GDD |
| Level up | `XP requise = round(100 × level^1.5)` | Formule GDD |
| Stat points / level | +5 par level franchi | GDD |
---
## Monstres seedés
| Nom | Level min | Level max | HP | Attaque | Défense | Type | XP | Or (min-max) |
|-----|-----------|-----------|-----|---------|---------|------|----|-------------|
| Têtard Vase | 1 | 2 | 40 | 5 | 0 | melee | 25 | 38 |
| Grenouille Boueuse | 2 | 4 | 65 | 8 | 1 | melee | 45 | 615 |
| Serpent des Marais | 3 | 6 | 90 | 11 | 2 | ranged | 70 | 1025 |
| Champi Vénéneux | 2 | 5 | 75 | 9 | 3 | magic | 60 | 820 |
| Golem de Boue | 6 | 9 | 150 | 16 | 5 | melee | 130 | 2560 |
---
## API Sprint 2
```
GET /api/monsters → liste tous les monstres
POST /api/combat/start → { monsterId, attackType: 'melee'|'ranged'|'magic' }
GET /api/combat/history → combats du personnage connecté
```
### Format réponse POST /api/combat/start
```json
{
"winner": "player",
"rounds": [
{
"round": 1,
"playerDamage": 6, "playerCrit": true, "monsterDodged": false,
"monsterDamage": 5, "playerDodged": false,
"playerHp": 95, "monsterHp": 34,
"log": ["Tetard frappe le Têtard Vase pour 6 dégâts (CRITIQUE) !", "Le Têtard Vase frappe Tetard pour 5 dégâts."]
}
],
"summary": "Victoire en 7 tours ! +25 XP, +5 Or.",
"rewards": { "xp": 25, "gold": 5, "levelUp": false },
"character": { "level": 1, "xp": 25, "gold": 5, "hpCurrent": 75, "enduranceCurrent": 90 }
}
```
---
## Architecture modules
```
src/
├── monster/
│ ├── monster.entity.ts
│ ├── monster.module.ts
│ ├── monster.service.ts
│ └── monster.controller.ts
├── combat/
│ ├── combat.engine.ts → fonctions pures (pas de dépendances NestJS)
│ ├── combat-log.entity.ts
│ ├── combat.service.ts
│ ├── combat.controller.ts
│ ├── combat.module.ts
│ └── dto/start-combat.dto.ts
└── database/
└── monsters-seed.ts
```
---
## Critères de validation integrator
- [ ] `GET /api/monsters` → liste 5 monstres
- [ ] `POST /api/combat/start` → combat résolu, log retourné
- [ ] Personnage level 1 peut vaincre Têtard Vase
- [ ] XP et or crédités après victoire
- [ ] `hpCurrent` mis à jour en DB après combat
- [ ] Endurance déduite (10) après combat
- [ ] Défaite : `hpCurrent` = 20% hpMax, endurance 60 total
- [ ] `GET /api/combat/history` → historique retourné
- [ ] Sans cookie → 401
- [ ] Endurance insuffisante (< 10) → 400
- [ ] Monster inexistant → 404
- [ ] Level up déclenché si XP seuil atteint