Design BDD & PHP pour association/rareté objets type MMORPG

Eléphant du PHP | 73 Messages

28 août 2012, 13:33

Bonjour

Je récolte en ce moment quelques infos pour la création d'un jeu de type MMORPG en ligne.
Je connais les principes de base des bdd relationelles, mais j'ai du mal à comprendre comment je pourrais mettre en place certaines choses donc j'aimerais vos lumières.

Dans un jeu de type RPG/MMORPG, il y a ces concepts :

- le joueur drop des objets (sur des monstres, suite à des quêtes etc.)
- ces objets peuvent être uniques (fixes, prédéfinis), ou randoms (stats générées aléatoirement à partir d'un générateur d'objets j'imagine).
- un même objet (même stats, objets uniques donc) peut appartenir à plusieurs personnes
- n'importe quel objet est échangeable (changement de propriétaire)
- suivant le type de monstre (ou quête) tué, la qualité de l'objet augmente etc.

j'aimerais implémenter donc ce concept dans mon supposé jeu, mais j'ai du mal à comprendre comment je peux mettre en forme tout cela.

je comprend le principe de la création d'un objet et de ses stats, l'allocation à une personne ou plusieurs etc.. (avec les relations c simple à mettre en place), mais j'ai du mal à concrétiser la partie sur les objets random/uniques etc. et les proprios.

quelqu'un pourrait-il m'expliquer brièvement comment je pourrais mettre cela en place dans la base et dans le PHP

pour plus de simplicité, je vais mettre un exemple "très simplifé" de tables et relations de comment j'imagine le truc, je suis ouvert à tout conseil/critique :

dans l'exemple, j'envisagerais plusieurs tables du genre :

- item (contenant les items)
- item_types (contenant le type d'item, unique ou random)
- lien_personnage_item (qui fait le lien plusieurs/plusieurs entre les items et les cha
- monstre

on envisagerais donc :

table "item" avec par exemple :

item_id id de l'item
item_type clef étrangère sur la table item_types
item_name nom de l'item
item_level niveau de l'item
item_bonus_str bonus de force
item_bonus_int bonus d'intel
item_bonus_vit bonus de vitalité
item_bonus_N bonus N (on peut en imaginer plein)

a moins qu'il faille que je mette les bonus dans une table séparée et faire des liens ? j'ai du mal à voir comment gérer ça

table "item_types" :

type_id
type_name

table "personnage" :

personnage_id
personnage_name
personnage_level
personnage_statX
personnage_statX
personnage_statX
etc..

table "lien_personnage_item"

item_id
personnage_id

table "monstre"

monstre_id
monstre_level
monstre_name
monstre_statX
monstre_statX
monstre_statX

1. alors ma question déjà sur ce petit truc de base, est-ce que quelque-chose du genre vous semble correct ?
2. d'après vous, faut-il mettre les stats dans des tables séparées ? (par exemple pour faire des groupes de stats etc. pour les monstres identiques par exemple) et si oui, comment ?
3. comment puis-je gérer le fait que le personnage ait des items sur lui et aussi dans son sac ? dois-je simplement rajouter un champ dans la table de relation (colonne genre type_item étant sac ou perso ?)
4. c'est pareil, vaut-il mieux mettre les stats de base du perso (de la classe), et générer 'in-game' (dans le PHP) les stats finales du personnage avec les items qu'il porte ? ou les mettre en base ? (car j'aimerais implémenter la notion de dureté de l'item etc. aussi)

ensuite, comment gérer le fait :

- qu'un monstre puisse laisser tomber tel tel ou tel item "unique" ? on crée une colonne dans la table monstre contenant tous les ID des objets uniques qu'il peut dropper ? (et dans le PHP on fait une fonction de random avec pourcentage de chance de dropper un des items de la liste ?)

- je peux faire un générateur d'items dans le PHP qui créerait aléatoirement des items dans la base (fait à la volée lors du jeu), mais ceci est-il classique ? est-ce que cela se fait comme ça ?

- pour gérer le changement de prorpiétaire d'objets, d'après vous, il suffit de changer les entrées dans la table lien_personnage_item ? tout simplement ?

y-a-t"il des best practices pour tout cela ? ou est-ce que je me trompe complètement ?

merci :)

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

29 août 2012, 14:05

salut,

pour te répondre simplement :
- Des bonnes pratiques, oui y 'en a même plein, comme les formes normales SQL, et le modèle entité association de merise.
- Tu peux faire une modélisation UML de ton application, en suvant, par exemple la démarche de Craig Lerman (google pour plus d'info). il y en a surement d'autre
- Pour finir une image c'est plus parlant que le reste donc voici un modèle rapide qui pourrait convenir (je ne dit pas qu'il est ultime ;) ).

Image

pour les stats aléatoire un select sur la table des stats (avec mysql un order by rand + un limit et c'est fait ;) ). ensuite tu créer un nouvel item et tu l'ajoute à la table des items et ensuite ajoutes les entrées correspondante dans la table statItem.

Tu peux très bien créer une procédure stockées pour le faire (sur le principe je dirais même conseiller, ça rend la chose plus simple si tu modifie le modèle plus tard ;)).
Il faut que tu fasse attention à ne pas créer de doublon dans la base.

Avec ça tu a déjà de quoi un peu mieux, et surement affiner ton modèle, compléter le mien ou en faire un nouveau ;)



