JeuWeb - Crée ton jeu par navigateur
[Résolu] Cron ou pas cron ? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Résolu] Cron ou pas cron ? (/showthread.php?tid=431)



[Résolu] Cron ou pas cron ? - Sezyth - 27-05-2013

Re !

Pour ma première question ici, j'aurai besoin plus d'un avis ou d'une idée que d'un code.
Je vous explique :

Dans mon projet (PHP), les joueurs sont censés regagner de la vie toutes les X minutes (1 ou 5).

- J'avais d'abord pensé à faire une simulation de cron :
Dans ma BDD serait stockée un timestamp de la dernière action du joueur. Tant qu'il joue, on vérifie le timestamp et si celui-ci est dépassé de X * 60 alors on lance le script de regain d'énergie.
S'il ne joue plus, le joueur est figé. Lorsqu'il se connecte, on relance le script.

A priori invisible pour le joueur. Mais si le joueur quitte le jeu alors qu'il n'a plus que 10 PV, un autre player qui l'attaquerai même 2 jours plus tard le battrait facilement car sa vie n'aurait pas augmenté.

- Autre solution : Passer par un cron qui, lancé toutes les X minutes fait le tour des joueurs et augmentent à tous leurs PV.
Défaut : Si 2 joueurs sont en train de s'affronter pendant l'exécution du cron, alors d'un coup PAF : regain d'énergie.
Raisonnement pas si bête : on stocke les niveaux de santé des 2 joueurs dans la session de l'attaquant.
Défaut : C'est falsifiable, aussi quelqu'un de malveillant peut très bien gagner tous ses combats aisément :/

=> En résumé, j'aimerai connaître votre avis sur la question et/ou si vous aviez des idées à me proposer pour améliorer ce système. J'imagine ne pas être le premier qui se pose ce genre de question..
Malgré mes recherches sur le forum, je n'ai rien trouvé de comparable excepté les ressources mais ma problèmatique ne s'y applique pas..

Merci !


RE: Cron ou pas cron ? - niahoo - 27-05-2013

C'est un problème que le regain d'énergie arrive en plein combat ? Y a pas de raison d'autant que les deux joueurs en bénéficient. Donc si dans ta table joueurs tu as un champ qui indique combien il gagne par minutes (ou de quoi le calculer) tu balances update joueur set vie = vie + gain_par_minute;. Ensuite faut voir comment ça se place au niveau des combats.


RE: Cron ou pas cron ? - Xenos - 27-05-2013

Variante:

un système qui enregistre, pour chaque joueur, le nombre de points de vie dans la BDD, avec le timestamp donnant la date de validité de ces PV.
Dans le PHP, dans la classe "player", l'attribut "vie" est initialisé en lisant la vie dans la BDD, et en calculant la différence entre timestamp actuel et timestamp de la BDD. Cette différence est alors multipliée par la valeur de regénération, donnant la santée réelle dans l'attribut "vie" de la classe "player" pour le code PHP. Une fois ces opérations faites, le joueur est re-sauvé dans la BDD, avec le timestamp actuel et sa santé issue de l'attribut "vie" de la classe "player".

Si la BDD est de type "objet" (certains NoSQL par exemple), cela peut se simplifier en déportant tout le calcul du PHP vers la BDD elle-même.
Dans les autres cas, type MySQL, la seule délicatesse à gérer est de s'assurer que le scénario suivant ne se produit pas:
- Le script lit la BDD et instancie "player"
- La vie du joueur est calculée
- Un autre script instancie ce même joueur (un autre visiteur du jeu par exemple)
- Le 1er script fait ses traitement, et blesse le joueur (classe "player")
- Le 2nd script fait ses traitement et blesse le joueur (classe "player")
- Le 1er script sauve son résultat
- Le 2nd script sauve son résultat

Le 1er script se fera, dans ce scénario, totalement occulter.
On peut le gérer de plusieurs façons:
- L'ignorer (si les traitements sont courts, et qu'il n'y a pas énormément de joueurs, la probabilité que ce scénario apparaisse peut être faible et tolérée)
- Verrouiller la table (dur!) ou la ligne (mieux) de la BDD, mais cela ralentit le traitement
- Utiliser un système incrémental (au lieu de lire la vie dans la BDD, puis de la mettre à jour dans la classe, puis de combattre et enfin de sauver, on fait tout ca dans une seule et même requête SQL qui serait "atomique")

