274 lines
11 KiB
Markdown
274 lines
11 KiB
Markdown
# Barrières techniques avant la verticale
|
|
|
|
## Objectif
|
|
|
|
Cette politique protège la verticale contre trois dérives principales :
|
|
|
|
1. transformer silencieusement les POC en code de production ;
|
|
2. dupliquer une règle dans plusieurs scènes ou interfaces ;
|
|
3. découvrir tardivement des erreurs de dépendance, de chargement ou de
|
|
régression.
|
|
|
|
Les contraintes ci-dessous sont volontairement plus strictes que nécessaire
|
|
pour un petit prototype. Une verticale engage plusieurs mois de travail ; une
|
|
frontière légèrement contraignante maintenant coûte moins cher qu'une
|
|
réécriture au milieu de la production.
|
|
|
|
## 1. Séparation physique entre prototypes et production
|
|
|
|
```text
|
|
src/ POC A et B jetables
|
|
scenes/ scènes des POC
|
|
game/ futur code de production
|
|
domain/ règles pures et données typées
|
|
application/ cas d'usage et contrats
|
|
world/ acteurs, physique et monde Godot
|
|
presentation/ HUD, écrans et rendu
|
|
infrastructure/ sauvegarde, audio, plateforme et entrées
|
|
composition/ assemblage des scènes et dépendances
|
|
content/ définitions de contenu, sans logique dupliquée
|
|
tests/
|
|
unit/ règles sans scène
|
|
integration/ assemblage de nœuds et services
|
|
contract/ ressources, sauvegardes et compatibilité
|
|
docs/adr/ décisions d'architecture immuables
|
|
scripts/ barrières qualité reproductibles
|
|
```
|
|
|
|
Les dossiers `game/` et `content/` seront créés avec la première tranche de la
|
|
verticale. Ils ne contiendront aucune copie directe des scripts des POC.
|
|
|
|
## 2. Direction unique des dépendances
|
|
|
|
```text
|
|
domain <── application <── world
|
|
▲ ▲ │
|
|
└──────────────┼── presentation
|
|
└── infrastructure
|
|
|
|
composition peut assembler toutes les branches.
|
|
```
|
|
|
|
### Domain
|
|
|
|
Contient les règles qui doivent rester vraies quel que soit l'écran ou la scène :
|
|
ressources, dégâts, intensité sonar, coût d'une amélioration, identification,
|
|
inventaire et transitions d'état.
|
|
|
|
- Classes `RefCounted` ou `Resource` typées.
|
|
- Aucun `Node`, `Input`, signal de scène, audio, fichier ou rendu.
|
|
- Aucun accès à une horloge ou à un générateur aléatoire global.
|
|
- Tests synchrones et déterministes.
|
|
|
|
### Application
|
|
|
|
Exprime ce que le joueur ou le jeu peut demander : démarrer un scan, équiper un
|
|
module, enregistrer une preuve, terminer une plongée ou vendre un objet.
|
|
|
|
- Dépend uniquement du domaine.
|
|
- Définit des ports abstraits pour sauvegarde, audio, temps ou plateforme.
|
|
- Retourne des résultats explicites ; aucune dépendance à un HUD ou un acteur.
|
|
|
|
### World
|
|
|
|
Adapte Godot aux cas d'usage : véhicule, collisions, capteurs, épaves et outils.
|
|
|
|
- Ne possède pas les règles économiques ou de campagne.
|
|
- Convertit les événements physiques en commandes d'application.
|
|
- Ne référence aucun HUD concret.
|
|
|
|
### Presentation
|
|
|
|
Affiche des snapshots et transforme une interaction en commande.
|
|
|
|
- Ne calcule pas la consommation, les dégâts, la valeur ou la réussite.
|
|
- Ne modifie pas directement un acteur ou une ressource de domaine.
|
|
- Les shaders et renderers traduisent les données ; ils ne les inventent pas.
|
|
|
|
### Infrastructure
|
|
|
|
Implémente les ports externes : sauvegardes, fichiers, audio, entrées, builds et
|
|
services de plateforme.
|
|
|
|
- Ne contient aucune règle de gameplay.
|
|
- Les erreurs d'I/O deviennent des résultats contrôlés et testables.
|
|
|
|
### Composition
|
|
|
|
Seule couche autorisée à connaître les implémentations concrètes de toutes les
|
|
autres. Elle instancie, injecte et connecte. Une scène de composition ne doit pas
|
|
devenir un second système de gameplay.
|
|
|
|
## 3. Une seule source de vérité
|
|
|
|
Chaque information mutable possède un propriétaire unique.
|
|
|
|
| Concept | Propriétaire attendu | Consommateurs |
|
|
|---|---|---|
|
|
| Oxygène, batterie, coque | état de plongée du domaine | HUD, alarmes, sauvegarde |
|
|
| Mouvement physique | acteur sous-marin du monde | caméra, télémétrie, sonar |
|
|
| Relevé sonar | service/cartographie sonar | renderer, sauvegarde éventuelle |
|
|
| Inventaire | agrégat de campagne | HUD, vente, sauvegarde |
|
|
| Contrat actif | service de contrats | objectifs, port, sauvegarde |
|
|
| Paramètres d'accessibilité | service de réglages | UI, caméra, audio, sonar |
|
|
|
|
Un consommateur reçoit un snapshot immuable ou un événement. Il ne maintient
|
|
pas une copie concurrente de l'état. Un cache doit être explicitement nommé,
|
|
invalidé par son propriétaire et vérifié par test.
|
|
|
|
## 4. Politique anti-duplication
|
|
|
|
Avant d'ajouter une fonction, rechercher le concept et ses synonymes avec `rg`.
|
|
|
|
Une similitude ne justifie pas toujours une abstraction. Extraire lorsque deux
|
|
implémentations portent la même règle métier ou doivent évoluer ensemble. Garder
|
|
deux présentations séparées lorsqu'elles partagent seulement quelques lignes de
|
|
mise en page.
|
|
|
|
Interdictions :
|
|
|
|
- copier un calcul du domaine dans un HUD ;
|
|
- dupliquer des seuils dans plusieurs scripts ;
|
|
- créer un dossier générique `utils`, `helpers`, `common` ou `shared` ;
|
|
- coder une variante par difficulté avec un second système complet ;
|
|
- dupliquer les identifiants d'actions ou les chemins de sauvegarde ;
|
|
- faire du prototype une dépendance de production.
|
|
|
|
Les constantes de réglage deviennent des ressources de configuration validées.
|
|
Les identifiants stables deviennent des types ou constantes centralisés dans
|
|
leur domaine propriétaire.
|
|
|
|
## 5. Contrats de données
|
|
|
|
Les dictionnaires anonymes sont tolérés dans les POC mais interdits aux
|
|
frontières de production. Un contrat doit préciser :
|
|
|
|
- le type de chaque champ ;
|
|
- son unité (`m`, `s`, `%`, radians) ;
|
|
- le repère spatial utilisé ;
|
|
- sa mutabilité ;
|
|
- son propriétaire ;
|
|
- sa stratégie de version si elle est sauvegardée.
|
|
|
|
Exemples attendus : `SonarSample`, `SonarScan`, `DiveSnapshot`,
|
|
`TelemetrySnapshot`, `WreckDefinition` et `SaveGameVersion`.
|
|
|
|
Les conversions entre coordonnées monde, véhicule et carte sonar se font dans
|
|
un adaptateur nommé et couvert par des tests. Aucune convention implicite de
|
|
signe ou d'axe ne doit traverser plusieurs fichiers.
|
|
|
|
## 6. Tests obligatoires
|
|
|
|
### Pyramide
|
|
|
|
1. **Unitaires** : majorité des tests ; domaine pur, rapides et déterministes.
|
|
2. **Contrats** : ressources, sérialisation, migrations, configurations et
|
|
invariants de contenu.
|
|
3. **Intégration** : scènes minimales, signaux, physique et assemblage.
|
|
4. **Parcours** : peu nombreux ; une boucle complète avec critères observables.
|
|
5. **Visuels et humains** : lisibilité, contraste, mouvement et compréhension.
|
|
|
|
### Règles
|
|
|
|
- Tout bug corrigé commence par un test qui échoue lorsque c'est raisonnable.
|
|
- Aucun test ne dépend du réseau, de l'heure réelle ou d'un ordre aléatoire.
|
|
- Les attentes temporelles utilisent une horloge injectée ou un nombre de ticks
|
|
borné, jamais un sommeil arbitraire.
|
|
- Une scène d'intégration construit le minimum requis pour le comportement.
|
|
- Les tests vérifient des résultats, pas la structure interne d'une méthode.
|
|
- Une migration de sauvegarde garde un échantillon de chaque version supportée.
|
|
- Le contenu principal reçoit des tests de validation : ID uniques, références
|
|
résolues, profondeur possible et absence de blocage narratif.
|
|
|
|
### Barrière actuelle
|
|
|
|
`bash scripts/quality_gate.sh` exécute dans cet ordre :
|
|
|
|
1. règles d'architecture ;
|
|
2. chargement de tous les scripts et scènes ;
|
|
3. tests unitaires existants ;
|
|
4. tests d'intégration du POC B.
|
|
|
|
La verticale ajoutera ses suites à cette commande unique. Une fonctionnalité ne
|
|
peut pas être déclarée terminée si la barrière échoue.
|
|
|
|
La commande locale est la barrière active dans le dépôt actuel. Avant la
|
|
première fusion de code de production sur un dépôt distant, elle devra devenir
|
|
un contrôle CI obligatoire avec protection de branche. La CI appellera ce même
|
|
script ; elle ne maintiendra pas une seconde liste de tests.
|
|
|
|
## 7. Taille et responsabilités
|
|
|
|
Seuils de revue, non objectifs mécaniques :
|
|
|
|
- au-delà de 350 lignes par fichier, vérifier si plusieurs responsabilités sont
|
|
mêlées ;
|
|
- au-delà de 40 lignes par fonction, vérifier si des étapes nommées manquent ;
|
|
- au-delà de cinq dépendances injectées, vérifier si le composant orchestre trop
|
|
de domaines ;
|
|
- une scène ne doit avoir qu'une racine de composition identifiable ;
|
|
- un signal doit décrire un fait passé, une commande une intention.
|
|
|
|
Une exception justifiée vaut mieux qu'un découpage artificiel. Une exception
|
|
durable doit être documentée dans un ADR.
|
|
|
|
## 8. Gestion des erreurs et observabilité
|
|
|
|
- Toute erreur récupérable produit un résultat explicite et un message utile.
|
|
- Les erreurs de sauvegarde ne doivent jamais écraser la dernière sauvegarde
|
|
valide.
|
|
- Les ressources invalides échouent au chargement ou au test de contrat.
|
|
- Les logs n'enregistrent aucune donnée personnelle ou secret.
|
|
- Les événements importants portent un contexte : mission, site, scan ou version.
|
|
- Les fuites de nœuds, avertissements et erreurs Godot sont triés avant fusion.
|
|
|
|
## 9. Sauvegardes et migrations
|
|
|
|
- Format versionné dès le premier prototype de verticale sauvegardé.
|
|
- Écriture dans un fichier temporaire, validation, puis remplacement atomique.
|
|
- Jamais de sérialisation arbitraire de nœuds ou de physique.
|
|
- IDs stables plutôt que chemins de scène comme identité métier.
|
|
- Migration explicite d'une version à la suivante.
|
|
- Sauvegardes de référence anonymes conservées sous `tests/fixtures/`.
|
|
|
|
## 10. Entrées, accessibilité et localisation
|
|
|
|
- Le gameplay dépend d'actions abstraites, jamais de touches codées en dur.
|
|
- Une seule infrastructure traduit les périphériques en commandes.
|
|
- Toute nouvelle action est remappable et documentée.
|
|
- Les textes visibles sont identifiables pour la localisation ; aucun texte
|
|
métier n'est construit par concaténation fragile.
|
|
- Les informations critiques combinent texte, forme, son ou animation avec la
|
|
couleur.
|
|
- Les options réduisant mouvement, flash et contraste sont consultées par la
|
|
présentation, pas recodées dans chaque effet.
|
|
|
|
## 11. Décisions d'architecture
|
|
|
|
Un ADR est requis avant :
|
|
|
|
- un nouvel autoload ;
|
|
- une dépendance qui inverse le graphe défini ici ;
|
|
- un format de sauvegarde ou une migration ;
|
|
- une technologie externe ou un plugin ;
|
|
- une exception durable à une barrière automatique ;
|
|
- un changement de renderer ou de version Godot pendant un jalon.
|
|
|
|
Un ADR décrit le contexte, la décision, ses conséquences et les alternatives
|
|
rejetées. Il ne doit pas être réécrit pour masquer une ancienne décision ; un
|
|
nouvel ADR le remplace explicitement.
|
|
|
|
## 12. Ordre de mise en production
|
|
|
|
Avant le premier gameplay de la verticale :
|
|
|
|
1. créer les couches vides et leur test d'architecture ;
|
|
2. définir les premiers contrats typés ;
|
|
3. porter une règle pure avec ses tests ;
|
|
4. créer une seule scène de composition ;
|
|
5. intégrer le véhicule puis le sonar par adaptateurs ;
|
|
6. ajouter un parcours end-to-end minimal ;
|
|
7. seulement ensuite ajouter contenu, port et économie.
|
|
|
|
Chaque tranche doit rester jouable et laisser la barrière qualité verte.
|