feat(combat): apply cumulative -2 range penalties per increment
This commit is contained in:
@@ -72,10 +72,10 @@ players : 3 combatants
|
||||
monsters : 2 combatants
|
||||
1000 combats simulés (seed 1, plafond 100 rounds)
|
||||
|
||||
Victoires players : 100.0% (1000) — bande 3σ : [100.0%, 100.0%]
|
||||
Victoires monsters : 0.0% (0) — bande 3σ : [0.0%, 0.0%]
|
||||
Victoires players : 98.1% (981) — bande 3σ : [96.8%, 99.4%]
|
||||
Victoires monsters : 1.9% (19) — bande 3σ : [0.6%, 3.2%]
|
||||
Nuls : 0.0% (0)
|
||||
Rounds moyens : 5.8
|
||||
Rounds moyens : 6.6
|
||||
```
|
||||
|
||||
## Utilisation de la CLI
|
||||
@@ -130,9 +130,11 @@ confiance à 3σ calculée en forme fermée (modèle binomial) :
|
||||
immobiles, camps inaccessibles…).
|
||||
|
||||
Exemple vérifié — 1 gobelin (players) contre 2 orcs (monsters), 1000 runs,
|
||||
seed 1 : players 55,7 %, bande 3σ [51,0 % ; 60,4 %], 0 nuls, 13,1 rounds moyens.
|
||||
seed 1 : players 49,6 %, bande 3σ [44,9 % ; 54,3 %], 0 nuls, 11,4 rounds moyens.
|
||||
Sans ligne de visée depuis la zone de départ, l'archer gobelin doit contourner
|
||||
le mur central avant de tirer — c'est ce qui coûte des rounds.
|
||||
le mur central avant de tirer ; une fois la ligne de visée gagnée, il tire de
|
||||
loin avec la pénalité de portée au lieu de s'approcher — c'est ce qui équilibre
|
||||
le face-à-face à 1 contre 2.
|
||||
|
||||
## Formats de données
|
||||
|
||||
@@ -228,9 +230,11 @@ ligne d'effet ⇒ l'attaque est impossible ; couvert ⇒ bonus de +4 CA.
|
||||
}
|
||||
```
|
||||
|
||||
Champ `range_increment_ft` (optionnel, uniquement pour `kind: ranged`) : portée
|
||||
maximale de tir — au-delà, l'arme n'est pas utilisable. `damage_bonus` et `dr`
|
||||
sont optionnels. Deux monstres d'exemple sont fournis : gobelin et orc.
|
||||
Champ `range_increment_ft` (optionnel, uniquement pour `kind: ranged`) :
|
||||
incrément de portée en pieds. La pénalité de portée vaut −2 par incrément
|
||||
complet au-delà du premier ; l'arme reste utilisable jusqu'à 10 incréments,
|
||||
au-delà elle n'est pas sélectionnable. `damage_bonus` et `dr` sont optionnels.
|
||||
Deux monstres d'exemple sont fournis : gobelin et orc.
|
||||
|
||||
### Fiches de personnages (PJ)
|
||||
|
||||
@@ -274,15 +278,17 @@ Règles modélisées :
|
||||
- Couvert (règle des coins) : la cible gagne +4 CA sur la touche et la
|
||||
confirmation de critique ; le couvert octroyé par les créatures n'est pas
|
||||
modélisé.
|
||||
- Distance : l'arme doit être à portée (range_increment_ft) ; aucune pénalité
|
||||
de portée au-delà du premier incrément.
|
||||
- Distance : pénalité cumulative de −2 par incrément de portée complet au-delà
|
||||
du premier, appliquée au jet d'attaque et à la confirmation de critique ;
|
||||
l'arme ranged reste utilisable jusqu'à 10 incréments. Les armes de jet
|
||||
(5 incréments max) ne sont pas distinguées des armes à projectiles.
|
||||
|
||||
Non modélisé en Phase 0 (couches `elevation`/`markers` présentes mais non
|
||||
appliquées dans la résolution) :
|
||||
|
||||
- Sorts, jets de sauvegarde, conditions et états.
|
||||
- Attaques d'opportunité, flanquement, manœuvres de combat.
|
||||
- Pénalités de portée (distance) et couvert mou des créatures.
|
||||
- Couvert mou des créatures.
|
||||
- Effets mécaniques de hauteur/élévation.
|
||||
- Tailles Large+ (2×2), allonge > 5 ft, itératifs de BAB, économie d'action
|
||||
complète (charge, pas de placement…).
|
||||
@@ -301,8 +307,8 @@ appliquées dans la résolution) :
|
||||
- `los.py` — ligne d'effet et couvert par la règle des coins : gate de ligne
|
||||
d'effet dans `weapon_for`, bonus de couvert +4 CA dans `resolve_attack`.
|
||||
- `combat.py` — `CombatEngine` déterministe : initiative, actions, résolution
|
||||
des attaques (couvert, ligne d'effet), états de vie, transcripts, politique
|
||||
par défaut.
|
||||
des attaques (couvert, ligne d'effet, pénalités de portée), états de vie,
|
||||
transcripts, politique par défaut.
|
||||
- `metrics.py` — statistiques en forme fermée : `win_rate`, `win_rate_sigma`,
|
||||
`win_rate_band` (bande 3σ bornée à [0, 1]).
|
||||
- `runner.py` — `EncounterSpec`/`Side`, `build_states` (placement en zone +
|
||||
@@ -318,7 +324,7 @@ appliquées dans la résolution) :
|
||||
La gate de validation complète (tests + lint + types) :
|
||||
|
||||
```bash
|
||||
uv run pytest -q # 182 tests
|
||||
uv run pytest -q # 189 tests
|
||||
uv run ruff check src tests
|
||||
uv run basedpyright src # mode strict
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user