Cela dit, la méthode de Niahoo est parfaitement envisageable aussi. En revanche, si tu as des milliers d'enregistrements ou si ce genre de scénario se reproduit de nombreuses fois par minute ou pour de nombreuses variables, cette méthode peut vite devenir lourde.
Celle que je te propose est lourde aussi, mais sa "lourdeur" est répartie sur tous les clients (vaut-il mieux faire, dans une journée, 24*60=1440 mises à jours de toute la table de la BDD, soit une par minute, ou faire des mises à jour que lorsque cela est nécessaire?)


RE: Cron ou pas cron ? - Sezyth - 27-05-2013

Merci de vos réponses.
En effet, la raison pour laquelle je n'avais pas 'préféré' la solution 'cron' est que cela peut vite devenir lourd pour le serveur : nombre de requetes pour une journée = X joueurs * 1440 (1 minute) + X joueurs * 288 (5 minutes, pour une autre ressource) + X joueurs * 24 (une autre donnée actualisée toutes les 24 heures).
Si jamais je n'ai "que" 200 membres, cela me fait déjà 350 400 opérations par jour, sans qu'aucun membre n'ai joué..

Je pense adopter ta méthode Xenos, à savoir que le joueur attaquant fera automatiquement actualiser le ombre de PV du défenseur. Cependant, j'ajouterai simplement une colonne dans ma table 'en_combat'. Lorsque le joueur attaque ou se fait attaquer, cette valeur passe à 1.
Si un autre désir l'attaquer => impossible.
Si le combat se termine ou que l'attaquant ne réagit pas assez vite pour continuer le combat (JS ou Ajax peut-être ? ), on termine automatiquement le combat (pour éviter le cas ou l'attaquant ferme son navigateur et que tous 2 restent en combat indéfiniment) et la colonne repasse à 0.

Qu'en penses-tu ?


RE: Cron ou pas cron ? - Xenos - 27-05-2013

Cela ressemble à un bricolage de sémaphores sur du "long terme" (on compte en minutes, pas en milliseconde) hmm...
Cela ne me semble pas trop puer... Pour autant, je ne partirai pas que là-dessus. A ta place, j'utiliserai non pas un booléen, mais un timestamp, qui indique le début du combat, ou la date de dernière activité du combat. Si cette date est trop "ancienne" (passé 5 minutes par exemple), le personnage n'est pas bloqué. Tant que cette date est récente (moins de 5 minutes), elle indique que le joueur est bloqué. Ainsi, tu pourras savoir qui est en combat, et depuis combien de temps (à condition d'enregistrer la date de début de combat ET la date de dernière activité, sinon, le "depuis combien de temps" n'est pas déterminé).

Cela évite les bisebilles avec des AJAX qui ne se termineront peut-être jamais ou qui pourront être relancés en boucle pour faire croire que le personnage combat alors qu'il ne combat pas (et ainsi, on rendrait son personnage "intouchable" car on le coincerai dans une boucle infinie d'un "faux-combat").


RE: Cron ou pas cron ? - Sezyth - 27-05-2013

Idée excellente, merci beaucoup.
Cependant, si je stocke la dernière activité du combat, quelle est l'utilité du timestamp du début du combat ? Peu importe la durée du combat, si le mec n'a pas attaqué au bout de X minutes il n'est plus considéré comme étant en combat.
En plus ça me fait du coup double dans le sens où ça laisse le défenseur s'enfuir ou gagner de la vie avant de se faire attaquer une nouvelle fois par un autre joueur.


RE: Cron ou pas cron ? - Xenos - 27-05-2013

La date de début de combat peut te servir si tu veux afficher des statistiques pour tout le jeu, avec la liste des utilisateurs en combat, et la date de début du combat (machin est en combat depuis XXX minutes, bidule est en combat depuis XXX heures... en calculant le XXX à partir du timestamp de début de combat stocké dans la BDD)
Ce n'est en rien une obligation ce timestamp de début de combat, c'est juste une statistique intéressante (et vu qu'OVH est passé de 20Mo à 200Mo pour la BDD des mutualisés perso c'est à dire le ras-les-paquettes à 2€/mois, être radin sur la taille de la BDD n'a plus de sens).


RE: Cron ou pas cron ? - Sezyth - 27-05-2013

Très bien je vois.
Radin sur la BDD non, mais le plus rapide possible oui (:
Après je verrai si j'organise des stats ou des nouvelles de ce genre.
Sujet résolu pour ma part, encore merci à vous.
Bonne soirée !