Erewhon-Game
Erewhon-Game copied to clipboard
[FR] [Discussion] Points d'entrée des scripts
Cette issue est un topic de discussion, elle ne vise pas à régler un problème existant mais à discuter d'une direction à prendre pour l'évolution du jeu.
Actuellement, il y a deux points d'entrée à un script Lua, respectivement Spaceship:OnTick(elapsedTime)
et Spaceship:OnUpdateInput(elapsedTime)
.
Le second étant peut-être voué à disparaître (voir #6 ), je ne vais considérer que OnTick
.
Du coup actuellement un script ressemble à ceci:
function Spaceship:OnTick(elapsedTime)
if (self.Radar:IsScanReady()) then
self:PerformScan()
end
end
Ce qui vérifie à chaque tick (dix fois par seconde) si le scan est prêt.
Une autre approche qui avait été évoquée serait de se baser sur les événements, remplaçant le code du haut par ce genre de code:
function Spaceship:OnInit()
self:PerformScan()
end
function Spaceship:OnRadarScanReady()
self:PerformScan()
end
Supprimant ainsi la notion de tick (qu'on pourrait néanmoins conserver à un rate largement inférieur, toutes les (demi-)secondes par exemple).
Cela pourrait également être plus facile à programmer.
Des avis ?
Totalement d'accord avec ce système. Faut que ton jeu soit le plus accessible possible pour éviter de faire fuir les débutants en programmation, peu de joueur avant de jouer vont s'amuser à apprendre le Lua, ils vont uniquement s'y intéresser si le jeu leur plaît et pour ça le mieux c'est de simplifier au maximum.
Dans le cas du callback (le 2ème), comment fait-on si on ne veut pas relancer un scan directement (parce que ça bouffe de l'énergie par exemple) ?
@REMqb Je pense qu'il faut pouvoir supporter un système de timer avec cette approche, avec une API permettant de dire "appelle cette fonction dans X secondes". Je ne suis pas très fan de cette approche, étant donné qu'elle revient à presque retrouver un système de ticks, en plus organisé peut-être.
La meilleure option doit se trouver entre les deux.
L'approche événementielle est beaucoup plus simple et (imho) adaptée ici. Plutôt que de devoir faire 36000 conditions pour savoir où il en est, le joueur a je pense envie de gérer l'aspect "réaction" de la logique assez rapidement (je vois un ennemi, deux ou trois conditions et je tire !).
Rien n'empêche que certains événements ne soient très réguliers, mais au moins toute la logique n'est pas exécutée à chaque fois, ça prend moins de ressources non ?
L'idéal serait, je pense, d'avoir un set d'évènements prédéfinis, et de permettre à l'utilisateur d'en défiinir par lui-même. Ou aussi, en fonction de l'équipement du vaisseau, celui-ci vient avec son set d'évènements propres
@DragonJoker oui, des événements personnalisés c'est nécessaire! (j'entends des événements custom qu'on appelle soit-même, et non pas des événements que l'on fait appeler dans le code du jeu en hard)
Finalement on rejoint l'architecture des plugins Bukkit avec des EventListeners.
Tu fais un évènementiel de base, et tu laisses la possibilité d'enregistrer des évènements custom. Lors de l'enregistrement d'un évènement custom, tu fais enregistrer 2 fonctions : la fonction qui vérifie les conditions de déclenchement de l'évènement, et la fonction de traitement l'évènement.
+1 pour l'approche événementiel. Pour la question des timer, on pourrait imaginer pouvoir lier un timer à un évent custom et que le timer appelle l'event tous les X ticks.
Je ne vois pas comment ça pourrait être mis en oeuvre... Dans chaque fonction logique tu veux check si par hasard un user aurait pas demandé de se faire notifier ?
Plutôt limiter a une API d'événements donnés par le jeu. Les événements sont alors dispatché vers les listeners enregistrés.
Mais je plussoies les événements customs dans le sens où des joueurs pourraient construire des librairies d'événements custom, basées sur les événements dans le jeu, mais qui dispatch des classes d'événement custom
Je propose :
- OnFrame (à chaque frame du client)
- OnEvent (à chaque événement)
Avec petit subtilité, le script s'inscrit à des événements, ils ne reçois que ceux qu'il demande.
J'ai du mal aussi à imaginer le côté "enregistrement des événements", je pense que c'est plus simple de considérer qu'un événement équivaut à une fonction (et que donc si la fonction existe, elle est appelée lors du déclenchement de l'événement).
Après rien n'empêche derrière de se faire une petite lib où chaque fonction d'événement déclenche plusieurs autres fonctions derrière. Il ne faudrait pas mâcher tout le boulot non plus ;)
J'ai plus de mal à imaginer un système d'événement custom par contre, c'est quoi un événement "custom" ? Il se déclenche quand ?
@hardcpp
Le script étant côté serveur, il n'y a pas de notion de frame ni même de client.
Je pense qu'une fonction OnEvent complexifie le code (on se retrouve à devoir gérer tous les événements au sein d'une même fonction).
Donc je suis assez d'accord pour partir sur une approche événementielle, mais quelle tête est-ce que ça doit avoir ? Comment je fais si je veux faire une action toutes les trois secondes ? Comment je fais si je veux faire une action très souvent ? Quel impact cela a-t-il sur le jeu ?
Je commence à imaginer un système de ticks qui soit réglable et qui, en fonction du temps passé dans le script, se mette à pomper plus d'énergie (donnant ainsi la possibilité d'entrer en mode "combat" et de ticker beaucoup plus souvent en cas de danger, et de passer à un mode de veille où on tick moins souvent).
En revanche, ça m'embête un peu d'avoir à la fois des ticks et une notion de timer, est-ce que ce ne serait pas possible de les réunir ? De pouvoir créer à la volée un timer périodique (qu'on demande d'appeler toutes les 0.1s par exemple) qu'on pourra détruire à la volée, remplaçant le système des ticks ?
On peut aussi imaginer que chaque module processeur s'accompagne d'une fréquence de tick maximale, changeant donc la résolution possible d'un timer.
Le système d'event avec juste du "onEvent" donnerait aussi plus de souplesse sur la façon de faire les actions. Si on reçoit beaucoup d'événements on peut filtrer d'abord les plus intéressant pour les traiter puis essayer de traiter les autres si on a encore du temps, ou bien tous les traiter. Ca pourrait peut être donner un peu plus de profondeur au jeu.