JeuWeb - Crée ton jeu par navigateur
Gérer les Pièces d'Or - 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 : Gérer les Pièces d'Or (/showthread.php?tid=2573)

Pages : 1 2


Gérer les Pièces d'Or - MaXOhBalle - 23-09-2009

Bonjour,

j'ai un problème lié aux Pièces d'Or Smile

Pour faire court, dans mon jeu vous étes le chef d'une cité et des habitants arrivent et ont un emploi dans les différents bâtiments de la cité; cet emploi implique une paye, qui coute des Pièces d'Or à la cité (à vous quoi).

Seulement je n'arrive pas à trouver la bonne technique pour gérer ça.

La paye se fait par heure donc j'ai bien un algorithme pour savoir combien la ville doit s'enlever de pièces d'or à chaque heure mais pour que tout se passe en temps réel les pièces d'or doivent diminuer (ou augmenter selon ce que la ville gagne avec les bâtiments) selon les gains/pertes engendrées par heure (si on gagne 60 pièces d'or par heure, il y aura une modification toutes les minutes). Le problème étant que si la ville gagne 19.999 pièces d'or par heure ça va en faire un sacré paquet de requêtes sql (oui car le problème est là, à chaque fois qu'on modifie, on modifie aussi la base sql).

Je me demandais donc comment faire une sorte de "temps réel" (le joueur voit les pièces d'or diminuer ou augmenter en direct grâce à du javascript) tout en évitant les requetes sql trop régulières (à chaque rafraichissement de page quoi); je suppose que la plupart d'entre-vous avez eu un problème analogue à un moment ou à un autre et vous demande quel est le meilleur système à adopter, pour vous ?

Merci d'avance, je bloque là... Smile


RE: Gérer les Pièces d'Or - QuentinC - 23-09-2009

Ben c'est simple, tu mets à jour la base à chaque fois que le joueur demande une nouvelle page ou actualise avec F5. Si le joueur ne se connecte pas, tu n'actualises pas... mais c'est pas grave, il n'est pas là pour le voir. tu enregistres la date de la dernière mise à jour et tu calcules en conséquence au moment où tu en as besoin.


RE: Gérer les Pièces d'Or - Anthor - 23-09-2009

Qu'est-ce qui t'empêche d'afficher uniquement le calcul, au lieu de sauvegarder à chaque fois ?


RE: Gérer les Pièces d'Or - MaXOhBalle - 23-09-2009

QuentinC très bonne solution, j'y avais déjà pensé mais c'était flou Smile

Anthor, ben pour l'instant yah pas de cache sur le jeu donc ça va chercher automatiquement dans la base le nombre de pièce d'or donc impossible d'afficher uniquement le calcul (le cache j'le ferais à la fin du dev)

Merci beaucoup à vous deux Wink


RE: Gérer les Pièces d'Or - Plume - 23-09-2009

J'avoue avoir du mal à cerner la nécessité de mettre en place du cache pour afficher une valeur calculable.

Ca me pousse à compléter cet article sur l'organisation des données dans les tables ou à en écrire un autre dans la continuité...


RE: Gérer les Pièces d'Or - zeppelin - 23-09-2009

La remarque d'anthor était la suivante il me semble: Quand le gaillard se logge tu fait une requête, et tu stock la valeur en session par exemple. Il te reste à savoir combien déduire par heure, et à chaque actualisation de la page tu lance un calcul (il s'est loggé à timestamp et avait x or, il est timestamp +y maintenant, il a donc z or...). Tu sais donc combien afficher, combien il peux dépenser etc. mais tu n'actualise pas en BDD!! Tu actualise uniquement chaque heure avec une tâche cron. Le joueur a donc toujours la bonne quantité d'or, mais tu n'actualise qu'une fois par heure.

ps. Pas sûr d'avoir été clair, je vais faire un petit exemple si besoin ;-)


RE: Gérer les Pièces d'Or - Anthor - 23-09-2009

Zeppelin a bien résumé ma question.
Un simple calcul est transparent pour le serveur, maintenant, je ne mettrais pas la mise à jour avec un CRON, je ferais simplement une vérification pour mettre à jour si l'update n'a pas été fait depuis un certain temps, ou si une action autre que l'affichage nécessite le calcul. De façon a bien répartir la charge.


RE: Gérer les Pièces d'Or - Argorate - 23-09-2009

Je me demande s’il ne faudrait pas faire un tuto une bonne fois pour toute avec ça, c'est toujours la même chose...^^

Déjà, ne parle pas de temps réel quand c'est un jeu par tour avec 1 tour = 1H.
Ensuite pour des raisons de performances évidentes, le cron n'est pas la bonne solution puisqu'il ira rafrech tout le monde y compris des inactifs.
Il reste donc la solution que d'autres ont déjà évoqué et qui me semble judicieuse:

Tu actualises que ce qui a besoin d'être actualiser. Pourquoi actualiser un joueur qui ne vient pas jouer (peu importe la raison)? Ça te fait des requêtes pour rien.
Donc lorsqu'un joueur se connecte ou fait F5 sur ta page jeu, tu vérifies le temps qui est passé depuis le dernier "tour" et tu regarde si ça fait X heure(s).

En conséquence de quoi, tu fais t'es calcule et ce X fois.

Pour calculer ce fameux X (nb d'heure écoulé [allant de 0 à l'infinie en théorie]), rien de plus simple: tu stock en bdd un timestamp et tu le compares au timestamp actuel lorsque le gars appel la page de jeu, ensuite c'est juste une soustraction avec des convertissions des unités (puisque timestamp est en seconde)...
Sachant qu'il y a 60 secondes par minute
60 minutes par heure
Et 3 600 secondes par heure, tu as tes diviseurs pour convertir Wink

