02-01-2008, 04:40 PM
Il ne faut faire ces taches que lorsqu'on est sûr d'en avoir besoin, et n'effectuer que les opérations qui concernent directement ou indirectement le joueur connecté.
Par exemple au moment où il se connecte tu vas recalculer sa jauge de faim, car c'est un élément qui doit être à jour instantanément.
En revanche si sa réserve de blé n'est pas affichée en page d'accueil, il ne faut faire la mise à jour que lorsque son affichage est réclamé.
L'inconvénient de cette pratique, c'est que les classements sont soit pas à jour, soit très lourds à calculer (puisqu'il faut faire toutes les mises à jour de tout le monde avant d'afficher le classement).
Que personne ne la réclame pendant 3 jours ou qu'on la réclame toutes les 3 secondes ne doit avoir aucun impact ! sinon tu peux être sûr que tout ton jeu ne sera qu'une grosse faille béante demandant à être exploité.
Un exemple : un joueur gagne 1 épi de blé toutes les heures pleines (60 minutes).
J'ai stocké quelque part (mettons dans une table "updates", qui aurait 3 champs : user_id, quoi, quand) la date de dernière mise à jour du stock d'épis de blé, date_maj = 31/12/2007 02:51:34 (timestamp = 1199065894)
date_maintenant = 02/01/2008 15:31:47 (timestamp = 1199284307)
Différence des timestamps = 1199284307 - 1199065894 = 218413 secondes
Nombre d'heures pleines écoulées = floor(218413/3600) = 60, restent 218413 % 3600 = 2413 secondes.
- Depuis la dernière mise à jour, le joueur a gagné 60 épis de blé (60 heures pleines écoulés), qu'on ajoute dans la base de données
- On stocke la nouvelle date de dernière mise à jour : maintenant ? Raté !! C'est là l'erreur, car en faisant ça on sucre 2413 secondes, et le joueur ne gagnera son épi que dans une heure complète au lieu de 20 minutes ! La nouvelle date de dernière mise à jour est donc date_maintenant - 2413
Et là, aucun bug
Si je résume, pour un évènement indépendant du contexte (s'il dépend d'un élément tiers comme la météo, la santé, etc... on est obligé de passer par un vrai cron) régulier survenant toutes les X secondes :
- Exécuter l'évènement N fois, N = arrondi_inférieur((date_maintenant - date_derniere_mise_a_jour) / X)
- Stocker date_derniere_mise_a_jour = date_maintenant - ((date_maintenant - date_derniere_mise_a_jour) % X)
Par exemple au moment où il se connecte tu vas recalculer sa jauge de faim, car c'est un élément qui doit être à jour instantanément.
En revanche si sa réserve de blé n'est pas affichée en page d'accueil, il ne faut faire la mise à jour que lorsque son affichage est réclamé.
L'inconvénient de cette pratique, c'est que les classements sont soit pas à jour, soit très lourds à calculer (puisqu'il faut faire toutes les mises à jour de tout le monde avant d'afficher le classement).
Que personne ne la réclame pendant 3 jours ou qu'on la réclame toutes les 3 secondes ne doit avoir aucun impact ! sinon tu peux être sûr que tout ton jeu ne sera qu'une grosse faille béante demandant à être exploité.
Un exemple : un joueur gagne 1 épi de blé toutes les heures pleines (60 minutes).
J'ai stocké quelque part (mettons dans une table "updates", qui aurait 3 champs : user_id, quoi, quand) la date de dernière mise à jour du stock d'épis de blé, date_maj = 31/12/2007 02:51:34 (timestamp = 1199065894)
date_maintenant = 02/01/2008 15:31:47 (timestamp = 1199284307)
Différence des timestamps = 1199284307 - 1199065894 = 218413 secondes
Nombre d'heures pleines écoulées = floor(218413/3600) = 60, restent 218413 % 3600 = 2413 secondes.
- Depuis la dernière mise à jour, le joueur a gagné 60 épis de blé (60 heures pleines écoulés), qu'on ajoute dans la base de données
- On stocke la nouvelle date de dernière mise à jour : maintenant ? Raté !! C'est là l'erreur, car en faisant ça on sucre 2413 secondes, et le joueur ne gagnera son épi que dans une heure complète au lieu de 20 minutes ! La nouvelle date de dernière mise à jour est donc date_maintenant - 2413
Et là, aucun bug
Si je résume, pour un évènement indépendant du contexte (s'il dépend d'un élément tiers comme la météo, la santé, etc... on est obligé de passer par un vrai cron) régulier survenant toutes les X secondes :
- Exécuter l'évènement N fois, N = arrondi_inférieur((date_maintenant - date_derniere_mise_a_jour) / X)
- Stocker date_derniere_mise_a_jour = date_maintenant - ((date_maintenant - date_derniere_mise_a_jour) % X)
Ressources [PHP][MySQL][prototype.js]