27-11-2018, 07:29 PM
Merci à vous pour les réponses.
Dans mon cas, le jeu est purement local, écrit en Lua : la machine a état est pilotée par le jeu, elle est autonome sur l'ordinateur du joueur. La machine a état s'assure que les règles sont respectées. Elle plante dans le cas contraire. Quand elle reçoit l'événement "Tel joueur joue telle carte", elle cherche la carte dans la main du joueur donnée, si elle ne l'est pas, une erreur est envoyées. La gestion d'erreur étant minimaliste, on suit plus facilement la logique du jeu. C'est au client d'envoyer les bons paramètres et de s'assurer que le joueur fait ce qu'il a le droit de faire.
Prenons maintenant le cas d'un jeu multijoueurs. Chez moi c'est un process Elixir qui respecte une interface proche d'une machine à états (le module gen_statem d'Erlang, et en l'occurrence le wrapper Elixir GenStateMachine ) : ça se comporte "naturellement" comme une machine à états qui n'accepte que des messages bien précis, le reste est rejeté. Un message inattendu ait planter la machine, qui est relancée par son superviseur. C'est une politique classique en Erlang/Elixir : le "let it crash", ça permet d'éviter beaucoup de code défensif.
Les clients communiqueront par Websocket (pour le client Web en JS) et UDP (pour le client lourd en Lua). L'interface entre le client et le serveur s'assurera que la machine reçoit les bons événements avec de bons arguments, et s'occupera de transmettre au client de "belles" erreurs s'il y en a, ce qui devrait être rare : le client n'envoie pas de données merdiques, mais qui peut arriver (s'il n'a pas pu se synchroniser, etc.).
Dans mon cas, le jeu est purement local, écrit en Lua : la machine a état est pilotée par le jeu, elle est autonome sur l'ordinateur du joueur. La machine a état s'assure que les règles sont respectées. Elle plante dans le cas contraire. Quand elle reçoit l'événement "Tel joueur joue telle carte", elle cherche la carte dans la main du joueur donnée, si elle ne l'est pas, une erreur est envoyées. La gestion d'erreur étant minimaliste, on suit plus facilement la logique du jeu. C'est au client d'envoyer les bons paramètres et de s'assurer que le joueur fait ce qu'il a le droit de faire.
Prenons maintenant le cas d'un jeu multijoueurs. Chez moi c'est un process Elixir qui respecte une interface proche d'une machine à états (le module gen_statem d'Erlang, et en l'occurrence le wrapper Elixir GenStateMachine ) : ça se comporte "naturellement" comme une machine à états qui n'accepte que des messages bien précis, le reste est rejeté. Un message inattendu ait planter la machine, qui est relancée par son superviseur. C'est une politique classique en Erlang/Elixir : le "let it crash", ça permet d'éviter beaucoup de code défensif.
Les clients communiqueront par Websocket (pour le client Web en JS) et UDP (pour le client lourd en Lua). L'interface entre le client et le serveur s'assurera que la machine reçoit les bons événements avec de bons arguments, et s'occupera de transmettre au client de "belles" erreurs s'il y en a, ce qui devrait être rare : le client n'envoie pas de données merdiques, mais qui peut arriver (s'il n'a pas pu se synchroniser, etc.).