@+
Il en faut peu pour être heureux ......

ViPHP
ViPHP | 3300 Messages

30 août 2012, 10:53

Y'a un truc que j'ai toujours trouvé hérétique dans Merise c'est d'avoir un table Membre et d'avoir le champ de clef de cette table s’appeler idMembre, et de répéter la chose un peu partout, pour moi on devrait l’appeler id dans sa propre table et éventuellement idMembre en tant que clef étrangère ailleurs.

c'est beaucoup plus objet, pose 0 problèmes fonctionnels dans tous les SGBD que je connais...

Aussi c'est une bonne pratique d'historiser les données des tables avec des champs (creation_date, modification_date, removal_date, removed) et éventuellement de relier les mêmes informations à un compte user, ça offre de la traçabilité, et vaut mieux le prévoir à l'origine qu'à la fin, aussi il vaut mieux gérer une suppression au niveau du code que du sgbd, pour l'intégrité de la base c'est souvent mieux en fait.
Fait du php depuis que ca existe ou presque :)

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

30 août 2012, 13:25

Y'a un truc que j'ai toujours trouvé hérétique dans Merise c'est d'avoir un table Membre et d'avoir le champ de clef de cette table s’appeler idMembre, et de répéter la chose un peu partout,
Effectivement mais :
- dans une requête sur plusieurs tabletu peux te mélanger les pinceaux avec les "id" qui viennent de toutes part et tu finis par faire des alias => paf idMembre :)
- Perso j'utilise using pour faire mes jointures et la ben si ta clef primaire se nomme aussi id c'est cramé ( select .. from table1 join table2 using(idMembre)) en lieu et place du truc.id = machin.idTruc

au total j'écris moins de chose et je m'y retrouve.

mais c'est vrai qu'a partir du moment il s'agit que de l'entité elle même on n'a pas vraiment de la nommer ainsi, c'est juste une question de "confort" pour moi ensuite ;)

L'historisation effectivement, ça peux être pratique, mais la pour le coup j'ai fait "simple" j'y ai même pas pensé.

aussi il vaut mieux gérer une suppression au niveau du code que du sgbd, pour l'intégrité de la base c'est souvent mieux en fait
La je ne suis que partiellement d'accord, ça peux être vrai si tu n'a qu'un soft qui utilise ta base.

Cela ne le devient plus lorsque tu a plusieurs soft qui l'utilise, il faudrait être certain que tous utilise la même politique.

Le contrainte d'intégrité réduise pas mal de soucis, mais la procédure pour le faire est pratique, ceci bien entendu si elle est la seul à effectuer des suppressions :mrgreen:

bon la c'était surtout pour la création, ça évite un appel sur les stats (même avec un limit) + une requête qui vérifie si l'item n'existe pas déjà + l'insertion dans la table. Et potentiellement en boucle si on à pas de bol :d.
Avec une procédure un seul appel, le sgbd fait autant de requête qu'il veux ce sera plus rapide qu'avec les aller - retour sur le réseau.

