99e9203d8c
Consolidates the round-1 audit: 15 fixed divergences (one commit each, 312f9fd..ea60b2e), the deliberate out-of-scope rules, the assumed residuals, and the verified-conformant guard rails. Linked from README.
10 KiB
10 KiB
Conformité SRD Pathfinder 1re édition — journal d'audit
Ce document consigne, de façon exhaustive et vérifiable, l'écart entre les règles
implémentées par le moteur et le SRD Pathfinder 1re édition. Il complète le
README.md (qui décrit le comportement attendu) en traçant ce qui a été
corrigé, ce qui est hors périmètre, et ce qui reste assumé comme
résiduel.
Méthode
- Audit read-only par domaine : chaque passe couvre un domaine étanche
(sorts, mouvement, morts-vivants, dons, manœuvres, conditions, données de
sorts, bestiaire). L'auditeur croise le code avec la base de connaissances
SRD (
pathfinder-kb, collectionpathfinder-1e-rules) et cite la règle. - Classement :
High(change matériellement l'issue d'un combat),Med(clairement faux, impact étroit),Low(donnée / cosmétique). - Correction : un commit par correctif, gate complète verte avant chaque
commit (
ruffselect=ALL,basedpyrightstrict,pytest). - Non-régression : le transcript doré (
tests/test_pc_combat_golden.py) n'est réécrit que lorsqu'un correctif SRD change légitimement la sortie, avec justification ligne à ligne. - Traçabilité : tout constat non corrigé est classé ici en hors périmètre (choix délibéré) ou résiduel assumé (écart connu, non corrigé).
État de la gate
| Contrôle | Résultat |
|---|---|
uv run pytest -q |
1491 tests verts |
uv run ruff check src tests (select=ALL) |
conforme |
uv run basedpyright src (strict) |
0 erreur |
| Transcript doré depuis la passe 1 | inchangé |
1. Écarts corrigés
Passe 1 — sorts de buff, mouvement/grille, morts-vivants, armes naturelles
| # | Constat | Sév. | Correctif (commit) |
|---|---|---|---|
| B1 | Bless affectait toutes les créatures d'un burst de 20 ft (y compris les ennemis) ; le SRD cible « you and each of your allies within a 50-ft. burst » | High | e43066e — filtre AreaEffect.targets (all/allies/enemies), burst 50 ft, alliés + lanceur |
| B2 | Bane était un sort mono-cible ; le SRD cible les ennemis dans un burst de 50 ft | Med | 5e3505d — conversion en AreaEffect 50 ft, targets: "enemies" |
| B3 | Bladed Dash : niveau 1 (au lieu de 2), portée close (au lieu de personal) |
Med | 312f9fd |
| B4 | Aid : niveau 1 (au lieu de 2), portée long (au lieu de touch) |
Med | 312f9fd |
| B5 | Doom : portée close (au lieu de medium) |
Med | 312f9fd |
| B6 | Bull's Strength : sauvegarde fort (le SRD n'accorde pas de jet ; valeur neutre corrigée en will) |
Med | 312f9fd |
| B7 | Bear's Endurance : sauvegarde fort (idem) |
Med | 312f9fd |
| B8 | Mage Armor absent du registre | Low | 3e19d29 — sort ajouté (niveau 1, conjuration, contact, +4 CA d'armure, RM non) + type de bonus "armor" non cumulable (registre porté à 108 sorts) |
| C1 | Budget de déplacement : parité des diagonales figée à 0 dans les descentes gloutonnes → la règle 5-10-5 était violée (un marcheur vitesse 30 parcourait 6 cases en diagonale au lieu de 4) | Med | 2cc2ba1 — parité propagée (_best_move_step, _descend_path, _run_line_path, _flee_path) + _path_cost_5105 pour la charge |
| C2 | Pas de placement (5 ft) autorisé depuis/vers un terrain difficile | Med | 437507e — rejet si le footprint courant ou la destination touche du terrain difficile |
| C3 | Entrer dans la case d'une créature hostile ne provoquait pas d'AoO | Med | 9a16ca0 — _check_enter_aoo câblé dans _walk_steps |
| C4 | Traversée d'une case hostile à ≥ 3 catégories d'écart de taille non modélisée | Med | 9a16ca0 — _can_pass_through (porte « traversée ») distincte de _blocked (porte « fin de mouvement ») |
| C5 | Un combattant fatigué/épuisé pouvait courir (seule la charge était bloquée) ; le SRD : « can neither run nor charge » | Low | 7fc7a1d — garde cant_charge ajoutée à _execute_run |
| D1 | Les morts-vivants (et les créatures artificielles) mouraient à hp ≤ -CON au lieu d'être détruits à hp ≤ 0 |
Med | 59caf67 — seuil de mort à 0, pas de bande d'agonie |
| D2 | Fiche du liche non conforme au bloc SRD : BAB 8 (au lieu de +5), contact +10 (au lieu de +5), damage_bonus 5 doublant la formule (dégâts réels 1d8+10 au lieu de 1d8+5), CA 25/14/23 (au lieu de 23/14/21), jets 10/10/14 (au lieu de 6/7/11), con_score 14 alors qu'un mort-vivant n'a pas de Constitution |
Low | 881f2ef |
| D3 | Les sorts de soin (cure) soignaient les morts-vivants au lieu de les blesser |
Low | cad35e2 — dégâts (Volonté pour moitié), ni RD ni stabilisation |
| A1 | Armes naturelles : itératifs de BAB accordés à tort et absence de la pénalité −5 des attaques secondaires | Med | e5691bd — champs natural/secondary (une seule attaque, secondaires −5, Multiattack −2) |
Passe 2 — dons/capacités, manœuvres, conditions, données de sorts
En cours. Les constats de la passe 2 sont ajoutés ci-dessous à mesure que les audits reviennent (voir § 6, journal des audits).
| # | Constat | Sév. | Correctif (commit) |
|---|---|---|---|
| — | (à compléter) | — | — |
2. Hors périmètre (choix délibéré, documenté)
Ces règles sont volontairement non modélisées et signalées dans le
README.md (sections « Limites hors périmètre » et « Limites de sorts ») pour
ne pas être confondues avec des bogues.
| Sujet | Raison |
|---|---|
| Squeeze (se serrer dans un passage étroit) | La largeur de couloir n'est pas comparée à la taille ; une créature bloquée par son footprint l'est sans option de squeeze payante |
| Acrobatics « Tumbling » (traverser une case ennemie sans AoO) | Le moteur n'a pas de système de compétences |
| Créature inerte très grande = obstacle à 2 cases | Les cases d'une créature inactive ne bloquent pas et ne coûtent pas double |
| Échec d'incantation du personnage sourd (20 %) | SpellSpec n'a pas de composante verbale ; il faudrait encoder les composantes sur les 108 sorts |
Incantation multi-round (long : 3 rounds, 10 min, 1 h) |
Non planifiable dans un tour ; jetée du budget (downgraded:cast_time) plutôt qu'approximée |
| Co-occupation au-delà de Tiny vs plus grand | Deux créatures Small+ ne partagent jamais une case ; plusieurs Tiny sur une case non gérés |
| Combat à deux armes / arme en main secondaire (×0,5 Force) | Hors du modèle d'attaque actuel |
| Vol 3D / vol par-dessus les obstacles | La vitesse de vol est un budget au sol ; pas de maniabilité ni de survol du terrain |
markers (points nommés de la carte) |
Validés à la lecture, non appliqués à la résolution |
3. Résiduels assumés (écart connu, non corrigé)
| Sujet | Nature de l'écart | Décision |
|---|---|---|
| Course — durée liée à la Constitution, don Run, armure lourde (×3) | Le SRD limite la course à CON tours puis impose un jet de Constitution DD 10, et réduit la vitesse de course en armure lourde ; le moteur applique toujours ×4 |
Assumé : aucun scénario courant ne course plus de quelques tours |
| Dégâts non létaux | Absents du modèle de PV | Assumé : aucune source de dégâts non létaux dans les données |
| Armes à éclaboussures / dégâts d'éclaboussure | Absents (pas d'objet concerné dans les données) | Assumé |
| Sort « harmless » sur cible consentante | Le moteur roule tout de même une sauvegarde (consommation de RNG) ; l'issue du soin n'en dépend pas | Assumé : fidélité de déterminisme, pas d'effet observable |
| Réglages du liche non SRD (pv 100 vs 111, Force, Intelligence, initiative, aura de terreur 30 ft/DD 22 vs 60 ft/DD 18) | Réglages d'équilibrage du scénario doré | Assumé : conservés pour ne pas casser la fiche dorée |
| Dés énergétiques non multipliés par un critique (contact du liche) | Règle moteur globale (exceptions CRB « Critical Hits ») | Assumé : cohérent avec les autres attaques |
selective_channeling non modélisé |
Le canal d'énergie affecte toutes les créatures du type visé dans la zone | Assumé (documenté au README) |
4. Conformités vérifiées (garde-fous anti-régression)
Constats explicitement contrôlés et confirmés conformes :
- Résistance aux sorts : le drapeau
spell_resistanceest respecté et_check_spell_resistancecourt-circuite sans consommer de RNG quand la cible n'a pas de RM. - Description de Lightning Bolt (ligne 120 ft, 1d6/niveau plafonné 10d6, Réflexes demi) : conforme.
- Diagonale entrant en terrain difficile : coût plat de 3 cases, convention
de table explicite dans
grid.py, cohérente entre Dijkstra et descentes. - Terrain mixte : les coûts de pas s'additionnent sans double comptage.
- Déplacement d'un personnage aveuglé : le SRD n'interdit ni le déplacement, ni la course, ni la charge à un aveugle (seuls la touche, la CA et les compétences sont affectés) — le constat d'audit initial ne visait pas une vraie règle.
5. Journal des audits
| Passe | Domaines | Sessions | Constats | Statut |
|---|---|---|---|---|
| 1 | Sorts (B), Mouvement/grille (C), Morts-vivants (D), Armes naturelles (A) | bg_9e9e22e6, bg_cda707bf, bg_ba80396a, bg_6a621d4c |
1 High, 12 Med, ~20 Low | Corrigés + documentés (ci-dessus) |
| 2 | Dons/capacités (E), Manœuvres (F), Conditions (G), Données de sorts (H) | bg_e764efda, bg_9fdc610e, bg_f5829c68, bg_b289533d |
en cours | En cours de triage |
| 3+ | Bestiaire/PJ (données), résolution d'attaque/défense, économie d'action, sorts restants | — | à lancer | À faire |
6. Relancer une passe d'audit
Chaque passe suit le même protocole :
- Choisir un domaine non encore audité (voir le journal § 5).
- Lancer un auditeur read-only (agent
oracle) avec la base SRDpathfinder-kbet l'exigence de citer la règle et la ligne de code fautive. - Trier chaque constat : corriger (si l'impact est matériel et le correctif propre) ou classer en hors périmètre / résiduel assumé (ce document).
- Un commit par correctif ; gate complète verte ; transcript doré préservé ou justifié ligne à ligne.
- Reporter les constats dans les tableaux ci-dessus et la ligne de journal.