Donify est une application Unreal Engine. Le code est réparti entre trois modules de compilation Unreal : DonifySimulation, DonifyAudio et Donify. Les dossiers de fonctionnalités à l'intérieur de Donify organisent l'intégration dans le jeu ; ils ne constituent pas chacun un module indépendant.
Les flèches signifient « dépend de » :
flowchart LR
Game[Donify : intégration du jeu] --> Audio[DonifyAudio : restitution sonore]
Game --> Simulation[DonifySimulation : dynamique et types]
Audio --> Simulation
| Module | Responsabilité | Dépendances Unreal principales | Ce qu'il ne connaît pas |
|---|---|---|---|
DonifySimulation |
Équations du quadrirotor, contrôleur physique, commandes et types partagés | Core |
Acteurs, scène, interface, audio, ressources /Game |
DonifyAudio |
Boucles, annonces, priorités, transitions et son procédural de repli | Core, CoreUObject, Engine, DonifySimulation |
ADronePawn, HUD, construction de la vallée |
Donify |
Entrées utilisateur, vol dans la scène, collisions, missions, présentation, monde et diagnostics | Les deux modules précédents et les services de rendu/jeu Unreal | — |
DonifySimulation utilise les vecteurs, quaternions et conteneurs de Core. Il est indépendant de la scène Unreal, mais ce n'est pas une bibliothèque C++ autonome compilable sans les en-têtes du moteur. Les dépendances exactes se trouvent dans les fichiers *.Build.cs de chaque module.
Les chemins ci-dessous sont relatifs à Source/.
| Modification | Point d'entrée |
|---|---|
| Interface, commandes et constantes physiques | DonifySimulation/Public/DroneDynamics.h : FDroneDynamics, FDroneCommand |
| Forces, moteurs, batterie et régulation | DonifySimulation/Private/DroneDynamics.cpp |
| Vérifications déterministes du modèle physique | DonifySimulation/Private/DroneDynamicsChecks.cpp |
| État d'assistance et représentation des entrées | DonifySimulation/Public/FlightTypes.h |
| Mixage, annonces, interruption ou repli audio | DonifyAudio/Public/DroneAudioComponent.h et l'implémentation dans DonifyAudio/Private/ |
| Consignes manuelles, décollage, atterrissage, mission, contact avec le monde | Donify/Flight/FlightControl.cpp |
| Actions clavier/manette et menu de sélection | Donify/Flight/ControlInput.cpp, avec Config/DefaultInput.ini |
| Lecture des entrées à afficher | Donify/Flight/InputDisplay.cpp |
| Cycle de vie du drone et assemblage des systèmes | Donify/Flight/DronePawn.h et .cpp |
| Géométrie visible du drone | Donify/Presentation/DroneVisual.cpp |
| Animation visuelle de la pluie autour du drone | Donify/Presentation/DroneWeatherVisual.cpp |
| Cockpit, boutons et télémétrie | Donify/UI/FlightHUD.cpp, DonifyHUD.h, CockpitDrawing.h |
| Mini-carte, zoom, cadrage et trace | Donify/UI/CockpitMap.cpp |
| Manette dessinée et roue MANUEL/AUTO | Donify/UI/ControllerHUD.cpp, ModeMenuHUD.cpp |
| Assemblage de la vallée, bâtiments, rues, véhicules et plantations | Donify/World/ValleyWorld.h, ValleyWorld.cpp, World*.cpp, Reference*.cpp |
| Scénarios de vol, commandes, entrées et captures reproductibles | Donify/Diagnostics/FlightChecks.cpp, ControlChecks.cpp, InputChecks.cpp, FlightSessionDiagnostics.h et .cpp |
| Démonstration filmée, commandes séquencées et légendes | Donify/Diagnostics/GameplayDemo.h et .cpp, Scripts/record_gameplay.py à la racine |
| Choix du pawn, du HUD et création du monde | Donify/Game/DonifyGameMode.h et .cpp |
DonifyModule.cpp enregistre le module principal. Donify.h reste un en-tête de compatibilité qui regroupe les classes du jeu : le code de production inclut directement l'en-tête dont il a besoin, pour ne pas réintroduire une dépendance globale. UI/MissionHUD.cpp conserve l'ancien dessin de carte ; le cockpit courant utilise CockpitMap.cpp.
Les classes de jeu gardent leurs identifiants /Script/Donify et les assets conservent leurs chemins /Game. La réorganisation des sources ne demande pas de recréer les cartes, matériaux ou sons importés.
UDroneAudioComponent reçoit un instantané FDonifyAudioState en lecture seule. Le pawn construit cet instantané à partir du vol courant. Le composant dispose ainsi des mesures et des états utiles au son sans lire directement les propriétés du pawn.
Son interface publique expose InitializeAudio(Attachment, State), UpdateAudio(Dt, State) et ResetAudioFeedback(State) pour l'intégration, ainsi que RunAudioChecks(State) pour les diagnostics. Il conserve ses propres composants, gains et annonces en attente ; EndPlay arrête ses sons. L'instantané contient notamment les quatre RPM, les vitesses du drone et du vent en m/s, la batterie, la météo et l'état d'assistance.
Le sens des échanges est le suivant :
- Les entrées et assistances produisent les commandes du vol.
- La dynamique et les collisions déterminent l'état physique réel.
- Le pawn transmet au composant audio les mesures et états correspondants.
- L'audio choisit ses sons et leurs paramètres ; il ne modifie ni la propulsion, ni la mission, ni la position du drone.
Un nouveau son lié au vol s'ajoute donc dans le module audio. Si une nouvelle mesure lui est nécessaire, ajouter explicitement cette donnée au contrat, puis la renseigner côté intégration. Ne pas inclure DronePawn.h dans le module audio pour atteindre un champ manquant. Le régime sonore dépend des RPM simulés, pas de la position graphique d'une gâchette.
Les ressources sonores restent dans /Game/Audio. Leur provenance, les règles des annonces et les outils de régénération sont décrits dans AUDIO.md. Les scripts de production de ressources ne s'exécutent pas pendant le vol.
La dynamique utilise les mètres, secondes, kilogrammes, newtons et radians. Les coordonnées d'acteurs, les collisions Unreal, la route et la trace du vol utilisent les centimètres. Le pawn convertit les positions entre ces deux représentations : multiplier par 100 vers la scène, par 0.01 vers la dynamique. ADronePawn::Velocity est une valeur de compatibilité en cm/s ; Dynamics.Velocity est en m/s. Les angles passés à FRotator sont en degrés.
Les cibles manuelles sont exprimées dans le repère du monde : ManualTargetVelocity en m/s, ManualTargetAltitude en mètres. La hauteur affichée au-dessus d'un toit ou du sol provient d'une mesure de la scène ; elle n'est pas interchangeable avec l'altitude absolue de la dynamique. Les équations, conventions d'axes et hypothèses se trouvent dans FlightPhysics.md.
La simulation avance à pas fixe de 1/240 s. Le rendu et l'audio suivent les mises à jour du jeu. Modifier une fréquence de présentation ne doit pas changer les unités ou le pas d'intégration. La télémétrie décrit le vol, tandis que FDonifyInputDisplay décrit uniquement les entrées réellement reçues de l'utilisateur.
FDonifySessionDiagnostics, défini dans FlightSessionDiagnostics.h, regroupe la préparation des vols de test, les captures, la temporisation et le relevé de performances. Son état appartient à une instance de pawn. Ces préparations s'activent avec -DonifyCheck, -DonifyCapture ou -DonifyAudioProbe ; le lancement interactif normal conserve un départ au sol, moteurs arrêtés.
Les contrôles physiques sont implémentés dans DonifySimulation/Private/DroneDynamicsChecks.cpp. Les scénarios d'intégration de Diagnostics/ accèdent encore au pawn et à la scène : leur regroupement ne les rend pas indépendants d'Unreal. Les scénarios de vol, de commandes et d'affichage des entrées restent des méthodes du pawn ; le pilote de session de diagnostic dispose d'un accès friend explicite pour préparer ses fixtures.
python3 Scripts/check_architecture.py
./Scripts/build.sh
./Scripts/check.shLe premier contrôle vérifie les frontières de dépendances et la cohérence de la déclaration des modules. La compilation vérifie les interfaces C++ et Unreal. Le dernier lance les scénarios dans le jeu et vérifie leurs marqueurs dans Saved/Logs/Validation.log. Un succès du contrôle d'architecture ne prouve pas le comportement du vol ni la qualité du rendu. Les résultats d'exécution sont consignés séparément dans VALIDATION.md.
Le HUD lit encore directement les mesures du pawn et appelle ses actions. Le pawn porte toujours les entrées, les consignes, les assistances, les collisions et la coordination du monde. Plusieurs fichiers de contrôle implémentent la même classe. Il reste donc des changements qui nécessitent de comprendre cette classe, même après l'extraction de l'audio et du noyau physique.
Une prochaine étape utile serait un contrat de télémétrie pour le HUD, suivi d'un contrôleur de missions recevant des observations de la scène et produisant des commandes. Chaque extraction doit partir d'une responsabilité et de données explicites, conserver les scénarios existants et éviter les dépendances circulaires. Le monde et l'interface pourront devenir d'autres modules Unreal lorsqu'une frontière stable le justifiera.
Pour le parcours de contribution : CONTRIBUTING.md. La préparation à une publication open source reste un sujet plus large, suivi dans OPEN_SOURCE_AUDIT.md.