Perso je ferais tourner ça une bonne fois pour toute histoire d'avoir pas mal d'items existants et ensuite un order by rand limit 1 sur cette table ^^ (bon vu la chose je suppose qu'il va y avoir des critère de 'niveau' et tout qui vont complexifier la chose :)

Bref je pense qu'au globale c'est plus une habitude qu'autre chose, je ne sais pas s'il y a vraiment des bonnes pratiques entre mettre toute la logique métier dans des procédures sur le SGBD et tout faire dans le code :mrgreen:


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 73 Messages

30 août 2012, 13:31

Salut,

Merci à vous pour vos réponses, et merci pour l'exemple concret moogli c'est sympa, je comprend bcp mieux.
je n'ai pas la connnaissance UML/Merise requise pour tout lire proprement peut-être (je vais aller lire quelque docs dessus..), mais malgré ton schéma, j'ai du mal à comprendre comment tu gère concrètement l'association par exemple des stats des personnages ?

sur ton ER je vois deux tables par exemple (personnages & stats), mais aucune clef en commun ?
ton lien "statperso" doit se gérer à l'aide d'une table de relation également ? (ou même plusieurs)

en tout cas ton schéma est très clair et très logique, c'est pratique d'avoir cette vue modélisée (tu modélise avec un programme particulier ?), j'étais habitué à modéliser des petits MCD de base, mais n'ai jamais pensé à le faire en UML/Merise, ne connaissant pas la technique, c'est très intéressant.

mais si ce n'est pas trop demander, pourrais-tu m'éclairer simplement en me donnant un exemple de cette relation personnage/stats (ou mobs/stats par exemple).

après, pour les relations du type sac -> items, tu fais une relation de base ? par exemple dans la table 'items', on crée une colnone idSAc ? et on s'occupe de la relation manuellement ? (ex : WHERE items.idSAc = sacs.idSAc ?)

merci encore

cdt,

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

30 août 2012, 14:00

de rien :)


ce que tu ne comprend pas est ce qu'il te manque pour lire le sshéma :)

ce qu'il faut comprendre dans ce schéma c'est que l'on parle d'entité (les tables c'est plus tard).
Qu'est ce qu'une entité, c'est la représentation de quelque chose de "réel" par exemple un personnage est une entité. le modèle entité relation (de la méthode merise) représente donc les relations entre les entités (qui sont nommées au mieux avec des verbes, créer, appartient etc etc, c'est pas toujours facile comme mon schéma l'indique :) ).

Ensuite viens le passage du modèle aux tables.
Tu as remarqué qu'il n'y avait pas de référence aux autres tables dans le schéma, normal elle ne définissent pas l'entité, et sont indiqué par les relations.
Les règles de passage sont indiquées dans des cours ;)

Par exemple sur développez.com il y a une section merise.

en fait les relations que tu vois ne sont pas forcément de simple clef étrangère, il peux s'agit de table.
C'est cas lors d'une relation n - n par exemple.

dans le cas de la relation peso / stat il s'agit de fournir des stats à des personnages. sachant qu'un personnagepeux avoir une pour plusieur stats (1,n) et qu'une stat peux être utilisée par zéro ou n perso (0,n).

la relation "globale" c'est n, n. cette relation sera traduite par une table très simple (idperso,idStat) (avec les deux champs en clef primaire).
maintenant dans la relation j'ai ajouté une valeur (histoire que la stat puisse changer, par exemple quand tu prend un niveau. la table devient donc (idperso,idStat, valeur), la clef primaire est toujours le couple (idperso,idStat) .

c'est la même chose pour les stats des mobs ou des items :)

pour ce qui est des sac, c'est pareil un personnage peux avoir de 1 à n sac et un sac peux contenir de zéro à n items.
Dans le schéma on pourrait ajouter, dans l'entité sac, le nombre d'élément max que le sac peux contenir (pratique ;) ).
donc au final il y aura un table sacs avec (idSac, numéro, idPerso)
par contre la relation contient va être une table (idSac,idItem).

j'ai fait simple, tu peux avoir une table avecdes sac type (qui au final ne seront que des items avec un stat nbslot par exemple) dans ce cas ta table sacs aura deux relatio avec items
une relation pour le type de sac et une pour la contenance.
La première se traduit par une clef étrangère dans la tables sac et la second toujours pas une table (idSac,idItems).



J'espère être clair, mais je ne suis pas certain :)

