JeuWeb - Crée ton jeu par navigateur
Gestion des enchantements et autres effets sur la durée - 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 : Gestion des enchantements et autres effets sur la durée (/showthread.php?tid=4989)



Gestion des enchantements et autres effets sur la durée - PommeCassis - 14-07-2010

Bonjour,

je planche actuellement sur la conception d’un système de gestion des altérations (enchantements, malédictions, tout ça). Je souhaiterai offrir pas mal de possibilité gameplay au niveau des compétences. Pour cela le joueur aura le choix d’une classe primaire, d’une race puis d’une classe secondaire qui offriront chacune un arbre de compétences.

Mon objectif est de réaliser un système polyvalent qui ne me limitera pas pour de futures compétences. Mon problème est que cela semble complexe, je ne sais pas trop comment m’y prendre.

Pour vous situer dans ce bazar voila un bref récapitulatif du jeu que je veux faire :
Le but du jeu est de faire évoluer son personnage sur un damier géant de 500*500 cases (jeu que certains qualifieront de tapes-cases :haha: ). Celui-ci ce caractériserait par la possibilité d’altérer l’environnement, la possibilité de construire des bâtiments pour sa race, la prise de reliques, etc. Le jeu se baserait sur un système de point d'action attribué en petites quantités toutes les XX minutes (15 min par ex).
Le jeu sera développé sous Symfony.

Règle générale sur les effets/altérations/enchantements (enfin appelez ca comme vous voulez) :
- Altération des statistiques pouvant être exprimée en pourcentage ou en valeur chiffrée
- Les effets peuvent être apportées par :
> Compétences
> Terrains
> Bâtiments
> Equipements