Bonne chance.


RE: Gérer les Pièces d'Or - zeppelin - 23-09-2009

A vrai dire j'ai dis cron dans le but de dire "une autre fois". Mais attention messieurs s'il vous plaît! Ce n'est pas par-ce qu'on utilise un cron qu'il doit être mauvais!

C'est sûr que si on passe par des boucles, bonjour les dégâts! Mais un update comme ci-dessous est léger, ou plutôt relativement léger en comparaison de certains scripts qui sont récurrents à chaque appel de page. Stop préjugé :-p

Code PHP :
<?php 
'UPDATE ressources left join userInfos on ressources.uid = userInfos.uid SET ressources.gold += '. $value .' WHERE userInfos.lastLogin >= '. time() - 3600;



RE: Gérer les Pièces d'Or - MaXOhBalle - 24-09-2009

(23-09-2009, 06:42 PM)Argorate a écrit : Je me demande s’il ne faudrait pas faire un tuto une bonne fois pour toute avec ça, c'est toujours la même chose...^^

Déjà, ne parle pas de temps réel quand c'est un jeu par tour avec 1 tour = 1H.
Ensuite pour des raisons de performances évidentes, le cron n'est pas la bonne solution puisqu'il ira rafrech tout le monde y compris des inactifs.
Il reste donc la solution que d'autres ont déjà évoqué et qui me semble judicieuse:

Tu actualises que ce qui a besoin d'être actualiser. Pourquoi actualiser un joueur qui ne vient pas jouer (peu importe la raison)? Ça te fait des requêtes pour rien.
Donc lorsqu'un joueur se connecte ou fait F5 sur ta page jeu, tu vérifies le temps qui est passé depuis le dernier "tour" et tu regarde si ça fait X heure(s).

En conséquence de quoi, tu fais t'es calcule et ce X fois.

Pour calculer ce fameux X (nb d'heure écoulé [allant de 0 à l'infinie en théorie]), rien de plus simple: tu stock en bdd un timestamp et tu le compares au timestamp actuel lorsque le gars appel la page de jeu, ensuite c'est juste une soustraction avec des convertissions des unités (puisque timestamp est en seconde)...
Sachant qu'il y a 60 secondes par minute
60 minutes par heure
Et 3 600 secondes par heure, tu as tes diviseurs pour convertir Wink

Bonne chance.

Je parlais uniquement d'une "impression" de temps réel, étant donné que le jeu en son entier implique des interactions permanente (la paye toutes les heures c'est qu'un point précis du jeu). Evidemment c'est toujours "par tour" mais l'impression de temps réel doit être là donc voilà.

Ensuite, je peux pas vraiment faire de requête toutes les heures (idée de zeppelin/Anthor) étant donné les fameuses "interactions" qui font que pratiquement à chaque action du joueur le calcul est chamboulé pour X raison.

Je vais donc opter pour un système de "vagues" (j'appelle ça comme ça); dans mysql je met le time() de la prochaine vague, chaque vague est calculée en fonction de la production de pièces d'or par heure (produc & pertes) et dés que l'user rafraichi sa page le header de la page (un script php qui fait toutes les actions avant l'affichage) calcul combien de fois la vague aurait dû passer (et met le bon nombre de pièces d'or en +/- à l'user) puis remet en place un nouveau système de vague si jamais le time() actuel est plus grand que le time() dans la BDD & qu'aucune modif impliquant les pièces d'or n'a été effectué.

Voilà, je pense que ça fonctionnera, merci beaucoup Smile

(si quelqu'un a une meilleur idée qu'il n'hésite pas)

Voilà voilà