pour le schéma j'ai utilisé JMesire, fait en java, il est gratuit, assez limité mais fait ce dont on a besoin a la base : le MCD (et le vérifie), leMPD et le passage vers le code SQL. Limité à mysql mais il fait du code relativement portable pas trop complexe à modifier.

Il ne fait pas toujours des trucs qui me plaise (mais vont dans le sens de ce que disait Nagol sur le dénomination des clef primaire :)

sinon le meilleur que j'ai pu tester (pour moi) c'est power AMC (de sybase) par contre pas gratis, mais tu peux tester 15J si tu veux regarder la chose.

par exemple il donne le script suivant (dans lequel j'ai ajouté le type de sac et nombre de slot dans le sac).
Je ne l'ai pas vérifier, c'est qu'un exemple :)
DROP TABLE IF EXISTS membres;
CREATE TABLE membres(
        idMembre     Auto_increment (25),
        nom     Varchar (25),
        email     Varchar (255),
        passwd     Varchar (256),
        PRIMARY KEY (idMembre)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS personnages;
CREATE TABLE personnages(
        idPerso     Auto_increment (25),
        pseudo     Varchar (25),
        idMembre_membres     Auto_increment (25),
        idRace_races     Auto_increment (25),
        idRace_classes     Auto_increment (25),
        PRIMARY KEY (idPerso)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS races;
CREATE TABLE races(
        idRace     Auto_increment (25),
        nomRace     Varchar (25),
        description     Varchar (500),
        PRIMARY KEY (idRace)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS items;
CREATE TABLE items(
        idItems     Auto_increment (25),
        nomItem     Varchar (50),
        idQualite_qualite     Auto_increment (25),
        PRIMARY KEY (idItems)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS stats;
CREATE TABLE stats(
        idStat     Auto_increment (25),
        nomStat     Varchar (25),
        description     Varchar (150),
        PRIMARY KEY (idStat)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS mobs;
CREATE TABLE mobs(
        idMob     Auto_increment (25),
        nomMob     Varchar (25),
        idRace_races     Auto_increment (25),
        idRace_classes     Auto_increment (25),
        PRIMARY KEY (idMob)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS classes;
CREATE TABLE classes(
        idRace     Auto_increment (25),
        nomRace     Varchar (25),
        description     Varchar (150),
        PRIMARY KEY (idRace)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS sacs;
CREATE TABLE sacs(
        idSAc     Auto_increment (25),
        numeroSac     Int (2),
        nbSlot     Int (2),
        idPerso_personnages     Auto_increment (25),
        idItems_items     Auto_increment (25),
        PRIMARY KEY (idSAc)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS qualite;
CREATE TABLE qualite(
        idQualite     Auto_increment (25),
        nom     Varchar (25),
        PRIMARY KEY (idQualite)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS statItem;
CREATE TABLE statItem(
        valeur     Int (25),
        idItems_items     Auto_increment (25),
        idStat_stats     Auto_increment (25),
        PRIMARY KEY (idItems_items,idStat_stats)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS itemsPorté;
CREATE TABLE itemsPorté(
        idPerso_personnages     Auto_increment (25),
        idItems_items     Auto_increment (25),
        PRIMARY KEY (idPerso_personnages,idItems_items)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS statMob;
CREATE TABLE statMob(
        valeur     Int (25),
        idMob_mobs     Auto_increment (25),
        idStat_stats     Auto_increment (25),
        PRIMARY KEY (idMob_mobs,idStat_stats)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS itemMob;
CREATE TABLE itemMob(
        idItems_items     Auto_increment (25),
        idMob_mobs     Auto_increment (25),
        PRIMARY KEY (idItems_items,idMob_mobs)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS statPerso;
CREATE TABLE statPerso(
        valeur     Int (25),
        idPerso_personnages     Auto_increment (25),
        idStat_stats     Auto_increment (25),
        PRIMARY KEY (idPerso_personnages,idStat_stats)
)ENGINE=InnoDB;

DROP TABLE IF EXISTS contient;
CREATE TABLE contient(
        idSAc_sacs     Auto_increment (25),
        idItems_items     Auto_increment (25),
        PRIMARY KEY (idSAc_sacs,idItems_items)
)ENGINE=InnoDB;

ALTER TABLE personnages ADD CONSTRAINT FK_personnages_idMembre_membres FOREIGN KEY (idMembre_membres) REFERENCES membres(idMembre)
ALTER TABLE personnages ADD CONSTRAINT FK_personnages_idRace_races FOREIGN KEY (idRace_races) REFERENCES races(idRace)
ALTER TABLE personnages ADD CONSTRAINT FK_personnages_idRace_classes FOREIGN KEY (idRace_classes) REFERENCES classes(idRace)
ALTER TABLE items ADD CONSTRAINT FK_items_idQualite_qualite FOREIGN KEY (idQualite_qualite) REFERENCES qualite(idQualite)
ALTER TABLE mobs ADD CONSTRAINT FK_mobs_idRace_races FOREIGN KEY (idRace_races) REFERENCES races(idRace)
ALTER TABLE mobs ADD CONSTRAINT FK_mobs_idRace_classes FOREIGN KEY (idRace_classes) REFERENCES classes(idRace)
ALTER TABLE sacs ADD CONSTRAINT FK_sacs_idPerso_personnages FOREIGN KEY (idPerso_personnages) REFERENCES personnages(idPerso)
ALTER TABLE sacs ADD CONSTRAINT FK_sacs_idItems_items FOREIGN KEY (idItems_items) REFERENCES items(idItems)
ALTER TABLE statItem ADD CONSTRAINT FK_statItem_idItems_items FOREIGN KEY (idItems_items) REFERENCES items(idItems)
ALTER TABLE statItem ADD CONSTRAINT FK_statItem_idStat_stats FOREIGN KEY (idStat_stats) REFERENCES stats(idStat)
ALTER TABLE itemsPorté ADD CONSTRAINT FK_itemsPorté_idPerso_personnages FOREIGN KEY (idPerso_personnages) REFERENCES personnages(idPerso)
ALTER TABLE itemsPorté ADD CONSTRAINT FK_itemsPorté_idItems_items FOREIGN KEY (idItems_items) REFERENCES items(idItems)
ALTER TABLE statMob ADD CONSTRAINT FK_statMob_idMob_mobs FOREIGN KEY (idMob_mobs) REFERENCES mobs(idMob)
ALTER TABLE statMob ADD CONSTRAINT FK_statMob_idStat_stats FOREIGN KEY (idStat_stats) REFERENCES stats(idStat)
ALTER TABLE itemMob ADD CONSTRAINT FK_itemMob_idItems_items FOREIGN KEY (idItems_items) REFERENCES items(idItems)
ALTER TABLE itemMob ADD CONSTRAINT FK_itemMob_idMob_mobs FOREIGN KEY (idMob_mobs) REFERENCES mobs(idMob)
ALTER TABLE statPerso ADD CONSTRAINT FK_statPerso_idPerso_personnages FOREIGN KEY (idPerso_personnages) REFERENCES personnages(idPerso)
ALTER TABLE statPerso ADD CONSTRAINT FK_statPerso_idStat_stats FOREIGN KEY (idStat_stats) REFERENCES stats(idStat)
ALTER TABLE contient ADD CONSTRAINT FK_contient_idSAc_sacs FOREIGN KEY (idSAc_sacs) REFERENCES sacs(idSAc)
ALTER TABLE contient ADD CONSTRAINT FK_contient_idItems_items FOREIGN KEY (idItems_items) REFERENCES items(idItems)
@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 73 Messages

30 août 2012, 14:21

merci pour ta réponse aussi rapide, je comprend mieux.

commes le entités ressemblent fortement aux tables du mcd, je pensais que l'on devait spécifier également toutes les colonnes et clefs (et donc clefs étrangères etc) dans le schéma Merise directement, donc je ne comprenais pas trop, pour moi il manquait des infos :)

merci bcp c'est plus clair une fois encore !

je vais regarder le code SQL voir si ça correspond et si ça me permet de mieux comprendre

cdt,

Eléphant du PHP | 73 Messages

30 août 2012, 16:07

Ah, une dernière chose (excuse moi je vais t'embêter) mais toujours dans l'optique des stats, il y a quelque-chose que j'ai du mal à comprendre pour le stockage des stats des items par exemple.

si je prend ton example avec ces 3 tables :

Code : Tout sélectionner

DROP TABLE IF EXISTS statItem; CREATE TABLE statItem( valeur Int (25), idItems_items AUTO_INCREMENT (25), idStat_stats AUTO_INCREMENT (25), PRIMARY KEY (idItems_items,idStat_stats) )ENGINE=InnoDB; DROP TABLE IF EXISTS stats; CREATE TABLE stats( idStat AUTO_INCREMENT (25), nomStat Varchar (25), description Varchar (150), PRIMARY KEY (idStat) )ENGINE=InnoDB; DROP TABLE IF EXISTS items; CREATE TABLE items( idItems AUTO_INCREMENT (25), nomItem Varchar (50), idQualite_qualite AUTO_INCREMENT (25), PRIMARY KEY (idItems) )ENGINE=InnoDB;

ça donnerait un truc du genre :

Code : Tout sélectionner

ITEMS EXAMPLE idItem nomItem 1 item_qui_rox 2 item_qui_sux 3 item_random

Code : Tout sélectionner

STATS EXAMPLE idStat nomStat description 1 intelligence dégats magiques 2 force dégâts physiques 3 vitalité points de vie 4 dextérité esquive et dégâts d'archerie

Code : Tout sélectionner

STATITEM EXAMPLE IDItems_items IDStat_stats 1 1 1 2 1 3 1 4
mais soit je vois mal le truc, soit c'est pas vraiment ce que je cherche :)

en fait, chaque item a des stats particulières, par exemple :

item_qui_rox pourrait donner :

intelligence +15
force +15
vitalité +50
dextérité +10

et item_qui_sux pourrait donner :

intelligence +15
vitalité +2

item_random pourrait donner :

force +5
vitalité +78
dextérité +0

comment puis-je gérer ça justement ? (en fait depuis le départ c'est sourtout ça qui me tracasse :p tu les met ou les stats ?! les valeurs du moins)

pour les stats du perso, je pense que j'aurais pas trop de mal, car je vais gérer ça in-game (suivant l'équipment que le perso va porter, j'additionne les stats à la volée dans le code, et je met ça en mémoire/session/etc.. bref, ça reste à voir), mais pour les stats d'items, c'est plus embêtant (d'ou mon idée de départ ou je voulais faire des champs pour chaque item avec bonus_intel, bonus_force, bonus_machin etc.. dans chaque item).

mais cette perspective m'embete car si on décide de rajouter une nouvelle stat du jour au lendemain (exemple : vitesse d'attaque), il faut rajouter une colonne sur tous les items de la base.

merci de tès lumières encore et de passer du temps à rédiger tout cela :)

cdt

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

30 août 2012, 23:26

mais cette perspective m’embête car si on décide de rajouter une nouvelle stat du jour au lendemain (exemple : vitesse d'attaque), il faut rajouter une colonne sur tous les items de la base.
C'est justement à ça que sert ce système :)


tu n'est pas obligé de mettre toute les stats as tout les items.

donc les données pourrait êtres
IDItems_items IDStat_stats
1 1
1 2
2 3
2 2
3 1
3 4
3 3
4 1
4 3
etc etc
Donc si tu ajoute une stat c'est pas un problème :)

Lorsque tu fera ta jointure tu n'aura que ce que tu as prévue c'est tout.

(select ... from items join stat using(idItem))


Je sais pas si mon explication est très clair, plus simple c'est que tu test et que tu te fasse une interface simple tu devrais mieux comprendre :)


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 73 Messages

31 août 2012, 15:30

oui j'ai bien compris cette partie là, sans soucis :)

ce que je ne comprend pas, c'est ou tu stocke les valeurs des items :) (les stats elles même, le +15, +38, +2 etc. listés au dessus)

merci!

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

01 sept. 2012, 00:26

CREATE TABLE statItem(
valeur Int (25), -- la :)
idItems_items AUTO_INCREMENT (25),
idStat_stats AUTO_INCREMENT (25),
PRIMARY KEY (idItems_items,idStat_stats)
)ENGINE=InnoDB;

cette table contient l'id de l'item, l'id de la stat et sa valeur.

ça permet de tout maitriser, sinon il faudrait que tu ai une stat +2 bourrinage, une + 48 bourrinnage etc etc.

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 73 Messages

04 sept. 2012, 13:06

ahhh merci j'avais pas vu, je comprend bcp mieux à présent, ça me trottait :)

en fait je me rend compte que.. cette table va être colossale en terme d'enregistrements.

ya intérêt à bien gérer les indexes & compagnie..

quoi qu'il en soit, merci pour ton aide c'est bien plus clair.

je pense malgré tout que je vais acheter un bouquin sur le design de bases, en auriez-vous à conseiller par hasard ? (pas forcément sur uml/merise mais un livre plus générique qui traite du design, j'imagine qu'il aborderais ces méthodes dans tous les cas).

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

04 sept. 2012, 15:36

en fait je me rend compte que.. cette table va être colossale en terme d'enregistrements.

ya intérêt à bien gérer les indexes & compagnie..
Effectivement, surement la plus "grosse" en termes de nombre de tuple.

coté indexation ce n'est pas forcément un gros soucis, sachant les recherches portent essentiellement sur les clefs primaire et qu'elles sont déjà indexées par nature (une pk c'est indexée na :) ).

Coté bouquin j'en connais pas trop, perso j'ai acheté le livre SQL (collection syntex) de Frédéric Brouard (SQLpro ).

Coté modélisation quelque chose sur merise, mais pas toute la méthode, généralement on utilise que le modèle entité association (qui est une petite partie de la méthode merise).

Tu peux aussi te renseigner sur la démarche suivis pas Craig Lerman sur la modélisation d'une application (avec UML). mais la pour le coup je ne connais pas trop d'ouvrage.


@+
Il en faut peu pour être heureux ......

ViPHP
ViPHP | 2577 Messages

05 sept. 2012, 11:25

Bonjour,

Il y a tout un tas de question à se poser.

Par exemple, un item peut appartenir à quelqu'un ou être stocké dans un "stockage".
Dans le second cas, tu vas gérer l'accès au stockage selon le personnage et pas la propriété de l'item. Tu pourras ainsi définir un coffre en banque, un inventaire du personnage. Toute opération sur la propriété de l'item ne sera que le transfert d'un lieu de stockage à un autre. Pour équiper un casque, il peut suffire de définir la tête de personnage comme un lieu de stockage. Il apparait alors qu'un lieu de stockage peut être limité en quantité voir en type d'item.

Pour les objets Il vaut mieux se rapprocher du réel. Un type d'object (epée, voiture...), un modèle d'objet (Mégane,Golf...), une version (GTI,TX..) et enfin la vrai voiture. On voit bien en général l'épée que le personnage à dans les mains, mais il est relativement difficile de répartir les données entre les tables. Doit on garder toutes les versions possible dans une table de référence et dire que l'item "réel" correspond à tel version ? Ou doit on avoir une table de toutes les items ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

05 sept. 2012, 15:43

Par exemple, un item peut appartenir à quelqu'un ou être stocké dans un "stockage".
Dans le second cas, tu vas gérer l'accès au stockage selon le personnage et pas la propriété de l'item. Tu pourras ainsi définir un coffre en banque, un inventaire du personnage. Toute opération sur la propriété de l'item ne sera que le transfert d'un lieu de stockage à un autre. Pour équiper un casque, il peut suffire de définir la tête de personnage comme un lieu de stockage. Il apparait alors qu'un lieu de stockage peut être limité en quantité voir en type d'item.
le stockage j'ai fait simple avec un (des) sac(s).
ceci dit tant qu'il s'agit de sac ou de banque d'un perso, la notion de propriété reste.

Après si l'on parle de guilde, effectivement un perso n'est plus propriétaire et la pour le coup c'est la guilde qui devient propriétaire de l'objet.

Donc il est possible de définir une entité plus large (propriétaire) qui aura un type guilde / perso et après ben jointure dynamique O_o la je sais pas faire mais c'est surement réalisable ^^


Pour le coup des emplacement je n'ai pas fait, mais le modèle reste le même, c'est effectivement un "stockage" différent. après c'est un cas non traité ici.


Pour ce qui est des items à conserver ou pas, je suis partis du principe que le loot était complètement aléatoire parmi les stats proposée.

Sinon oui autant avoir une base fixe d'items (même énorme) et éviter d'en créer à la louche :)

La modélisation reste toujours suggestive, cela dépend du cahier des charges et des gens qui modélise.

Ici on parle d'une modèle relationnel et non d'un modèle objet complet de l'application, ça peu changer des petites chose.


@+
Il en faut peu pour être heureux ......