Je lis Game Coding Complete et l'auteur recommande la communication événementielle entre les objets et les modules du jeu.
Fondamentalement, tous les acteurs du jeu vivants doivent communiquer avec les modules clés (physique, intelligence artificielle, logique de jeu, vue du jeu, etc.) via un système de messagerie d'événements interne. Cela signifie qu'il faut concevoir un gestionnaire d'événements efficace. Un système mal conçu consomme des cycles du processeur, en particulier pour les plates-formes mobiles.
Est-ce une approche éprouvée et recommandée? Comment devrais-je décider de l'utiliser?
architecture
software-engineering
events
Bunkai.Satori
la source
la source
libuv
a récemment émergé comme une bibliothèque d'événements réussie. (C'est dans C. Node.js est son cas d'utilisation le plus célèbre.)Réponses:
Ceci est une extension de mon commentaire à une réponse complète, comme suggéré.
Oui , tout simplement. La communication doit avoir lieu et bien qu'il y ait des situations où "Sommes-nous là?" Une interrogation de type type est requise, faire vérifier par les choses si elles doivent faire autre chose fait perdre du temps. Vous pourriez plutôt les faire réagir aux choses qu'on leur dit de faire. De plus, une voie de communication bien définie entre les objets / systèmes / modules optimise considérablement les configurations en parallèle.
J'ai donné un aperçu de haut niveau d'un système de messagerie d'événements sur le dépassement de capacité . Je l'ai utilisé dès l'école pour des titres de jeux professionnels et des produits non destinés aux jeux, adaptés au cas d'utilisation à chaque fois.
EDIT : Pour répondre à une question de commentaire sur comment savoir quels objets doivent recevoir le message : Les objets eux-mêmes doivent
Request
être informés des événements. VotreEventMessagingSystem
(EMS) aura besoinRegister(int iEventId, IEventMessagingSystem * pOjbect, (EMSCallback)fpMethodToUseForACallback)
d'une correspondance ainsi que d'une correspondanceUnregister
(en créant une entrée unique pour uniEventId
pointeur et un rappel en dehors de l'objet). De cette façon, lorsqu'un objet veut savoir un message, il peut le faireRegister()
avec le système. Lorsqu'il n'a plus besoin de connaître les événements, il peutUnregister()
. Clairement, vous voudriez un pool de ces objets d’enregistrement de rappel et un moyen efficace de les ajouter / supprimer des listes. (J'ai généralement utilisé des tableaux d'auto-classement; une façon élégante de dire qu'ils suivent leurs propres allocations entre une pile de pools d'objets inutilisés et des tableaux qui modifient leur taille en place en cas de besoin).EDIT : Pour un jeu complètement fonctionnel avec une boucle de mise à jour et un système de messagerie d’événement, vous pouvez consulter un de mes anciens projets scolaires . Le message Stack Overflow lié ci-dessus s'y réfère également.
la source
Mon opinion est que vous devriez juste commencer à créer votre jeu et à mettre en œuvre ce avec quoi vous êtes à l'aise. En faisant cela, vous utiliserez MVC à certains endroits, mais pas à d’autres; événements certains endroits, mais pas d'autres; composants certains endroits, mais héritage d'autres; nettoyer la conception de certains endroits, et la conception crue d'autres.
Et ce n'est pas grave, car lorsque vous aurez terminé, vous aurez réellement un jeu. Un jeu est bien plus cool qu'un système de transmission de messages.
la source
Une meilleure question est, quelles sont les alternatives? Dans un système aussi complexe avec des modules bien divisés pour la physique, l'IA, etc., comment pouvez-vous orchestrer ces systèmes?
La transmission de messages semble être la "meilleure" solution à ce problème. Je ne peux pas penser à des alternatives pour le moment. Mais il existe de nombreux exemples de transmission de messages dans la pratique. En fait, les systèmes d'exploitation utilisent la transmission de messages pour plusieurs de leurs fonctions. De Wikipedia :
(La communication entre processus est la communication entre les processus (c'est-à-dire les instances de programmes en cours d'exécution) au sein de l'environnement du système d'exploitation.
Donc, si cela suffit pour un système d'exploitation, il l'est probablement pour un jeu, n'est-ce pas? Il y a également d'autres avantages, mais je laisserai l'article de Wikipedia sur la transmission de message faire l'explication.
J'ai également posé une question sur le dépassement de pile, "Structures de données pour la transmission de messages dans un programme?" , que vous voudrez peut-être lire.
la source
Les messages fonctionnent généralement bien lorsque:
Plus vos besoins correspondent à cette liste, meilleurs seront vos messages. À un niveau très général, ils sont plutôt bons. Ils réussissent bien à ne pas gaspiller les cycles de la CPU pour ne rien faire à la différence des sondages ou d'autres solutions plus globales. Ils sont fantastiques pour découpler des parties d’une base de code, ce qui est toujours utile.
la source
Excellentes réponses jusqu'à présent de James et Ricket, je ne réponds que pour ajouter une note de prudence. La communication événementielle / transmission de messages / événement est certes un outil important dans l'arsenal du développeur, mais elle peut facilement être surutilisée. Quand vous avez un marteau, tout ressemble à un clou, etc.
Vous devez absolument, à 100%, penser au flux de données autour de votre titre et être parfaitement conscient de la manière dont l'information passe d'un sous-système à un autre. Dans certains cas, la transmission du message est clairement la meilleure; dans d'autres, il peut être plus approprié que l'un des sous-systèmes opère sur une liste d'objets partagés, ce qui permet à d'autres sous-systèmes de fonctionner également sur la même liste partagée; et beaucoup d'autres méthodes en plus.
Vous devez à tout moment savoir quels sous-systèmes ont besoin d'accéder à quelles données et à quel moment ils doivent y accéder. Cela affecte votre capacité à paralléliser et à optimiser et vous aide également à éviter les problèmes plus insidieux lorsque différentes parties de votre moteur deviennent trop étroitement liées. Vous devez penser à réduire au minimum la copie inutile de données et à la manière dont la disposition de vos données affecte votre utilisation du cache. Tout cela vous guidera vers la meilleure solution dans chaque cas.
Cela dit, à peu près tous les jeux sur lesquels j'ai travaillé ont un système de notification de message / événement asynchrone solide. Il vous permet de rédiger un code succinct, efficace et maintenable, même face à des besoins de conception complexes et en évolution rapide.
la source
Eh bien, je sais que ce message est assez ancien, mais je ne pouvais pas résister.
J'ai récemment construit un moteur de jeu. Il utilise des bibliothèques 3D pour le rendu et la physique, mais j’ai écrit la partie principale, qui définit et traite les entités et la logique du jeu.
Le moteur suit sûrement une approche traditionnelle. Il existe une boucle principale de mise à jour qui appelle la fonction de mise à jour pour toutes les entités. Les collisions sont directement signalées par rappel sur les entités. Les communications entre entités sont établies à l'aide de pointeurs intelligents échangés entre entités.
Il existe un système de messagerie primitif, qui ne traite qu'un petit groupe d'entités pour alimenter les messages. Il est préférable que ces messages soient traités à la fin d'une interaction de jeu (par exemple, la création ou la destruction d'une entité), car ils peuvent perturber la liste de mises à jour. Ainsi, à la fin de chaque boucle de jeu, une petite liste de messages est consommée.
Malgré le système de messagerie primitif, je dirais que le système est en grande partie "basé sur une boucle de mise à jour".
Bien. Après avoir utilisé ce système, je pense qu’il est très simple, rapide et bien organisé. La logique du jeu est visible et autonome dans les entités, pas dynamique comme un message quewe. Je ne voudrais vraiment pas que les événements soient axés sur les événements car, à mon avis, les systèmes d'événements introduisent une complexité inutile dans la logique du jeu et rendent le code du jeu très difficile à comprendre et à déboguer.
Mais, je pense aussi qu’un système pur "basé sur la boucle de mise à jour" comme le mien a aussi des problèmes.
Par exemple, à certains moments, une entité peut être dans un état "ne rien faire", peut attendre que le joueur s'approche ou quelque chose d'autre. Dans la plupart des cas, l'entité consomme le temps processeur pour rien et il est préférable de la désactiver, et de l'activer lorsqu'un certain événement se produit.
Donc, dans mon prochain moteur de jeu, je vais adopter une approche différente. Les entités s'enregistrent pour les opérations du moteur, telles que la mise à jour, le dessin, la détection de collision, etc. Chacun de ces événements aura des listes d'interfaces d'entités séparées pour les entités réelles.
la source
Oui. C'est un moyen très efficace pour les systèmes de jeu de communiquer les uns avec les autres. Les événements vous aident à découpler de nombreux systèmes et permettent même de compiler des éléments séparément sans connaître l’existence de chacun. Cela signifie que vos classes peuvent être plus facilement prototypées et que les temps de compilation sont plus rapides. Plus important encore, vous vous retrouvez avec une conception de code plat au lieu d'un désordre de dépendance.
Un autre grand avantage des événements est qu'ils sont facilement diffusés sur un réseau ou un autre canal de texte. Vous pouvez les enregistrer pour une lecture ultérieure. Les possibilités sont infinies.
Autre avantage: plusieurs sous-systèmes peuvent écouter le même événement. Par exemple, toutes vos vues distantes (lecteurs) peuvent automatiquement s'abonner à l'événement de création d'entité et générer des entités sur chaque client avec peu de travail de votre part. Imaginez à quel point cela demanderait plus de travail si vous n'utilisiez pas les événements: vous deviez passer des
Update()
appels quelque part ou peut-être appelerview->CreateEntity
de la logique du jeu (où la connaissance de la vue et des informations dont elle a besoin n'appartient pas). Il est difficile de résoudre ce problème sans événements.Avec les événements, vous obtenez une solution élégante et découplée qui prend en charge un nombre infini d’objets de types illimités qui peuvent tout simplement s’abonner à des événements et faire ce qu’il faut quand quelque chose se passe dans votre jeu. C'est pourquoi les événements sont géniaux.
Plus de détails et une implémentation ici .
la source
D'après ce que j'ai vu, il ne semble pas très courant de disposer d'un moteur entièrement basé sur la messagerie. Bien sûr, il existe des sous-systèmes qui se prêtent très bien à un tel système de messagerie, tels que la mise en réseau, l'interface graphique et éventuellement d'autres. En général cependant, il y a quelques problèmes auxquels je peux penser:
Avec l’approche commune des développeurs de jeux consistant à "il doit être aussi efficace que possible", ce système de messagerie n’est donc pas si courant.
Cependant, je conviens que vous devriez simplement aller de l'avant et l'essayer. Un tel système présente certainement de nombreux avantages et la puissance de calcul est aujourd'hui disponible à moindre coût.
la source