Chaque effet a donc :
Une durée : illimitée, limitée dans le temps, limité par rapport à une condition spéciale (dure jusqu'à ce que le personnage reçoive 3 coups par exemple)
Un type : enchantement, pose de combat, malédiction, aura, condition, etc.
Déclenchement/Effectivité : permanent ( boost de +10 en force par exemple), déclenchement lors d’une action particulière (5% de déclencher l’effet si frappé par exemple)
Un effet : altération des statistiques, altération de l’environnement, invisibilité/furtivité, renvoie de dégâts, invocation de monstres (Par exemple a votre mort sous l’enchantement, un puissant squelette est invoqué), dégâts périodiques, etc.


Les modifications normales de statistiques, ca doit être simple à gérer. Ce qui me dérange le plus c’est pour faire par exemple un enchantement qui a X% de chance de déclencher certaines actions lors de certains évènements, un autre qui augmente le coup en PA de telle action, etc. Ca devient compliqué vue la multitude d’effets possible.

Autre problème : Si chaque bestioles/personnages régénère 1% de vie et 3PA chaque tour, il faut faire un calcul sur par exemples 500 personnages + 300 bestioles, ca fait 800 petits calculs a faire toutes les 15 minutes. (dans le cas ou un tour correspond à 15 min).

Mais en plus je dois aussi regarder les effets, certains peuvent augmenter la régénération des PA ou des points de vie par exemple. Ces effets peuvent être offert aussi par le terrain (qui peut être aussi enchanté), une aura, un bâtiment ou autre. Mais je peux pas parcourir une liste de plusieurs milliers d’enregistrements toutes les quinze minutes et faire tout un tas de traitement pour déterminer qui a le droit à quoi puis mettre en conséquence. Ca serait trop lourd.

De plus les altérations ont des durées, il faut gérer cela avec une sorte de générateur de tache fcron qui s’occupe de nettoyer les effets ?

Par exemple je m’enchante avec « Bénédiction MêmePasMal » qui dure 15h. Je crée donc une tache fcron qui lancera un script pour supprimer l’effet 15h plus tard ?

Mais si la tache fcron se déroule mal pour une raison quelconque, ca risque de causer des vilains bugs.

Comment gérer efficacement cette multitude de paramètres pour chaque effet ? Placer des tas de tables dans la bdd juste pour les effets et transformer le tout en usine à gaz ? Comment gérer leurs cycles de vie ? Comment optimiser tout ça ?

Si vous avez de la documentation, un conseil ou n’importe quoi la dessus je suis preneur.

Merci d’avance.

edit: mince mauvaise section Sad


RE: Gestion des enchantements et autres effets sur la durée - Globe - 14-07-2010

Pour ce que tu cherches à faire je passeraispar plusieurs tables. Quelque chose comme une table sorts qui possède des champs qui appellent une table effets et des champs de valeur. En version simplifiée imaginons ta table sorts:
nom_du_sort, cout_mana, effet1, valeur1, effet2, valeur2, effet3, valeur3.
Bon et tu ne peux mettre qu'un seul effet et qu'un seul paramètre si tu n'as pas besoin de plus. Donc maintenant imaginons une entrée dans cette table:
boule_de_feu, 10, degats_feu, 25, brulure, 10, aucun, 0.
Et maintenant dans une table effets on pourrait imaginer quelque chose comme :
nom_effet, type_effet, type_sort.

Et là tu aurais par exemple deux entrées : degats_feu, degats_direct, elemental_feu
et brulure : brulure, degats_sur_temps, elemental_feu.

Enfin je pense que je m'y prendrais comme ça. Après concernant tes actualisations sur le temps pourquoi ne pas utiliser un simple timestamp et ne rafraichir les données que quand tu en as vraiment besoin plutôt que de faire des requetes immenses ?

Edit: Tu peux aussi rajouter type_cibles possibles si tu veux gérer les bâtiments...


RE: Gestion des enchantements et autres effets sur la durée - Foxglove - 14-07-2010

Tu peux aussi t'arranger pour que le calcul ne soit fait que lorsque la personne se reconnecte. Exemple :
Il était 10h30, le joueur est en combat avec une araignée. Le joueur commence l'attaque de l'araignée qui perd 10 PV. Le joueur se déconnecte.
Il est 11h17 et le joueur se reconnecte. Le système calcule qu'il y a eu 3 tours de 15 minutes passés. Le système rejoue les tours en vitesse accélérée. Le problème de cette approche, c'est quand il y a beaucoup d'interactions entre les joueurs, ou si les joueurs ne se déconnectent pas vraiment.

Tu as la possibilité d'utiliser un système d'agenda comme cron, comme tu le dis, mais à ta place je ferais un truc perso (tu aurais plus de flexibilité).

Tu peux aussi tenter de regrouper tes requêtes pour ne pas faire 800 requêtes différentes pour 800 actions. Cela dit, 800 requêtes toutes les 15 minutes, ça me paraît pas énorme non plus (même si elles doivent être faites toutes en même temps).


RE: Gestion des enchantements et autres effets sur la durée - Zamentur - 15-07-2010

Citation :Le problème de cette approche, c'est quand il y a beaucoup d'interactions entre les joueurs, ou si les joueurs ne se déconnectent pas vraiment.
C'est effectivement pas à la connexion qu'il faut le faire, mais à chaque nouvelle page demandé.

Mais plutôt que de faire un update de la table il vaut mieux enregistrer le timestamp du début et créer une vue (ou une requête préparé) qui va calculer à partir du timestamp la nouvelle valeur.

Exemple pour les PV
Citation :SELECT pv_origine*POW(1.01,(UNIX_TIMESTAMP()-timestamp) DIV (15*60)) as nouveau_pv FROM table WHERE id=%d
Ici on a bien une augmentation de 1% des points de vie toutes les 15 minutes.

Donc l'idée c'est de faire le calcul à la lecture (quand on en a besoin) et pas de le faire toutes les 15 minutes.

Ensuite çà ne t'empêche pas de faire un update lorsqu'il y a un évènement particulier qui va par exemple retirer des pv. Dans ce cas, tu indiques la nouvelle valeur et tu mets à jour le timestamp.


RE: Gestion des enchantements et autres effets sur la durée - keke - 15-07-2010

Ho, ça me rappelle un développement de Magdales ... table effet/effet en cours/type effet.

Une des autres problématique que tu vas rencontrer je pense, c'est "la conjoncture de l'espace-temps des jeux en tour par tour". Je vais t'exposer la problèmatique, et ensuite, la méthode que j'ai trouvé pour essayer de corriger ce problème.


Dans les jeux en tours par tours, chaque joueurs disposent d'un capital temps (appelle ça points d'actions, PA, nombre de tours, etc.). Dans Magdales, les donjons sont sombres. Il est possible d'éclairer à l'aide de torches. Les torches ont une durée limitée à quelques heures. Cela correspond dans le jeu admettons à 150 tours (réellement c'est tiré entre 120 et 180 tours au moment où la torche est fabriquée).
1er cas :
Un joueur A ayant 310 tours de jeu allume la torche. Il marche et fait des combats. lorsqu'il arrive à 160 tours, la torche s'éteind il est plongé dans le noir.

2eme cas :
Une équipe de 2 joueurs : B et C ont aussi 310 tours de jeu. B allume sa torche. C profite de la lumière et joue ses 310 tours bien éclairé.
Paradox spoted :
- Comment se fait-il que C puisse jouer 310 tours alors qu'une torche ne fonctionne que 150 tours ?
- Quid du cas ou B arrête de jouer la torche à la main ?

3eme cas :
Une équipe de 2 joueurs : D et E ont aussi 310 tours de jeu. D allume sa torche et joue tous ses tours. La torche s'éteind au bout de 150 tours ...
Paradox spoted :
- comment se fait-il que E n'ai pas pu jouer 150 tours en pleine lumière alors que la torche a bien été allumée ?


On comprend qu'il y a un certain malaise qui au mieux avantagerait certains joueurs, au pire générait de la frustration.
L'idéal serait de faire un jeu où toutes les actions sont consignées avec un horaire bien défini. Chaque joueur serait dans son univers et, lorsqu'il ne joue pas, le temps serait figé. Cela (dans mon cas) nécessiterait de tout reprogrammer. Deplus, le jeu deviendrait très compliqué : 2 joueurs qui souhaiteraient échanger de l'équipement devraient se retrouver dans le même temps In game et Out game.
Je n'ai pas retenu cette solution (qui, je pense est la seule véritable solution qui puisse appréhender tous les problèmes des effets).

La solution que j'ai retenu n'est pas la plus évidente et ne résout pas tous les cas tordus. J'ai préféré considérer les effets selon plusieurs voies :
1°/ Tout effet est limité en temps et en point d'action.
Ainsi si j'allume ma torche qui dure 150 tours, je sais que dans 12h30 (1 tours = 5 minutes dans le jeu => 150 tours = 12h et demi) au plus tard, ma torche sera consommée entièrement. Peut importe que j'use mes tours ou non. (je regarde ma montre il est 11h00, la torche sera consommée à 23h30)
Si j'utilise mes tours, alors la durée maximale diminue en proportion.
Exemple : 5 minutes après, j'ai consommé 100 tours. La torche sera maintenant consommée dans 50 tours soit 4h10.(je regarde ma montre, il est 11h05, la torche sera consommée à 15h15)

==> Pourquoi ? Si le temps ne rentre jamais en jeu, alors on pourrait fabriquer des joueurs qui serviraient de phares perpétuels...

2°/Autant d'effets que d'espace temps (dans la sphère d'influence).
Ca peut sembler bizarre, mais lorsqu'on allume une torche, j'offre un bonus de vision aux joueurs à proximité. Ces effets sont liés à un effet père et sont limités en temps et en action.
Si l'effet père disparait (le joueur qui a allumé la torche est mort, ou s'il change de lieu), on soustrait le nombre de point d'action restant au père à tous ses fils et on recacul le temps restant.
Exemple :
D et E sont dans le donjon. D allume sa torche. les joueurs D et E ont donc maintenant un effet de vision qui dure 150 tours. Il existe un effet père sur la torche. D souhaite jouer tous ses tours ... mais meurt au bout de 100 tours. La torche tombe et s'éteind. Il reste donc 50 tours à la torche. Avant de détruire l'effet père, on reporte le nouveau délais au joueur E qui ne disposera finalement que d'un effet de vision durant 100 tours.

A noter que ce point 2 peut aussi fonctionner si le joueur quitte la pièce, le donjon ... En fait, dès qu'il sort de la sphère d'affluence de l'effet père.

3°/Noter des dates de fin d'effet plutôt que des durées restantes.
En effet, au niveau calcul, les durées restantes se décrémentent à chaque secondes ... ce qui peut générer des monstres de calcul selon le nombre de joueur et d'effet.
Si tu notes une date de fin d'effet, tu te soustrais de ces calculs, et il est très facile de connaitre la durée restante à chaque instant.

Je pense t'avoir fait part de quelques mois de réflexion personnelle sur le sujet ...

Je pourrais te parler des effets génériques, des effets complexes, des catalogues d'effets de Magdales ^^.

Bon courage à toi. Le dév est assez long, mais lorsqu'on arrive au bout ... quel soulagement Smile

kéké


RE: Gestion des enchantements et autres effets sur la durée - PommeCassis - 15-07-2010

Merci beaucoup à vous pour vos conseils et réflexions personnelles !

Donc le mieux serait de se baser sur des timestamps pour la fin des effets et pour le rafraichissement uniquement lorsque c'est nécessaire.

Lorsqu'un joueur se connecte par exemple, la zone autour de lui est rafraichie dans le cas où 1 tour ou plus est passé dans la zone depuis le dernier rafraichissement.
1) On cherche tout d'abord les effets périodiques provoquant des pertes/gains de PV, PM et PA (poison, Hâte, etc..)
2) On attribue les nouveaux PV, PM et PA en prenant en compte la génération passive et les effets s'additionnant
3) On regarde tout les effets et on supprime ceux qui n'ont plus raison d'être
4) Mise en cache des cases et ce qui se trouvent dessus

Et cela à chaque rafraichissement.
Problème : les effets pourraient se terminer à n'importe quel moment. Une solution simple pour éviter de déterminer à chaque rafraichissement si l'effet est terminé, serait de faire en sorte que la durée soit en tour. Dans ce cas il faudrait diminuer la durée d'un tour pour avoir un peu plus de précision dans la durée des effets.

Je sais pas si tout ça est très clair ou si ça semble juste, je vais essayer de faire un petit MPD sous MySql Workbench pour voir si ça peut aller. Si vous avez envie de donner un bref avis dessus ça m'aiderait bien.

Citation :Bon courage à toi. Le dév est assez long, mais lorsqu'on arrive au bout ... quel soulagement
Merci, effectivement il y a du boulot Je sais pas si j'en verrai le bout un jour, on verra bien Smile

En tout cas merci beaucoup, ça m'a beaucoup aidé.