JeuWeb - Crée ton jeu par navigateur
Modelisation de données - 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 : Modelisation de données (/showthread.php?tid=7888)

Pages : 1 2


Modelisation de données - Air - 26-10-2017

Bonjour,

Je me pose encore des questions sur une partie modélisation.
Un personnage peut suivre un cursus d'apprentissage.

J'ai donc un curseur pilotage, curseur militaire, cursus scientifique et cursus commercial.
Chaque cursus dispose de plusieurs niveaux et souhaite modéliser le fait que le perso suit ou pas un niveau de cursus.

Donc j'ai une table perso cursus avec les champs suivants :
id_perso ; pil, mil ; sci; comm
10 ; 0 ; 1 ;2 ; 0

et pour modéliser qu'un cursus est en cours, une table :
id_perso ; cursus
10 ; mil

Ce qui signifie que le cursus militaire niveau 3 est en cours d'apprentissage.

Sinon je pourrais aussi dans ma table initial perso cursus, rajouter 4 champs pil_encours;mil_encours;sci_encours;comm_encours
id_perso ; pil, mil ; sci; comm ; pil_encours;mil_encours;sci_encours;comm_encours
10 ; 0 ; 1 ;2 ; 0 ; 0 ; 1; 0 ; 0

et dernière solution rajouter un seul champs dans perso cursus qui est une concaténation des 4 champs. On aurait donc :
id_perso ; pil, mil ; sci; comm ; Encours
10 ; 0 ; 1 ;2 ; 0 ; 0100

Le digit 1 en 3ème positions signifie que le cursus militaire est en cours.

J'aime bp cette dernière solution mais je ne parviens pas à comprendre ce qui me plait dans celle-ci sinon que je ne dispose que d'une seule table et je n'ai pas des 1 champ supplémentaire par cursus.

J'aimerais solliciter votre avis sur ces différentes solutions. Comment de votre côté vous implémenteriez cette problématique ?

Merci pour votre avis avisé Smile


Ajout : je viens de trouver le mot que je cherchais : J'aime bp cette dernière solution mais je ne parviens pas à comprendre. En faite je voulais dire que cette solution me paraît "élégante".


RE: Modelisation de données - niahoo - 27-10-2017

Hello,

Ta dernière solution effectue une sérialisation/dé-sérialisation pour enregistrer/lire l'information. À ce compte là, tu peux y mettre du Json, par exemple {"mil": 2, "mil_encours": 3, "sci": 2, ...}.

Ensuite, vu comment tu fais, on comprend qu'il faut avoir le niveau 2 pour apprendre le 3, ça sert à rien de socker ces deux infos : mil et mil_encours.

Tu peux opter pour un nombre décimal : le champ mil valant 2.56 indique qu'on a le niveau 2 et qu'on est à 56% du 3. Si tu fais des jointures ou des stats sur ce champ, les nombres flottants sont peut-être pas top pour les performances et l'écriture du SQL ; Xenos t'en dira peut-être d'avantage là dessus.

Et si tu ne fais pas de jointure, alors tu peux opter pour une concaténation (ou une structure JSON — encore mieux sur PostgreSQL). Mais c'est pas grave d'avoir plein de champs, surtout que tu as fait une table exprès au lieu de les mettre dans la table du personnage. Sur PostgreSQL tu pourrais aussi opter pour un seul champ de type tableau, par exemple, à voir si c'est justifié.

Tu n'as pas montré comment tu stockais la progression vers le prochain niveau. Je suppose qu'on n'achète pas les niveaux instantanément puisque tu veux stocker un min_encours. Au lieu d'y stocker le prochain niveau (qu'on trouve facilement en faisant mil + 1), tu devrais y stocker la progression.

La prochaine étape serait de simplement stocker les points d'expérience militaire, par exemple 3 584, et avoir dans ton code une formule qui donne le niveau à partir des points. Et d'avoir un champ comme ça et une formule de calcul pour chaque cursus.

Regarde ce topic : https://www.jeuweb.org/showthread.php?mode=linear&tid=9117&pid=116701 (mais c'est dommage car les maths me semblent un peu velus à cette heure tardive). Tu peux trouver des formules de calcul de niveau selon différents méthodes.


RE: Modelisation de données - Xenos - 27-10-2017

Salut,

tu peux y mettre du Json
Si et seulement si ce JSON est proprement géré par la BDD, ce qui veut dire compris par la BDD (MySQL 5.7+ par exemple) et correctement indexé ou jamais recherché, et correctement sérialisé/désérialisé lors de la communication avec la BDD (ie: pour PHP+PDO+MySQL, tu vas tevoir te tapper un json_decode côté client + la lourdeur du transfert éventuel entre MySQL et PHP).

Le décimal est une solution risquée, car je ne suis pas certain que les calculs dessus seront exacts (est-ce que "niveau 7.56 + 0.44 = 8.0 pile poil" pour dire que le niveau est fini? pas sûr). Les jointures, OSEF très certainement vu la quantité de données en jeu (cela serait Facebook, je ne dis pas).

Perso, je n'aurai pas du tout posé les mêmes questions que Niahoo. La première question à se poser c'est:
Est-ce que les cursus sont des données, ou de la structure?

Tes cursus sont des données si tu peux/veux en rajouter "à la volée", sans modifier la logique générale du jeu, ou éventuellement si tu en as une bonne dizaine. Dans un tel cas, il doit exister une table "Cursus: INT id, VARCHAR label" listant les cursus (1, "MILITAIRE"; 2, "PILOTAGE"; ...). Tu auras alors une table "joueur_cursur: INT id_joueur, INT id_cursus, INT level, BIT(1) est_en_cours" et éventuellement, une colonne "XP" ou "progression" si nécessaire. Si une et un seul cursus n'est faisable à la fois, un "UNIQUE INDEX id_joueur, est_en_cours" peut se faire, en rendant est_en_cours NULLABLE (ie: 1 = en cours, NULL = pas en cours). L'unicité de l'index assurera qu'un seul cursus par joueur sera à 1.

Sinon, tes cursus sont de la structure si chacun vient avec un lot de règles spéciales, et que l'ajout d'un cursus est (par définition du gameplay et de l'existence de ces règles spéciales) une opération lourde; le nombre de cursus doit également être limité (là, 4, c'est largement assez OK). Si tes cursus sont une structure, alors leur "ajout à la volée" n'est pas nécessaire, et on peut faire des tables plus "lourdes" mais plus simples à manipuler, type:
INT id_joueur, ENUM ("MILITAIRE", "PILOTAGE",...) en_cours, INT lvl_militaire, INT lvl_pilotage, INT lvl_commercial; INT lvl_scientifique
L'ENUM peut être nullable si un joueur peut ne suivre aucun cursus. Une colonne "progression" (FLOAT ou TINYINT) peut être rajoutée si la notion de progression est requise pour le cursus en cours.
Dans tous les cas, le JSON et la sérialisation, heu, non. Ta colonne "0100", une colonne binaire sérialisante comme soulevé à juste titre par Niahoo, n'est pas une bonne solution car elle n'assurera pas l'unicité du cursus suivit (la valeur 0101 sera possible, la seule solution, c'est de bombarder de TRIGGER...). Pour JSON, même problème au niveau de l'unicité du cursus suivit.

Et nota: tous les ne pouvant avoir de valeur négative peuvent être UNSIGNED. Je te laisse placer les autres index comme il faut.


RE: Modelisation de données - niahoo - 27-10-2017

Attention, il n'a pas dit qu'on ne pouvait suivre qu'un cursus à la fois. Le Json ne peut pas avoir de clés dupliquées, il n'y a pas de problème d'unicité.


RE: Modelisation de données - Xenos - 27-10-2017

Citation : Un personnage peut suivre un cursus d'apprentissage.
Que je lis (peut-être à tort), comme "le joueur suit un cursus d'apprentissage max à la fois" (et je considère qu'éventuellement, 0 cursus suivi est possible, lorsqu'on a terminé un cursus et qu'on veut en entamer un autre).

Code :
{"mil": 2, "mil_encours": 3, "sci": 2, ...}.

Donc {"mil": 2, "mil_encours": 3, "sci": 2, "sci_encours": 3 ...} passe, et n'assurera pas qu'on suive un et un seul cursus (en suivant ce que j'ai compris précédemment). Sans compter les erreurs possibles type {"mil": 2, "mil_encours": 4 ou 2 ou 0.5 voire -1 ou "x", "sci": 2, ...}.

JSON, pour le stockage, cela va bien quand on a la flemme (dans les minis-jeux, si je voulais sauver l'avancement du joueur côté serveur, un bon gros JSON suffirait) ou quand vraiment tout l'objet (toutes ses propriétés) sont des données et non de la structure (y compris dans le temps, ie la structure évolue trop vite pour pouvoir la poser clairement en colonnes) ou éventuellement quand on se tape le stockage d'arbres (débattable) ou quand on a besoin de checks trop complexes pour les faire classiquement (et qu'un recours à TRIGGER + JSON est donc indispensable; perso, je n'ai jamais vu ce cas).
Par exemple, si la notion même de cursus était une donnée, c'est à dire que le gameplay serait "le joueur peut [insérer verbe] autant de [insérer nom] qu'il veut", et les cursus n'en sont qu'un sous-genre parmi des tas.

Pour moi, c'est comme cela qu'on modélise "bien" les choses (de manière intègre, réaliste, maintenable, rapide et utilisable).


RE: Modelisation de données - niahoo - 27-10-2017

La règle de 1 cursus max n'est pas établie, ça sert à rien de digresser dessus. « Sans compter les erreurs possibles type {"mil": 2, "mil_encours": 4 ou 2 ou 0.5 voire -1 ou "x", "sci": 2, ...} » : je dis 2 lignes en dessous que c'est pas intelligent de stocker ça comme ça, ça n'a aucun rapport avec le fait de sérialiser ou non.

Par contre la notion de cursus est clairement une donnée.


RE: Modelisation de données - Air - 27-10-2017

Merci pour l'ensemble de vos retours. J'avoue n'avoir pas tout compris.
Je crois avoir mal décris (une fois n'est pas coutume) les règles.

Un personnage ne peux suivre qu'un seul niveau d'un cursus à la fois.
Exemple , le cursus pilotage est composé des niveaux 1, 2, 3.. le cursus militaire des niveaux 1,2,3,4,5
Un niveau dure 1 année (dans le jeu). Je décide en tant que joueur débutant de suivre le niveau 1 pilotage. Pendant cette année d'apprentissage, je ne pourrais pas suivre d'autre cursus. A la fin de l'année, je passe un examen qui valide ou pas le niveau.
Admettons que je valide, je décide de suivre un autre cursus. Commerce Niveau 2 (car j'ai déjà le niveau 1) et c'est reparti pour une année d'apprentissage.

Pour reprendre :
id_perso ; pil, mil ; sci; comm ; Encours
10 ; 0 ; 1 ;2 ; 0 ; 0100

'En cours' ne pourra avoir qu'un seul 1 à un moment donnée. Les champs pil, mil , sci et comm sont là uniquement pour donner le niveau d'étude actuel.


RE: Modelisation de données - niahoo - 27-10-2017

OK ben dans ce cas la la solution de Xenos avec l'ENUM me semble la plus simple.


RE: Modelisation de données - Xenos - 27-10-2017

Citation :Pendant cette année d'apprentissage
Je ne sais pas si on peut prendre le cursus en cours d'année de jeu (aka ne pas le démarrer le 1er janvier, mais le 20 Juin par exemple), mais si on le peut, alors il te faudra savoir à quelle date (in game) le joueur a commencé ce cursus (sinon, tu ne sauras pas quand le joueur a passé 1 an sur ledit cursus). Cette date te permettra de calculer une progression aussi, si besoin (qui se résume à (Date actuelle ingame - Date de début de cursus)[en jours] / 365 * 100, pour l'exprimer en %).
Nota que tu peux, au lieu d'enregistrer la date de début du cursus, sauver la date de fin, aka si un joueur démarre son cursus le 21/01/2010 dans le jeu, tu peux soit sauver cette date de début, et fixer que "date de début + 1 an" = "date de fin", soit stocker la date de fin uniquement.

Citation :'En cours' ne pourra avoir qu'un seul 1 à un moment donnée
D'où ma proposition d'ENUM, car là, tu ne peux pas assurer cette condition avec une colonne MySQL sans recourir à du TRIGGER (ce ne serait pas non plus faisable avec 4 colonnes booléennes).

S'il y a des points que t'as pas compris, n'hésite pas (perso, quand je lis quelque chose, j'aime reformuler pour voir ce que j'ai compris).


RE: Modelisation de données - niahoo - 27-10-2017

Comment se passe le passage d'examen à la fin de l'année ?