docs: document B5 engine hardening - reach, sizes, elevation, immediate actions
This commit is contained in:
@@ -166,7 +166,7 @@ legend: # un caractère = un type de terrain
|
|||||||
"~": { type: water, move_cost: 2 }
|
"~": { type: water, move_cost: 2 }
|
||||||
"C": { type: pillar, move_cost: null, cover: true } # bloque le pas, couvert
|
"C": { type: pillar, move_cost: null, cover: true } # bloque le pas, couvert
|
||||||
|
|
||||||
elevation: | # optionnel : chiffres = hauteur (validé, pas encore appliqué)
|
elevation: | # optionnel : chiffres = hauteur (appliqué : coût de pas + high ground)
|
||||||
....................
|
....................
|
||||||
..1111..............
|
..1111..............
|
||||||
..1111..............
|
..1111..............
|
||||||
@@ -273,7 +273,8 @@ Règles modélisées :
|
|||||||
`default_policy` renvoie `(full_attack,)` si l'ennemi est en portée, `(charge,)`
|
`default_policy` renvoie `(full_attack,)` si l'ennemi est en portée, `(charge,)`
|
||||||
si une ligne droite existe, `(5foot_step, full_attack)` si un seul pas
|
si une ligne droite existe, `(5foot_step, full_attack)` si un seul pas
|
||||||
suffit à entrer en portée, ou `(move, attack)` sinon. Les actions immédiates
|
suffit à entrer en portée, ou `(move, attack)` sinon. Les actions immédiates
|
||||||
(hors-tour, consomment le prochain swift) ne sont pas encore modélisées.
|
(hors-tour, consomment le prochain swift) sont modélisées via une politique
|
||||||
|
de réaction opt-in (`reaction_policy`) — voir « Actions immédiates » ci-dessous.
|
||||||
- Attaques multiples par action : une arme avec `count` > 1 (« 2x Talons »)
|
- Attaques multiples par action : une arme avec `count` > 1 (« 2x Talons »)
|
||||||
résout `count` balayages indépendants dans la même action ; les balayages
|
résout `count` balayages indépendants dans la même action ; les balayages
|
||||||
restants sont perdus si la cible tombe (inconsciente ou morte) en cours de
|
restants sont perdus si la cible tombe (inconsciente ou morte) en cours de
|
||||||
@@ -281,11 +282,34 @@ Règles modélisées :
|
|||||||
attaques supplémentaires à -5/-10/-15 ; les armes naturelles (`count` > 1)
|
attaques supplémentaires à -5/-10/-15 ; les armes naturelles (`count` > 1)
|
||||||
ne gagnent pas d'itératifs. Plusieurs armes naturelles en une seule attaque
|
ne gagnent pas d'itératifs. Plusieurs armes naturelles en une seule attaque
|
||||||
à outrance ne sont pas modélisées.
|
à outrance ne sont pas modélisées.
|
||||||
- Mêlée : allonge d'une case ; mouvement : un déplacement parcourt jusqu'à la
|
- Mêlée : allonge effective = max(allonge naturelle du gabarit (Small/Medium
|
||||||
|
5 ft, Large 10 ft, Huge 15 ft, Gargantuan 20 ft, Colossal 30 ft), `reach_ft`
|
||||||
|
de l'arme). Une arme à allonge (`reach_ft` > 5) menace l'anneau de cases à
|
||||||
|
distance égale à son allonge — les cases à 5 ft sont une « dead zone » où
|
||||||
|
elle ne frappe pas ; une arme sans allonge menace les cases adjacentes.
|
||||||
|
Mouvement : un déplacement parcourt jusqu'à la
|
||||||
vitesse du combattant en cases le long du plus court chemin réel (champ de
|
vitesse du combattant en cases le long du plus court chemin réel (champ de
|
||||||
coût Dijkstra depuis la cible, diagonales 5-10-5), en s'arrêtant adjacent à
|
coût Dijkstra depuis la cible, diagonales 5-10-5), en s'arrêtant adjacent à
|
||||||
l'ennemi le plus proche — les combattants contournent les murs au lieu
|
l'ennemi le plus proche — les combattants contournent les murs au lieu
|
||||||
d'osciller contre eux.
|
d'osciller contre eux.
|
||||||
|
- Tailles et occupation multi-cases : une créature occupe un footprint carré à
|
||||||
|
son ancre (`pos`) selon sa taille — Small/Medium 1×1, Large 2×2, Huge 3×3,
|
||||||
|
Gargantuan 4×4, Colossal 6×6 (taille inconnue → 1×1). Distance, ligne
|
||||||
|
d'effet/couvert, flanquement, zones menacées, AoO, charge, mouvement,
|
||||||
|
manœuvres et invocation sont généralisés aux cellules occupées (distance =
|
||||||
|
minimum entre cellules, LoS/couvert = meilleure paire) ; le comportement 1×1
|
||||||
|
reste bit-identique.
|
||||||
|
- Élévation : monter d'un niveau de hauteur coûte +1 case de mouvement par
|
||||||
|
niveau (la descente est gratuite) ; une créature située plus haut que sa
|
||||||
|
cible gagne +1 à ses jets d'attaque de mêlée et à la confirmation de
|
||||||
|
critique (règle du high ground). La ligne d'effet reste 2D (pas de LoS 3D).
|
||||||
|
- Actions immédiates hors-tour : politique de réaction optionnelle
|
||||||
|
`reaction_policy(engine, state, event)` (défaut : aucune) ; sur événement
|
||||||
|
(`attack_resolved`, `movement_step`, `spell_cast`, `damage_taken`) une
|
||||||
|
réaction `Action(kind="immediate")` peut être exécutée hors tour — une par
|
||||||
|
événement — et consomme le prochain swift de l'état (immédiate pendant le
|
||||||
|
tour : exécutée, consomme aussi le prochain swift — simplification
|
||||||
|
documentée).
|
||||||
- Ligne d'effet : une cible entièrement derrière un terrain `blocks_los` ne
|
- Ligne d'effet : une cible entièrement derrière un terrain `blocks_los` ne
|
||||||
peut pas être attaquée — la politique se déplace jusqu'à gagner une ligne de
|
peut pas être attaquée — la politique se déplace jusqu'à gagner une ligne de
|
||||||
visée.
|
visée.
|
||||||
@@ -298,7 +322,9 @@ Règles modélisées :
|
|||||||
distance ignorent le flanquement ; un allié désarmé ou à distance ne compte
|
distance ignorent le flanquement ; un allié désarmé ou à distance ne compte
|
||||||
pas pour le flanquement.
|
pas pour le flanquement.
|
||||||
- Attaques d'opportunité : un combattant actif doté d'une arme de mêlée menace
|
- Attaques d'opportunité : un combattant actif doté d'une arme de mêlée menace
|
||||||
les 8 cases adjacentes. Deux déclencheurs sont modélisés : (1) quitter une
|
les cases à distance de son allonge effective (les 8 cases adjacentes pour
|
||||||
|
une arme sans allonge ; l'anneau à son allonge pour une arme reach — la
|
||||||
|
dead zone de 5 ft n'est pas menacée). Deux déclencheurs sont modélisés : (1) quitter une
|
||||||
case menacée — le mouvement est résolu pas à pas, et chaque ennemi qui menace
|
case menacée — le mouvement est résolu pas à pas, et chaque ennemi qui menace
|
||||||
la case actuelle porte une AoO avant que le mouvant ne la quitte ; (2) tirer
|
la case actuelle porte une AoO avant que le mouvant ne la quitte ; (2) tirer
|
||||||
avec une arme à distance depuis une case menacée — chaque ennemi menaçant
|
avec une arme à distance depuis une case menacée — chaque ennemi menaçant
|
||||||
@@ -423,13 +449,8 @@ Règles modélisées :
|
|||||||
`paralysé` 1d4+1 rounds), RD 15/magie+contondant ; son JSON porte un dictionnaire
|
`paralysé` 1d4+1 rounds), RD 15/magie+contondant ; son JSON porte un dictionnaire
|
||||||
`spell_slots` sans clés dupliquées.
|
`spell_slots` sans clés dupliquées.
|
||||||
|
|
||||||
Non modélisé (couches `elevation`/`markers` présentes mais non appliquées
|
Non modélisé (couche `markers` présente mais non appliquée dans la
|
||||||
dans la résolution) :
|
résolution) :
|
||||||
|
|
||||||
- Effets mécaniques de hauteur/élévation (les hauteurs sont validées mais non
|
|
||||||
appliquées au déplacement, à la portée ou à la ligne d'effet).
|
|
||||||
- Tailles Large+ (2×2), allonge > 5 ft (la mêlée reste limitée à une case) et
|
|
||||||
actions immédiates hors-tour (consommeraient le prochain swift).
|
|
||||||
- Manœuvres : dirty trick applique toujours `dazzled` (le choix
|
- Manœuvres : dirty trick applique toujours `dazzled` (le choix
|
||||||
aveuglé/assourdi/entravé/malade n'est pas modélisé) ; reposition et drag
|
aveuglé/assourdi/entravé/malade n'est pas modélisé) ; reposition et drag
|
||||||
utilisent une direction déterministe (premier voisin libre / au-delà de la
|
utilisent une direction déterministe (premier voisin libre / au-delà de la
|
||||||
@@ -446,14 +467,17 @@ dans la résolution) :
|
|||||||
`DamageComponent`, `Saves`, `DamageReduction`.
|
`DamageComponent`, `Saves`, `DamageReduction`.
|
||||||
- `map.py` — `MapSpec`/`TerrainType`, chargement YAML et validation
|
- `map.py` — `MapSpec`/`TerrainType`, chargement YAML et validation
|
||||||
(dimensions, caractères connus, zones, déploiement, markers).
|
(dimensions, caractères connus, zones, déploiement, markers).
|
||||||
- `grid.py` — grille 5-10-5 : `distance`, `step_cost`, règle des coins
|
- `grid.py` — grille 5-10-5 : `distance`, `step_cost` (terrain + élévation),
|
||||||
(`diagonal_allowed`), Dijkstra `reachable` avec ou sans budget.
|
règle des coins (`diagonal_allowed`), Dijkstra `reachable` avec ou sans
|
||||||
|
budget.
|
||||||
- `los.py` — ligne d'effet et couvert par la règle des coins : gate de ligne
|
- `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 (terrain et couvert mou
|
d'effet dans `weapon_for`, bonus de couvert +4 CA (terrain et couvert mou
|
||||||
des créatures) dans `resolve_attack`.
|
des créatures) dans `resolve_attack`.
|
||||||
- `combat.py` — `CombatEngine` déterministe : initiative, actions, résolution
|
- `combat.py` — `CombatEngine` déterministe : initiative, actions, résolution
|
||||||
des attaques (couvert, ligne d'effet, pénalités de portée, CA de contact
|
des attaques (couvert, ligne d'effet, pénalités de portée, CA de contact
|
||||||
pour les attaques touch et firearms), états de vie, incantation
|
pour les attaques touch et firearms), tailles et allonges (occupation
|
||||||
|
multi-cases, zones menacées en anneau), high ground, actions immédiates
|
||||||
|
opt-in (réactions hors-tour), états de vie, incantation
|
||||||
(emplacements, concentration par situation, AoO d'incantation), invocation,
|
(emplacements, concentration par situation, AoO d'incantation), invocation,
|
||||||
manœuvres, capacités de classe, transcripts, politique par défaut. Les
|
manœuvres, capacités de classe, transcripts, politique par défaut. Les
|
||||||
modificateurs conditionnés (`StatModifier.condition`) sont évalués via
|
modificateurs conditionnés (`StatModifier.condition`) sont évalués via
|
||||||
@@ -533,9 +557,11 @@ uv run basedpyright src # mode strict
|
|||||||
conditions effectives (`conditions.py`), manœuvres de combat, dons (55 noms
|
conditions effectives (`conditions.py`), manœuvres de combat, dons (55 noms
|
||||||
résolus, `abilities.py` + chargeur) et capacités de classe (channel energy,
|
résolus, `abilities.py` + chargeur) et capacités de classe (channel energy,
|
||||||
hex, deeds, inspire courage / spell combat) sont en place et documentés dans
|
hex, deeds, inspire courage / spell combat) sont en place et documentés dans
|
||||||
« Règles implémentées ». Restent hors du socle (voir « Non modélisé ») : les
|
« Règles implémentées ». Le socle B5 est en place : hauteurs/élévations
|
||||||
hauteurs/élévations, tailles Large+, allonges > 5 ft et actions immédiates
|
(coût de déplacement + high ground), tailles Large+ (occupation multi-cases),
|
||||||
hors-tour.
|
allonges > 5 ft (allonge naturelle + `reach_ft`, zones menacées en anneau) et
|
||||||
|
actions immédiates hors-tour (politique de réaction opt-in). Restent hors du
|
||||||
|
socle (voir « Non modélisé ») : les markers et les manœuvres avancées.
|
||||||
- **Phase 2** — couche tactique LLM : stratégies en langage naturel traduites
|
- **Phase 2** — couche tactique LLM : stratégies en langage naturel traduites
|
||||||
en politiques, balayage de matrices de positionnement. (Non implémentée.)
|
en politiques, balayage de matrices de positionnement. (Non implémentée.)
|
||||||
- **Phase 3** — rapporteur LLM local : agrégation des statistiques et
|
- **Phase 3** — rapporteur LLM local : agrégation des statistiques et
|
||||||
|
|||||||
Reference in New Issue
Block a user