IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement 2D, 3D et Jeux Discussion :

Design / Conception d'un "Game Engine"


Sujet :

Développement 2D, 3D et Jeux

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Par défaut Design / Conception d'un "Game Engine"
    Design / Conception d'un "Game Engine"

    Bonjour à tous, je suis ici car j’ai en tête depuis bien longtemps de faire un moteur de jeu 2D dans le but de pouvoir créer un RPG du même genre que secret of mana (avec un mode multi à 3 joueurs).

    J’ai déjà tenté l’expérience et ca c’est soldé par un échec dû à un design mal pensé qui s’est révélé très difficile à finir. J’ai donc abandonné et repris récemment sur de nouvelles bases en m’inspirant d’un article intéressant trouvé sur gamedev.net . Mais là encore je me rends compte que je fonce droit dans le mur (la série d’article sur laquelle je comptais me baser n’est pas terminée et ne le sera pas, il manque donc de grande étapes conceptuelle que je ne suis pas parvenu à comblé).

    Avant de continuer à coder tout et n’importe quoi j’ai décidé de m’arrêter et de réfléchir un peu à ce que je voulais obtenir. Dans un premier temps, je me suis fixer l’idée de faire un « pong » proprement, ce qui me permettra de poser une très grande partie des fonctionnalités de mon game engine . Ensuite je tenterai de faire une version multi-joueurs (2) de ce même pong. Et enfin je me lancerai sans doute dans la réalisation de mon projet initial.

    J’ai commencé à sérieusement réfléchir à une architecture de classes me permettant d’avoir un design propre, flexible et surtout viable à terme. J’aimerai beaucoup avoir votre avis dessus, il n’est certainement pas parfait et peut-être même pas viable. Je suis ouvert à toute critique/remarque.

    Après avoir tenté de modéliser tout ca, j’en suis venu à considérer le modèle suivant. (Je précise que je ne cherche pas à avoir un code 100% OO, ni même exploitant à fond les possibilités du c++, mais juste un code qui fonctionne en étant maintenable et simple).

    Le modèle du « tout-singleton » (non, non ne partez pas !). J’ai tout d’abord voulu séparer la programmation en divers module, et je me suis vite heurté à un problème récurent : comment ces modules vont-ils communiquer entre eux ? La plupart ont besoin des données du jeu pour fonctionner, données que l’ont doit pouvoir rassembler en une classe de base « Entity » ( un menu, un décor, une carte, un objet, une interface … pouvant être considérer comme une Entity distinctes). Ne trouvant pas de moyen élégant de passer les données qu’il faut à chaque module quand il en a besoin, j’ai décidé de rendre ces données disponibles pour tous !

    Premier point donc, un « EntityManager » en singleton (oui, je sais singleton dans ce cas équivaut juste a une grosse liste d’Entity déclarée en static …).

    Ensuite, il nous faut un endroit où stocker des ressources bruts (image - texture, son - musique, fonts) [Si vous voyez d’autres types de ressources bruts, pouvant être utilisées par plusieurs Entity signalez le moi, car je suis certain que j’en oublie !]. Ca nous amène donc à un « RessourceManager » dont le but sera de charger les type de données énoncé précédemment et de renvoyez un pointeur a l’Entity demandant la ressource. On s’assure ainsi que les ressources ne sont pas chargé en plusieurs exemplaires.
    Je n’ai pas pour le moment vraiment réfléchis à la durée de vie de ses ressources, c’est un point sur lequel il va falloir que je me penche, mais je pars du principe que ca peux attendre un peu et que mon design n’en sera pas trop pénaliser (arrêter moi si j’ai tord).

    Pour le moment j’ai donc un endroit où stocker des Entity , qui peuvent être composés de ressources bruts et d’autres Entity sans trop de problème.

    Petite parenthèse sur les « a côtés » : je dispose déjà d’un système de log qui me convient et d’un profiler externe si besoin. Enfin mon application est emballée dans deux classes. La première ayant juste pour but de garder un « main » clair et de charger des données nécessaire au bon lancement du moteur ( taille de la fenêtre, plein écran ou pas ….) et de lancer le noyau de jeu (Kernel).
    Ce Kernel va initialiser certains Manager (Ressources, Entity par exemple) et contenir la boucle de jeu.

    Avant d’attaquer cette boucle de jeu, des plus classiques, il me reste encore une ou deux classes à présenter.
    L’ « InputManager », dont le rôle sera de récupérer l’état des touches clavier et de la souris à chaque frame. Etant un singleton, tout le monde y aura accès, notamment les Entity , c’est là que réside l’un des mécanismes que je compte utiliser au mieux, mais que j’ai bien du mal à mettre en place (surtout dans les autres parties de mon moteur) : les « Events ». A sa création en particulier ou durant sa vie, chaque Entity pourra enregistrer auprès de l’ InputManager des Events . Un Event sera sous la forme d’une petite classe/structure, contenant : un pointeur vers l’Entity émettrice, le nom de l’Event et une/plusieurs condition de déclenchement.
    Ainsi en plus de récupérer l’état des Inputs (touche appuyé cette frame, touche appuyé, touche relâchée cette frame, touche relâchée, souris en X et en Y), l’ InputManager testera chacun des Event qu’on lui aura enregistrer et si d’eux voit ses conditions remplies il enverra à l’Entity dont le pointeur est contenu dans l’Event un message du nom de l’Event en question.

    On a donc maintenant un moyen de traquer les inputs à notre convenance et de les envoyer à qui de droit (le seul cas pouvant poser problème est celui des menus de jeu qui peuvent se superposer au jeu actuel et donc il faut veillez a ce que les inputs leur soit attribué en priorité, je n’ai pas encore réfléchis au problème, si vous avez des idées, n’hésitez pas).

    A cela on ajoute un SoundManager, singleton, qui va juste permettre des petites choses comme : jouer un son, pauser un son, arrêter un son, mettre en file d’attente un son, jouer un son en dégradé sonore, changer le volume sonore ect…

    On peut enfin revenir à notre boucle de jeu (contenu dans le Kernel) qui sera faites ainsi :

    - Appel à l’InputManager pour qu’il récupère les inputs, les stocke et envoie les Events dont les conditions sont remplies.
    - Appel à une classe Timer, qui va calculer le temps écoulé, le temps total et 2-3 trucs dans se style.
    -Appel d’une fonction Update () sur toute les Entity (accessible grâce au singleton : EntityManager), cette fonction va d’abord procéder au traitement de tout les Event venant de l’InputManager, puis va procéder a son update normal (IA, physique, animation etc. …)
    - Appel à une classe Network, dont le comportement reste à définir, mais qui devra assez tôt dans la conception être pris en compte ! (surement dés le premier pong terminer, vous pensez que ce n’est pas trop tard ?)
    - Appel à une tache : Render() qui va passer en revue chaque Entity et l’afficher à ‘écran si elle est visible.
    -> on boucle depuis le début !


    Voila l’idée principale ! A vous de me dire ce que vous en pensez 

    A cela, il reste quelques choses majeures que je n’ai pas résolu :

    1) La communication entre Entity, j’aime bien l’idée de l’envoie de message, j’aimerai garder cela mais je ne sais pas trop comment.
    2) Comment définir les actions à prendre quand on recoit un message, je me vois mal tout codé en dur, j’aimerai pouvoir définir ca dans des fichiers simplement (xml ou autre) vous avez des idées ? Un langage de script comme LUA ferait-il mon affaire ? (je demande car je n’ai jamais utilisé)
    3) Toute la partie network …

    Dans le cas du système de messages Input->Entity et Entity<->Entity, il est sans doute préférable de traiter un message dés qu’il est reçu, plutôt que périodiquement à chaque frame, non ?

    Merci de m’avoir lu, désolé de la longueur du pavé, j’attends impatiemment vos remarques / conseils / critiques / encouragement ou autre ^^
    Par ailleurs si connaissez un livre (fr / en) traitant de se sujet de façons vraiment intéressante, l’architecture même d’un moteur de jeu, abordable d’un point de vue technique (si possible basé sur du C++) je suis preneur !

    PS : Ce message sera posté sur au moins deux forums différents, j’essaierai de faire le bilan des remarques d’un post sur l’autre !

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Salut

    Tout d'abord j'admire ta persévérance, depuis le temps que je te vois poster ici des pavés de questions existencielles (ce qui est une bonne chose) concernant la conception d'un moteur de jeu.

    Personnellement je n'ai rien à redire concernant la conception que tu as présentée, c'est aussi ce vers quoi j'ai convergé depuis que j'écris des moteurs.

    Je n’ai pas pour le moment vraiment réfléchis à la durée de vie de ses ressources, c’est un point sur lequel il va falloir que je me penche, mais je pars du principe que ca peux attendre un peu et que mon design n’en sera pas trop pénaliser (arrêter moi si j’ai tord).
    Tout pareil. L'idée que j'ai pour plus tard, c'est d'abstraire la stratégie de gestion des ressources. Ainsi il sera facile de coder plusieurs stratégies et d'utiliser celle que l'on veut à la volée.
    Genre ResourceManager::GetInstance().SetStrategy<Texture>(new StrategyMachinChouette);

    le seul cas pouvant poser problème est celui des menus de jeu qui peuvent se superposer au jeu actuel et donc il faut veillez a ce que les inputs leur soit attribué en priorité, je n’ai pas encore réfléchis au problème, si vous avez des idées, n’hésitez pas
    Peu importe la manière dont tu implémenteras ça (système de GUI, écrans de jeu, ...), tu verras que de toute façon tu te retrouveras toujours à coder un système de priorité et de focus. Donc ne t'embête pas avec ça pour le moment, de toute façon tu y passeras plus tard.

    1) La communication entre Entity, j’aime bien l’idée de l’envoie de message, j’aimerai garder cela mais je ne sais pas trop comment.
    De quelle genre de communication parles-tu ? Le réseau ? Ou bien un truc beaucoup plus générique que tu n'as pas encore bien défini ?

    2) Comment définir les actions à prendre quand on recoit un message, je me vois mal tout codé en dur, j’aimerai pouvoir définir ca dans des fichiers simplement (xml ou autre) vous avez des idées ? Un langage de script comme LUA ferait-il mon affaire ? (je demande car je n’ai jamais utilisé)
    XML (pour le descriptif) + Lua (ou autre langage de script -- pour les actions) c'est très bien. C'est ce que j'utilise personnellement et professionnellement.

    Bonne chance

  3. #3
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Par défaut
    Tout d'abord j'admire ta persévérance, depuis le temps que je te vois poster ici des pavés de questions existencielles (ce qui est une bonne chose) concernant la conception d'un moteur de jeu.
    Ca fait plaisir ! Merci pour les réponses.


    Tout pareil. L'idée que j'ai pour plus tard, c'est d'abstraire la stratégie de gestion des ressources. Ainsi il sera facile de coder plusieurs stratégies et d'utiliser celle que l'on veut à la volée.
    Genre ResourceManager::GetInstance().SetStrategy<Texture>(new StrategyMachinChouette);
    J'aime bien la notion de "stratégie" car en fin de compte c'est vraiment de ca qu'il s'agit !

    De quelle genre de communication parles-tu ? Le réseau ? Ou bien un truc beaucoup plus générique que tu n'as pas encore bien défini ?
    Je parle de la communication du style :
    Entity1 indique a Entity 2 qu'elle vient d'entrer en collision avec elle.
    Entity1 recoit un event "Lancer Sortilège en (x,y), il faut que l'entity en (x,y) recoive un event "Sortilège ennemie" contenant toute les information necessaires.

    En fait, le passage de message d'une entitées à l'autre ne devrai pas poser de problème, on en revient juste au traitement des messages effetifs ( il faut vraiment que je mette le nez dans LUA...D'ailleurs j'y vais de ce pas !!)

  4. #4
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    -> on boucle depuis le début !
    Vu la puissance actuelle des machines (cpu/gpu), je pense qu'on pourrait remplacer la traditionnelle main-loop par des objects actifs (thread) ayant chacun leur propre loop (avec des frequences differentes).

    En effet, il est prefferable d'avoir le Render() qui tourne a une cadence elevée (+75 fps) et les network,timer,... a une frequence plus basse.

    Pour la communication, un systeme avec des queues de messages me semble efffectivement bien vu.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Vu la puissance actuelle des machines (cpu/gpu), je pense qu'on pourrait remplacer la traditionnelle main-loop par des objects actifs (thread) ayant chacun leur propre loop (avec des frequences differentes).

    En effet, il est prefferable d'avoir le Render() qui tourne a une cadence elevée (+75 fps) et les network,timer,... a une frequence plus basse.
    Oui, mais pas au niveau le plus haut. C'est plutôt chaque module qui va faire sa sauce et se mettre à jour à sa propre fréquence si besoin. Mais du point de vue du moteur, tout ça doit rester transparent (cf. les moteurs de physique).

  6. #6
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Oui, mais pas au niveau le plus haut. (...) Mais du point de vue du moteur, tout ça doit rester transparent
    pas compris...

    Autant je comprend la necessite de faire un Entity.update() avant de faire un Render(Entity), autant je comprend pas pourquoi il faut avoir fait TOUS les update() avant de faire TOUS les Render(). Plus il y aura d'entity, plus la cadence va chuter. Or il y a de grandes chances que certaines Entity soient plus changeantes que d'autre... par exemple la balle du pong par rapport aux elements du decor, a l'affichage des scores, ...


    Donc je verrai plus des objets actifs avec des envois/lectures de messages

    - L'InputManager qui emplile des messages dans la GlobalMessageQueue

    - Le MessageDispatcher qui dépile les messages depuis la GlobalMessageQueue et qui les empile dans les Entity.MessageQueue que le message interesse (abonnement)

    - Les EntityManager qui appellent les Entity.update(). Je dis "LES" EntityManager, car ca serait bien d'en avoir plusieurs (cf. plus bas)

    - Le Render qui affiche les Entity lorsqu'un EntityManager a fini de mettre a jour sa liste d'Entity.

    Pourquoi plusieurs EntityManager ? Comme ca, on peut creer un EntityManager avec une priorité elevé qui aura terminé son cycle de mise a jour plus vite ==> Le Render affichera ces entités la plus souvent que les autres. Par exemple dans Pong le BalleManager aurait une priorité superieure au RaquetteManager, lui meme superieure au DecorManager, lui meme superieure au ScoreManager, ...
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Pourquoi plusieurs EntityManager ? Comme ca, on peut creer un EntityManager avec une priorité elevé qui aura terminé son cycle de mise a jour plus vite ==> Le Render affichera ces entités la plus souvent que les autres. Par exemple dans Pong le BalleManager aurait une priorité superieure au RaquetteManager, lui meme superieure au DecorManager, lui meme superieure au ScoreManager, ...
    Ce n'est pas une bonne idée de ne pas tout afficher à la même fréquence. D'ailleurs je ne sais pas comment tu veux faire, il faut bien que tu effaces ton écran à chaque tour de boucle, et donc que tu réaffiches tout.

    Par contre, avoir des fréquences différentes pour chaque module (graphique, physique, réseau, ...) est une bonne idée -- je croyais d'ailleurs que c'était de ça que tu parlais, mais comme je le disais ça doit rester encapsulé dans le module, et non être géré par le moteur.

  8. #8
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut
    Je suis également plutôt intéressé par la conception d'un moteur, car je dois avouer que je suis très très mauvais dans l'organisation, faire en sorte que tout soit mis ensemble intelligemment. Je cherchais souvent des livres sur amazon.com, et j'avais trouvé le fameux : "3D Game Engine Design, Second Edition", mais là je viens de voir qu'un tout nouveau livre (sorti le 8 décembre 2006), vient de sortir, et il m'a l'air extremement intéressant, bien qu'un peu court (560 pages) : http://www.amazon.com/Ultimate-Game-...e=UTF8&s=books

    Il traite de la création d'un moteur 3D de A à Z, avec la création de gestionnaires de mémoire, la physique, le son, l'input, l'affichage de graphismes, le scripting... Il y a deux extraits ici : http://www.charlesriver.com/books/Bo...oductID=149743 et ça m'a l'air d'être vraiment ce que je cherchai.

    Je pense que je me le prendrai en avril prochain pour mon anniv', mais si quelqu'un est intéressé pour le prendre et me dire ce qu'il vaut .

Discussions similaires

  1. [Livre] Ultimate 3D Game Engine Design & Architecture
    Par ram-0000 dans le forum Livres
    Réponses: 0
    Dernier message: 03/06/2014, 22h33
  2. [Livre] Ultimate 3D Game Engine Design & Architecture
    Par nicolas66 dans le forum Développement 2D, 3D et Jeux
    Réponses: 68
    Dernier message: 15/02/2007, 17h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo