Globalement, le cahier des charges proposé à été respecté.
Le moteur 3D possède toutes les primitives graphiques nécessaires à l'élaboration d'un jeu, ou d'un éditeur/visualiseur d'objets 3D, etc... En particulier, la gestion des caméras, des lumières, ou encore des objets 3D ont été fourni.
Le binding SDL a été, comme prévu, limité aux seules fonctions utiles au jeu, ce qui offre déjà d'énormes possibilités. Il est ainsi possible au final, d'ouvrir des fenêtres, de contrôler les actions de l'utilisateur au clavier, à la souris, et d'avoir un support OpenGL très simplement.
Etant donnée que le jeu implémenté fut un jeu de billard et non un jeu de combat, il n'a pas été nécessaire d'implémenter le moteur de squelette, ni le moteur d'animation. En effet, l'implémentation de tels moteurs aurait fait dévier le projet de son objectif initial, à savoir la programmation réactive, vers d'autre problèmes informatiques fortement plus compliqué.
Si l'on se place du point de vue du développeur évoluant dans l'environnement de programmation Bigloo, ce projet aura finalement permit de rajouter la couche multimédia attendue au compilateur.
Le fait d'être passé de petits tests en Java avec le moteur Junior, a une implémentation Scheme testée en "grandeur nature", c'est à dire a l'échelle d'un vrai petit jeu, aura finalement vraiment servi a quelque chose. Preuve en est: l'adaptation de la sémantique des instructions funcall& et apply&. Il faut souligner la cohabitation et le dialogue qui a put se développer durant le développement de ce projet avec le créateur de Senior. L'échange aura sûrement été fructueux pour tout le monde.
Il y a dans l'implémentation du moteur réactif mis a disposition des points forts qui ont fait l'unanimité au cours du développement du jeu:
L'apprentissage du langage réactif est assez rapide:
Ce fut une agréable surprise de s'en apercevoir. La principale raison de cette facilité d'apprentissage réside dans le fait que le nombre d'instructions mises à disposition par le langage est suffisamment restreint pour ne pas dérouter lors de la première approche. Toutefois, cela ne signifie pas qu'il est impossible de modéliser des comportements trop compliqués. Au contraire, la force du langage réside aussi dans le fait que le peu d'instructions disponible suffit a échafauder des constructions très complexes, sans se perdre dans la masse de code, généralement nécessaire dans les autres langages.
La couche Scheme de Senior 2.0 apporte réellement un plus:
Le port du moteur réactif en Scheme a été suffisamment bien conçu pour tirer partie de toutes facilités syntaxiques offertes par le langage Scheme lui-même. Senior 2.0 n'est donc pas qu'une bête copie de Junior pour Scheme, mais une réelle avancée dans la manière d'utiliser la programmation réactive. La hiérarchisation du code en lambda est incroyablement pratique et permet de conserver tout au long d'un projet une lisibilité de code, que même Junior est loin d'égaler. Les exemples developpés dans l'introduction du rapport prouvent bien qu'il est vraiment bien plus simple d'écrire du code en Senior qu'en Junior.
Les ressources de la machine restent disponibles:
Bien que permettant des constructions très complexes, l'implémentation de Senior repose sur des macro-expansions à l'étape de la compilation. Ainsi tout le surcoût qu'aurait pu engendrer une telle machine reste quasiment masqué a l'exécution. Seul le postage d'événement et l'ajout dynamique de comportements peuvent amener à un surcoût assez léger pour se faire oublier.
Gestion de la concurrence simplissime:
Il s'est avéré après avoir terminé le jeu qu'il était difficile de trouver un langage capable de gérer de manière aussi simple et aussi précise l'évolution de diverses tâches concurrentes. Bien sûr Senior n'utilise pas de thread pour simuler sa concurrence, mais les possibilités offertes par ce moteur et qui ont put être mis en oeuvre avec succès ont démontré que la simulation d'exécution de tâches concurrentes pouvait être réalisée sans aucun équivalent par rapport aux langages communs comme C, Java, etc...
Postage d'événements instantané:
Le concept de diffusion instantanée d'événements est un des points forts de la programmation réactive. Ce modèle de communication amène souvent à cacher des boucles dans des algorithmes comme pour notre projet avec le cas des collisions. Le résultat est non seulement plus clair au niveau du code source, mais surtout la garantie que tout événement sera traité au moment voulu permet de mettre en jeu des techniques de programmation reposant sur des base assez solides pour concevoir des algorithmes très sophistiqués.
La sémantique de certaines instructions est excellente:
Notamment les instructions comme scan&, qui ne finissent que lorsqu'il ne peut plus y avoir d'événement déclenché. Cela évite de faire une boucle et d'attendre des événements de manière habituelle. D'autres instructions comme funcall& permettent de hiérarchiser les comportements de manière extrêmement commode: ainsi il est possible lors des phases de cerner directement le bout de code recherché. Enfin l'instruction par&, à la base de l'exécution des instructions en parallèle apporte une souplesse encore une fois au niveau de la création de comportements mais surtout de tests: on peut en commentant seulement une ligne de code "débrancher" un comportement particulier (ex: les frottements d'une boule sur le billard), ou en rajouter un sans toucher plus d'une ligne de code!
Evidemment, comme toute chose, l'implémentation de Senior a ses points noirs:
La sémantique de certaines instructions manque de souplesse:
L'instruction scan& a vraiment un fonctionnement commode, mais toutefois, sa sémantique impose qu'après avoir détecté un événement, le code à exécuter soit du code Scheme, et non du code réactif. C'est un peu perturbant. Une instruction équivalente à scan& avec possibilité d'exécuter des instructions réactives aurait été la bienvenue... De même, il est dommage que toutes les fonctions d'attente d'événement ne puissent pas toutes gérer les événements valués.
Manque d'orthogonalité dans la communication avec la machine:
Si l'on peut générer des événement depuis l'extérieur et les diffuser dans la machine, il est en revanche impossible de tester depuis l'extérieur de la machine si un événement à eut lieu à l'intérieur de cette dernière. Le problème n'est pas crucial, mais il faut des fois chercher une solution détournée pour arriver à ses fins. C'est un peu dommage...
En tout, l'implémentation du jeu de billard aura nécessité moins de 700 Lignes de code, sans chercher particulièrement à réduire au maximum le nombre de lignes utiles. Bien entendu, le nombre de lignes de la bibliothèque que constitue le moteur 3D n'est pas pris en compte, mais ce n'est pas l'important: ce qu'il faut réaliser c'est qu'un tel jeu de billard en 3D en C avec OpenGL (par exemple) aurait pris bien plus de 2000 ou 3000 lignes!
Il est assez difficile d'estimer le nombre de lignes gagnées grâce au moteur et à l'utilisation du moteur réactif Senior 2.0, mais il est clair que sur les 700 lignes de sources, on peut compter qu'il n'y a pas plus de 200 lignes de code réactif effectif, et tout cela pour simuler grand nombre de comportements puisque la totalité du jeu est gérée de manière réactive.
Il est manifeste que la programmation réactive du billard a simplifié l'implémentation du jeu bien au delà des prévisions de début de projet. Et il est évident que le bénéfice induit par cette technique de programmation serait bien plus grand pour des jeux de plus grosse envergure:
un jeu de foot, où l'on doit gérer à la fois le déplacement et les réactions de 22 joueurs différents,
ou encore un jeu de stratégie ou de plateau, où des centaines d'entités doivent évoluer en même temps et où le code traditionnel deviendrait trop vite un cauchemar !
En résumé, on peut considérer que la technique de Programmation Réactive est validée, et ce avec beaucoup d'enthousiasme, avec notamment un grand bravo à Julien Demaria pour son implémentation en Scheme de la machine réative: Senior 2.0.