10-02-2019, 01:32 PM
Tu te retrouves, au moment précis de l'attaque, sans aucun joueur connecté.
On s'en balec, le web n'est pas conçu initialement pour faire du temps réel, y'a pas de notion de "sans aucun joueur connecté" (ou dit autrement, il n'y a jamais de joueur "connecté": ce sont des échanges ponctuels serveur/client, pas des flux continus).
Quand le joueur D va se pointer, les attaques/productions/j'sais pas quoi des autres joueurs seront résolus (ou quand le cron horaire/quotidien tournera, qui n'est à visualiser que comme un "joueur" régulier qui repasse toutes les X heures, histoire de ne pas trop stacker de trucs)
Tu attends donc le retour d'un d'entre eux voire de tous pour mettre à jour les données ?
C'est ça. S'il n'y a personne pour "voir" le jeu, y'a pas besoin de se poser la question de "mais attends, les combats n'ont pas été résolus là?!"
Tu attends la cron qui tourne, par exemple toutes les minutes ?
Non, horaire ou quotidien. Y'a aucun intérêt à bousiller un serveur avec des cron à la minute
Et donc, si un joueur D attaque dans cette minute, il joue sur des données non à jour ?
Non, quand le joueur D se pointe sur une des pages du jeu pour faire son attaque ou voir ce qu'il se passe, on résout la stack d'actions en attente puis on lui refile la page en question. Il ne joue donc pas sur des données "par à jour".
Mettre à jour les données quand le joueur se repointe dans une situation d'interaction n'est pas satisfaisant
Faudra m'expliquer pourquoi
de même que le cron ne suffit pas
Je pense que l'explication là-dessus rejoindra celle de la précédente
Le cron peut gérer cette situation si tu fais une exécution dans l'ordre des événements
Oui, de même si la résolution est faite avant de servir la page au joueur. L'important est de bien comprendre qu'on stock une stack d'évènements datés (avec heure, minute secondes heinà, et que leur résolution ne se fait pas (nécessairement) à la date en question
mais il ne gérera pas un joueur E qui viendrait espionner la situation vécue dans le laps de temps où ça n'a pas été exécuté
Ben, oui, c'est pour ça qu'un démon (sauf quant à avoir un langage+stack+besoin conçu pour, cf jeux AAA) ou un cron minuté merdique n'ont pas leur place ici. Quand le joueur E va lancer son espionnage, on va résoudre ce qui concerne ce joueur puis lui afficher la page de lançage d'espionnage, il va le lancer, il est censé se faire à une date T, et il sera résolu à une date T' indépendante de T.
Le joueur E n'aura donc pas la vision du jeu à N+30s d'un événement arrivé à N parce que ton cron tourne à N+1m.
Oui, c'est pour cela que le principe du démon pu du... coude, peu importe la fenêtre de temps qu'on se fixe.
Tu peux en revanche le gérer de façon insatisfaisante en renvoyant le résultat au joueur E à N+1min, une fois que son propre événement est exécuté.
Je ne suis pas sûr de comprendre...
Par contre, je ne vois pas en quoi le fait d'avoir une cron (qui reste à proprement parler un démon) qui tourne multiplierait ton risque de bug puisque c'est quelque chose de parfaitement géré par le serveur.
Fais donc un CRON minuté qui tourne pendant quelques jours voire semaine: tu tomberas très certainement sur des erreurs "random" (ou plutôt, des erreurs rares de "pas de chance"): une BDD qui va se déconnecter sur un des appels du cron, ou qui aura eu de la latence, ou un pool de connexion qui va saturer parce que le serveur mouline un peu ce jour-là, etc
J'en reviens toujours au même exemple hein: quand tu veux fêter l'anniversaire de tes joueurs (leur anniversaire IRL ou le "bravo vous jouez depuis 1 an"), tu stockes une date et une heure, et la résout à la volée au moment où tu veux savoir si c'est son anniversaire. Tu ne fais pas un cron qui sauve "0s" en BDD, et qui incrémente ce compteur de 1 à chaque seconde (ou à chaque minute, ou un CRON journalier qui va incrémenter de 1 jour le nombre de jours pendant lesquels le joueur a joué). Tu sauves un point du temps, et tu résouts le problème sur la base de ce point du temps.
Si ton langage est conçu pour faire du "at", comme posé dans la question initiale, tu t'en sers, tu dis "at [telle date+heure], faire ça", et point barre. Comme c'est résolu, ce n'est pas dans ton "scope". Si ton langage n'en est pas capable (type PHP), tu ne bricole pas un CRON secondé/minuté ou je ne sais quelle daube pour l'émuler de travers.
D'ailleurs, même si ton langage est capable de gérer les "at", il faut quand même comprendre comment les choses vont se passer: ton batiment ne sera pas construit pile à 3H59. Supposons qu'à 3H58, l'armée de A attaque l'armée de B, et qu'il s'agisse de 2 grosses armées dont le caclul du combat va prendre 5 minutes, tu vas faire comment? Le batiment va se terminer 5 minutes plus tard (donc perdre 5 minutes de production) car le démon/cron/jsaispasquoi est séquentiel? Le batiment va se terminer pendant le calcul du combat (et planter ce calcul ou éventuellement l'altérer si ce batiment était une tourelle de défense de A)?
D'où le principe de base de décorréler le moment où un calcul se fait (3H58+5 = 4H03 pour la construction du batiment) et le moment dans le jeu où il est construit (3H59 in game).
Après, vous faites bien comme vous voulez, sur des jeux web amateur y'a pas souvent beaucoup de conséquence à ce genre de choses, mais bon, j'espère que vous n'êtes pas ingénieurs (peu importe le domaine), et que vous ne travaillez pas dans une banque ou une entreprise critique en matière de fiabilité/sécurité...
On s'en balec, le web n'est pas conçu initialement pour faire du temps réel, y'a pas de notion de "sans aucun joueur connecté" (ou dit autrement, il n'y a jamais de joueur "connecté": ce sont des échanges ponctuels serveur/client, pas des flux continus).
Quand le joueur D va se pointer, les attaques/productions/j'sais pas quoi des autres joueurs seront résolus (ou quand le cron horaire/quotidien tournera, qui n'est à visualiser que comme un "joueur" régulier qui repasse toutes les X heures, histoire de ne pas trop stacker de trucs)
Tu attends donc le retour d'un d'entre eux voire de tous pour mettre à jour les données ?
C'est ça. S'il n'y a personne pour "voir" le jeu, y'a pas besoin de se poser la question de "mais attends, les combats n'ont pas été résolus là?!"
Tu attends la cron qui tourne, par exemple toutes les minutes ?
Non, horaire ou quotidien. Y'a aucun intérêt à bousiller un serveur avec des cron à la minute
Et donc, si un joueur D attaque dans cette minute, il joue sur des données non à jour ?
Non, quand le joueur D se pointe sur une des pages du jeu pour faire son attaque ou voir ce qu'il se passe, on résout la stack d'actions en attente puis on lui refile la page en question. Il ne joue donc pas sur des données "par à jour".
Mettre à jour les données quand le joueur se repointe dans une situation d'interaction n'est pas satisfaisant
Faudra m'expliquer pourquoi
de même que le cron ne suffit pas
Je pense que l'explication là-dessus rejoindra celle de la précédente
Le cron peut gérer cette situation si tu fais une exécution dans l'ordre des événements
Oui, de même si la résolution est faite avant de servir la page au joueur. L'important est de bien comprendre qu'on stock une stack d'évènements datés (avec heure, minute secondes heinà, et que leur résolution ne se fait pas (nécessairement) à la date en question
mais il ne gérera pas un joueur E qui viendrait espionner la situation vécue dans le laps de temps où ça n'a pas été exécuté
Ben, oui, c'est pour ça qu'un démon (sauf quant à avoir un langage+stack+besoin conçu pour, cf jeux AAA) ou un cron minuté merdique n'ont pas leur place ici. Quand le joueur E va lancer son espionnage, on va résoudre ce qui concerne ce joueur puis lui afficher la page de lançage d'espionnage, il va le lancer, il est censé se faire à une date T, et il sera résolu à une date T' indépendante de T.
Le joueur E n'aura donc pas la vision du jeu à N+30s d'un événement arrivé à N parce que ton cron tourne à N+1m.
Oui, c'est pour cela que le principe du démon pu du... coude, peu importe la fenêtre de temps qu'on se fixe.
Tu peux en revanche le gérer de façon insatisfaisante en renvoyant le résultat au joueur E à N+1min, une fois que son propre événement est exécuté.
Je ne suis pas sûr de comprendre...
Par contre, je ne vois pas en quoi le fait d'avoir une cron (qui reste à proprement parler un démon) qui tourne multiplierait ton risque de bug puisque c'est quelque chose de parfaitement géré par le serveur.
Fais donc un CRON minuté qui tourne pendant quelques jours voire semaine: tu tomberas très certainement sur des erreurs "random" (ou plutôt, des erreurs rares de "pas de chance"): une BDD qui va se déconnecter sur un des appels du cron, ou qui aura eu de la latence, ou un pool de connexion qui va saturer parce que le serveur mouline un peu ce jour-là, etc
J'en reviens toujours au même exemple hein: quand tu veux fêter l'anniversaire de tes joueurs (leur anniversaire IRL ou le "bravo vous jouez depuis 1 an"), tu stockes une date et une heure, et la résout à la volée au moment où tu veux savoir si c'est son anniversaire. Tu ne fais pas un cron qui sauve "0s" en BDD, et qui incrémente ce compteur de 1 à chaque seconde (ou à chaque minute, ou un CRON journalier qui va incrémenter de 1 jour le nombre de jours pendant lesquels le joueur a joué). Tu sauves un point du temps, et tu résouts le problème sur la base de ce point du temps.
Si ton langage est conçu pour faire du "at", comme posé dans la question initiale, tu t'en sers, tu dis "at [telle date+heure], faire ça", et point barre. Comme c'est résolu, ce n'est pas dans ton "scope". Si ton langage n'en est pas capable (type PHP), tu ne bricole pas un CRON secondé/minuté ou je ne sais quelle daube pour l'émuler de travers.
D'ailleurs, même si ton langage est capable de gérer les "at", il faut quand même comprendre comment les choses vont se passer: ton batiment ne sera pas construit pile à 3H59. Supposons qu'à 3H58, l'armée de A attaque l'armée de B, et qu'il s'agisse de 2 grosses armées dont le caclul du combat va prendre 5 minutes, tu vas faire comment? Le batiment va se terminer 5 minutes plus tard (donc perdre 5 minutes de production) car le démon/cron/jsaispasquoi est séquentiel? Le batiment va se terminer pendant le calcul du combat (et planter ce calcul ou éventuellement l'altérer si ce batiment était une tourelle de défense de A)?
D'où le principe de base de décorréler le moment où un calcul se fait (3H58+5 = 4H03 pour la construction du batiment) et le moment dans le jeu où il est construit (3H59 in game).
Après, vous faites bien comme vous voulez, sur des jeux web amateur y'a pas souvent beaucoup de conséquence à ce genre de choses, mais bon, j'espère que vous n'êtes pas ingénieurs (peu importe le domaine), et que vous ne travaillez pas dans une banque ou une entreprise critique en matière de fiabilité/sécurité...