JeuWeb - Crée ton jeu par navigateur
Structure d'un inventaire hétérogène - 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 : Structure d'un inventaire hétérogène (/showthread.php?tid=6804)

Pages : 1 2


Structure d'un inventaire hétérogène - MadMass - 01-02-2014

Bonjour,
Je réfléchis à comment coder un inventaire hétérogène du point de vue de la DB.

Pour l'instant deux choses inévitables me viennent à l'esprit :
- Une table listant tous les items du jeu
- Une table listant tous les items en possession de tel ou tel joueur

Jusque là ça va.
Mais je veux que dans mon jeu, les joueurs puissent avoir des objets très hétérogènes dans leur inventaire :
- Des objets complètement passif (genre : bout de métal trouvé par terre)
- Des objets d'équipement (donc qu'il est possible d'équiper)
- Des armes (idem que l'équipement, mais avec un script en plus)
- Des objets de quête
- Des objets empilables
- Des objets pas empilables
- Des objets liables
- Des objets pas liables

Bref des caractéristiques très très différentes. Donc j'hésite ce qui est le mieux niveau optimisation :
- Une seule table d'items sachant que qui peut le plus peut le moins : les items lambda auront donc un grand nombre de colonnes vides
- Une table qui liste tous les items et leur type, et une table par type d'items, le tout lié par des jointures ?
- Une autre solution ?

Je penche largement pour la première option, un champ de type indique quel genre d'item c'est, et le jeu sait ainsi quels champs chercher ou non.
Des idées ? :heu:


RE: Structure d'un inventaire hétérogène - Sephi-Chan - 01-02-2014

Je te conseille effectivement la première solution, c'est la plus simple et la plus efficace.

J'avais posté des liens qui expliquaient que le nombre de colonnes importaient peu (surtout en deçà de 64 colonnes), d'autant plus quand leur valeur était NULL.


C'est comme ça que je fais pour beaucoup de choses. Pour des objets, j'ai d'une part une table object_types qui liste les différents objets disponibles et qui contient les attributs génériques d'un objet, et une table objects qui associe un personnage à un type d'objet et qui porte les attributs spécifique à cette "instance" de l'objet (son seuil d'usure, son niveau d'amélioration, la quantité de charge restantes, etc.).


RE: Structure d'un inventaire hétérogène - Xenos - 01-02-2014

Salut,

je penche pour la 2eme option :p
La première n'est pas simple à maintenir: quand une caractéristique devra être rajoutée, il faudra une nouvelle colonne qui ne fera pas forcément sens pour toutes les items (qui devraient donc définir cette colonne à "null"). Cela va vite devenir ingérable.
Je te conseille clairement l'option "1 table par type d'objet", qui correspondrait un peu à "1 table par classe (et une ligne par instance de cette classe)". Ce sera plus simple à gérer.
Rien ne t'empêche ensuite d'ajouter une colonne dans la table "objetActif" par exemple, qui permet de faire une composition avec la table "objetInactif". Ainsi, une ligne de "objetActif" est toujours liée à une ligne "objetInactif" qui décrit la partie inactif de l'item.
Ce sera bien plus clair quand le temps te feras ajouter des tas de types d'objets, même s'il est assez rebutant de créer des tas de tables dans une BDD.

Ce qui sera à mon avis gênant par la suite, c'est que la structure de la table (les colonnes "actives", aka celles dont les données sont pertinentes) va dépendre d'une valeur de la ligne (le type d'objet). On sort des 3 premières formes normales...
Et que dire d'une erreur qui ferait passer le type d'un objet de "Bout de métal trouvé par terre" à "Arme magique"? C'est théoriquement possible, puisqu'il suffirait de changer la valeur de la colonne "TypeObjet", mais est-ce pertinent ou même logique?


RE: Structure d'un inventaire hétérogène - Sephi-Chan - 01-02-2014

(01-02-2014, 03:43 PM)Xenos a écrit : La première n'est pas simple à maintenir: quand une caractéristique devra être rajoutée, il faudra une nouvelle colonne qui ne fera pas forcément sens pour toutes les items (qui devraient donc définir cette colonne à "null"). Cela va vite devenir ingérable.

Pour le coup, je ne vois pas trop comment ça peut devenir ingérable dans la mesure où tu n'as rien à gérer : tu ajoutes la colonne dont tu as besoin et… c'est tout ! Smile

Mais je suis d'accord pour dire qu'on sort des formes normales. Après, est-ce que c'est un problème ? J'en doute. J'ai déjà expérimenté ça de nombreuses fois ça soucis.
Effectivement, ça peut merder — et même de manière silencieuse, ce qui est le plus pénible — si on corrompt ses données.

Bien sûr, il faut se limiter soi-même, puisque dans l'absolu rien ne nous empêcherait de tout stocker dans une seule table.


RE: Structure d'un inventaire hétérogène - niahoo - 01-02-2014

(01-02-2014, 04:24 PM)Sephi-Chan a écrit : Bien sûr, il faut se limiter soi-même, puisque dans l'absolu rien ne nous empêcherait de tout stocker dans une seule table.

Il me semble que tu disais d'utiliser une table commune pour les objets descendants d'une même classe.


RE: Structure d'un inventaire hétérogène - MadMass - 01-02-2014

Ce qui est arrangeant dans ce cas c'est qu'en quelque sorte, c'est additif.
Je m'explique :

Dans le cas d'un item normal : infos de base de l'item
Dans le cas d'un quest item : infos de base de l'item + infos relatives à la quête
Dans le cas d'un équipement : infos de base de l'item + infos de combat
Dans le cas d'une arme : infos de base de l'item + infos de combat + infos de script
Dans le cas d'une arme de quête (sisi) : infos de base de l'item + infos de combat + infos de script + infos relatives à la quête

Donc à chaque fois ça consiste à ajouter des colonnes, ça réduit fortement le risque de confusion Smile après, es-ce pertinent d'un point de vue optimisation ?


RE: Structure d'un inventaire hétérogène - Sephi-Chan - 01-02-2014

Disons que ça c'est le pattern Single Table Inheritence utilisé dans Rails ou .NET.
D'ailleurs dans Rails en suivant ça tu n'as rien à gérer. Et ça me semble être une bonne guildeline pour ne pas faire n'importe quoi.

Par exemple en Ruby avec Rails :


class Node < ActiveRecord::Base
belongs_to :map
has_many :neighborhoods, dependent: :destroy
has_many :areas, through: :neighborhoods

scope :crossroads, -> { where(type: 'Crossroad') }
scope :territories, -> { where(type: 'Territory') }
end


class Territory < Node
end

class Crossroad < Node
end

Dans une console Rails (avec PostgreSQL comme base) :


Node.all # SELECT "nodes".* FROM "nodes"
Crossroad.all # SELECT "nodes".* FROM "nodes" WHERE "nodes"."type" IN ('Crossroad')
Territory.last # SELECT "nodes".* FROM "nodes" WHERE "nodes"."type" IN ('Territory') ORDER BY "nodes"."id" DESC LIMIT 1
Territory.create(name: 'Foo') # INSERT INTO "nodes" ("name", "type") VALUES ($1, $2) RETURNING "id" [["name", "Foo"], ["type", "Territory"]]



RE: Structure d'un inventaire hétérogène - niahoo - 01-02-2014

Ils ont quoi de particulier les items de quête ? Si une quête te demande trois bouts de pain, tous les bouts de pain de ton jeu vont être des items de quête ? Et là, on parle bien des tables pour les types d'items, ou des copies de chaque type.

Tu ne nous a pas dit si on pouvait modifier un item (rajouter des bonus par exemple).


RE: Structure d'un inventaire hétérogène - MadMass - 01-02-2014

(01-02-2014, 05:15 PM)niahoo a écrit : Ils ont quoi de particulier les items de quête ? Si une quête te demande trois bouts de pain, tous les bouts de pain de ton jeu vont être des items de quête ? Et là, on parle bien des tables pour les types d'items, ou des copies de chaque type.

Tu ne nous a pas dit si on pouvait modifier un item (rajouter des bonus par exemple).

En fait les items de quêtes n'apportent pas grand chose, mais j'aimerais que le joueur puisse distinguer dans son inventaire un item courant et un item de quête. Parce que certains items seront confiés par un PNJ en début de quête, donc j'aimerais qu'ils soient indiqués comme tels.
Au final, ça peut se résumer à une seule colonne isQuestItem à 1 ou 0 qui indique si il s'agit d'un item de quête ou pas.

J'ai songé aux modifications d'items, et je me suis dit que si je devais implémenter ça, ce serait pas dans la table des items mais dans la table des items possédés par les joueurs Smile donc ça ne pose pas de soucis. La table dont je parle là est une table en read-only, une référence listant tous les items existant dans le jeu et leur attribuant un id numérique. J'ai ensuite une autre table qui fait le lien joueur-item.

@Sephi-Chan : désolé, mais je comprend pas le code que tu cites :$


RE: Structure d'un inventaire hétérogène - niahoo - 01-02-2014

j'ai comme toi, des records de type 'item_type', qui indiquent le nom d'un item et ses différentes proprietés. Ensuite, dans chaque inventaire on a des records de type 'items' (note le pluriel) qui indique l'id de l'item type, la quantité, et d'autres trucs qui ne nous intéressent pas ici.

tout est en vrac, mais dans l'inventaire chaque 'items' est associé à une métadonnée, par exemple 'processing' qui signifie que l'item est en cours d'utilisation, mais tu peux mettre 'quest' par exemple.