|
JustAnotherDnDGame 0.1.0
Jeu de rôle tactique au d20, vue de dessus, en C++/Qt
|
Statut : fait (vérification automatisée : build /W4 /WX sans avertissement, ctest à 919/919, lint d'exigences, cahier de test, Doxygen et clang-format verts). Prérequis : LOT-02, LOT-04.
Sortir de hmi::GameSession l'ordre codé en dur des passes du pas fixe, derrière une interface hmi::IGameMode.
Source/HMI/Game/GameSession.cpp mêle deux rôles : orchestrateur du pas fixe (monde ECS, caméra, événements, HUD, FixedTimestep, interpolation de rendu) et mode de jeu (l'ordre des passes lui-même). Tant qu'il n'y avait qu'un genre, la confusion ne coûtait rien.
Le RPG a besoin d'au moins trois ordres différents :
Sans cette séparation, les trois s'entasseraient en if dans une fonction déjà longue.
Ce lot est un refactoring à comportement constant, et c'est le plus risqué du programme : tout ce qui suit en dépend. Il doit être validé par un test de rejeu déterministe — mêmes entrées, mêmes positions au flottant près sur 600 pas, avant et après extraction.
N'y ajouter aucune fonctionnalité. Le mode dialogue et le mode combat arrivent aux LOT-15 et LOT-18 ; les écrire ici mélangerait un refactoring et une nouveauté, et on ne saurait plus lequel des deux a cassé quoi.
EX-ARCH-* : « l'ordre des passes du pas fixe est une donnée du mode de jeu, jamais de l'orchestrateur ».
Les passes sont une interface, pas des paramètres. L'epic esquissait step(World&, const PlayerInput&, float). Un World ne suffit pas : les passes touchent la caméra, les particules, la secousse d'écran, les mécanismes, la détection d'événements — tout ce que l'orchestrateur garde, par décision du périmètre. Le mode reçoit donc IGameModePasses, que GameSession implémente par héritage privé : les passes sont offertes au mode, jamais à l'appelant de la session, dont l'API publique ne bouge pas d'une ligne.
Le test de rejeu déterministe porte sur la séquence des passes, pas sur des positions. Le critère de l'epic demandait « mêmes entrées, mêmes positions au flottant près sur 600 pas ». Deux obstacles : GameSession exige un atlas, un lot de sprites et une police — impossible à instancier sans fenêtre, et aucun test ne l'instancie aujourd'hui ; et le personnage ne se déplace pas encore (le contrôleur top-down arrive au LOT-06), si bien que des positions constantes ne prouveraient rien. Ce que l'extraction doit garantir, c'est que l'ordre des passes n'a pas changé — et c'est vérifiable exactement, sur 600 pas, contre des passes qui enregistrent leurs appels. Le mode annonce son ordre (passOrder(), pour les diagnostics) et un test le compare à la séquence réellement appelée : la documentation ne peut plus diverger du code sans faire échouer la CI.
La boîte du personnage est relue par chaque passe qui en a besoin, plutôt que calculée une fois et passée de l'une à l'autre. Aucune passe intercalée ne déplace le personnage — le résultat est identique — et un état partagé de plus entre passes aurait rendu leur ordre difficile à changer : précisément ce que ce lot cherche à rendre facile.