JeuWeb - Crée ton jeu par navigateur
Ou stocker mes bâtiments ? ^^ - 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 : Ou stocker mes bâtiments ? ^^ (/showthread.php?tid=7292)



Ou stocker mes bâtiments ? ^^ - Max72 - 23-12-2014

Bonjour à tous !

Après une longue période prenante par le boulot, j'ai enfin le temps de me remettre à la conception de mon jeu Smile Aussi je reviens vous embêter :p
Au passage, j'aime bien le changement du site : pas forcément le style qui reste assez basique, mais le fait de proposer une nouvelle interface donne le sentiment que ce site est encore vivant Smile

Pour en revenir à mon jeu :
Pour mémoire, il s'agit d'un ogame like (on va faciliter les explications ^^) où les bâtiments ne sont pas uniques : Par exemple, on a au fil du temps une dizaine d'habitations différentes, et pas une qui change de niveau.

Mon problème est le suivant :
J'ai plus d'une centaine de bâtiments disponibles, et le joueur peut construire plusieurs fois chaque bâtiments. Certains bâtiments peuvent lancer des productions, par exemple produire 5 betteraves en 4h, et c'est l'utilisateur qui lance ces prods, pas en continu.
La liste des bâtiments disponibles sont stockées dans une BDD extérieure au jeu, une base de référence, elle même constituée de plusieurs tables qui me permet de classer les bâtiments selon leurs types (habitations, casernes, etc)
Maintenant, je ne sais trop où placer en BDD la liste des bâtiments que l'utilisateur a construit. Car il va y en avoir un bon paquet...

En créant plusieurs tables ? :
- Comme dans la BDD de référence, donc une table "habitations", avec uniquement l'id du bâtiment et l'id du joueur (beaucoup de lignes en BDD)
- une table "habitations" avec l'id du bâtiment, l'id du joueur et le nombre qu'il en possède dans sa cité (donc moins de lignes en BDD et peut-être plus facile à gérer)

En créant une seule table qui reprend tous les bâtiments de tous les joueurs ? :
Mais la table va juste être gigantesque si j'ai juste 100 joueurs avec 100 bâtiments chacun (10 000 lignes :/ )

Ou alors je me démerde pour que tous les bâtiments du joueur rentrent dans la table de sa cité ? Mais là ça va vite devenir chaud à s'y retrouver, parce que je pense que je vais devoir sérialiser le tout :/

J'aimerai savoir si, et je pense que c'est le cas ^^, vous avez déjà été confronté à cette problématique et quelle solution vous avez choisi.

PS : Oui je sais ça peut paraître très flou ^^

Merci !


RE: Ou stocker mes bâtiments ? ^^ - Thêta Tau Tau - 23-12-2014

(23-12-2014, 10:12 AM)Max72 a écrit : une table "habitations" avec l'id du bâtiment, l'id du joueur et le nombre qu'il en possède dans sa cité (donc moins de lignes en BDD et peut-être plus facile à gérer)
Si j'ai bien compris ce que tu veux faire, c'est ça qui s'approche le plus de ce qu'il faut faire.
Une table de liaison entre la table "type de bâtiment" et la table "joueurs" ou "planètes" si un joueur peut avoir plusieurs planètes, et une colonne supplémentaire pour le nombre de bâtiments.

(23-12-2014, 10:12 AM)Max72 a écrit : Mais la table va juste être gigantesque si j'ai juste 100 joueurs avec 100 bâtiments chacun (10 000 lignes :/ )

10000 lignes c'est pas gigantesque du tout, c'est même plutôt petit, faut pas avoir peur, les SGBD sont capable de gérer de gros volumes de données.
Pour te donner une idée, au boulot, j'utilise une base de données dont certaines tables font plusieurs centaines de millions de lignes.


RE: Ou stocker mes bâtiments ? ^^ - Max72 - 23-12-2014

Merci de ta réponse.
Oui c'est le système que je voyais le plus également, mais non certain de moi j'ai préféré poster ici.
Je vais creuser ça, et voir comment je peux gérer les productions en cours sans que chaque bâtiment ai un id propre à lui.

Plusieurs centaines de millions de lignes ? O_o
L'accès à ces tables est-il aussi rapide qu'une table qui possède 100 enregistrements ?

Merci !


RE: Ou stocker mes bâtiments ? ^^ - Thêta Tau Tau - 23-12-2014

(23-12-2014, 01:16 PM)Max72 a écrit : L'accès à ces tables est-il aussi rapide qu'une table qui possède 100 enregistrements ?

Tout dépends de la requête.

Si c'est pour sortir 10 lignes pas de soucis. Les SGBD ont un système d'index qui permet de retrouver rapidement une ligne dans une table.

Si c'est pour sortir plusieurs millions de lignes tout en faisant des jointures multiples, le temps explose, mais c'est pas étonnant étant donné que le résultat peut alors faire plusieurs Go. Cela dit vu que c'est pas du web ni des requêtes qu'on fait souvent, on s'en fout un peu que ça prenne du temps, d'autant que certains script qui traitent ensuite ces données mettent plusieurs jours/semaines.

(23-12-2014, 01:16 PM)Max72 a écrit : Je vais creuser ça, et voir comment je peux gérer les productions en cours sans que chaque bâtiment ai un id propre à lui.
Si chaque bâtiment peut "recevoir des ordres" individuellement, le plus simple serait d'avoir une ligne par bâtiment.
Cependant si ça ne concerne que certains bâtiments (par exemple, uniquement les bâtiments de production, et pas les habitations), avoir une ligne par bâtiment pourrait conduire à avoir des lignes identiques. Du coup je ferais un truc du genre :

Code :
table batiments :
PK id_type_de_batiment
PK id_planete
nombre

table productions :
Pk id_production
id_type_de_batiment
id_planete
type_de_production (par exemple)
date_de_fin_de_production (par exemple)

Quand un joueur lance une production, tu compare le nombre de lignes qu'il y a dans la table productions au nombre indiqué dans la table batiments pour savoir combien de bâtiments ne font rien.


RE: Ou stocker mes bâtiments ? ^^ - niahoo - 23-12-2014

Toute façon tu peux "peser" les tables. Elle ne pèsera même pas 10 Mo à tout casser. Genre un gros mp3


RE: Ou stocker mes bâtiments ? ^^ - Prélude - 23-12-2014

Tu peux aussi faire du hash sur tes tables.
Par exemple, pour une table qui se nomme "batiments", tu la scindes en "batiments_1", "batiments_2", "batiments_3" ...
Le chiffre sera alors un modulo de l'id du joueur par exemple (là, ça dépend de ce que tu souhaites faire comme requêtes).
Et tu peux alors scinder en autant de tables que tu le souhaites, en fonction du nombre de lignes que tu penses avoir, divisant ainsi grandement le temps de tes requêtes.


RE: Ou stocker mes bâtiments ? ^^ - Max72 - 23-12-2014

(23-12-2014, 01:45 PM)Thêta Tau Tau a écrit : Si chaque bâtiment peut "recevoir des ordres" individuellement, le plus simple serait d'avoir une ligne par bâtiment.
Cependant si ça ne concerne que certains bâtiments (par exemple, uniquement les bâtiments de production, et pas les habitations), avoir une ligne par bâtiment pourrait conduire à avoir des lignes identiques.

C'est exactement ça. La plupart des bâtiments construisent en continu, mais d'autres produisent 'à la demande', car les ressources fabriquées sont payantes (guerriers, betteraves ^^ ...)
De plus, la proportion doit être de 6 habitations pour un bâtiment de prod, si ce n'est plus. Je vais donc appliquer ta méthode, cela allégera ma BDD Smile

(23-12-2014, 01:45 PM)Thêta Tau Tau a écrit : Quand un joueur lance une production, tu compare le nombre de lignes qu'il y a dans la table productions au nombre indiqué dans la table batiments pour savoir combien de bâtiments ne font rien.

Je vais faire comme ça, merci Smile

@niahoo : Oui bien sûr, mais pour le moment je n'ai aucune idée de ce que donnera la BDD au final.
J'espère toucher plus de 100 joueurs ( j'ai déjà codé la partie qui me permet de mettre en place plusieurs serveurs, ce n'est pas pour 100 bonhommes ^^), et la barre des 100 bâtiments par joueur sera vite atteinte. Pour cela que j'aimerai alléger le plus possible le bousin.

@Prélude : Comme dit au dessus, j'ai prévu de quoi mettre en place plusieurs serveurs si le nombre de joueurs est conséquent. J'espère ne pas avoir besoin de diviser les joueurs d'un même monde sur plusieurs tables. Mais je garde ça sous le coude, au cas où Smile

Merci pour vos réponses pertinentes.


RE: Ou stocker mes bâtiments ? ^^ - Xenos - 23-12-2014

@prelude:
Oh là, j'ai relu deux fois pour comprendre, mais mauvaise idée. Scinder ainsi une table pour accélérer les accès aux données, point de vue sémantique, c'est créer deux tables réellement différentes et autonomes (par d'auto-increment commun ou de structure commune par exemple). Je ne l'ai jamais utilisé, mais MYSQL (et surement les autres SGBD) proposent du clustering, qui revient grosso modo au même système, sauf que c'est le SGBD qui le gère et non le développeur Smile
Mais bon, ce principe de découpe suivant le modulo, c'est ni plus ni moins qu'un arbre binaire, donc, cela revient simplement à (mal) réinventer les index → A ne pas faire.


Inutile d'alléger ou d'optimiser tant que cela n'a pas été nécessaire. Ou, en anglais, early optimization is evil. Fait au plus pratique pour le développeur (toi): il faut pouvoir "piloter" chaque bâtiment indépendamment? Alors une ligne par bâtiment. Piloter uniquement par type? Une ligne par type. Piloter des deux façons? Une ligne par bâtiment → on va au plus "ciblé", et on fait ensuite des groupes, façon atomes groupés en molécules.

Si les index sont bien construits, et que les requêtes les utilisent correctement, tu pourras sans soucis gérer des tables de millions de lignes.

Le seul élément qui pourrait être limitant, suivant l'offre en ligne à laquelle tu souscris, c'est la taille limite de la BDD. Mais bon, de ce point de vue là, on est autour de 100Mo facile plutôt que 10Mo.

D'expérience, sur ECLERD, j'avais une BDD de 5Mo maximum. J'ai commencé par appliquer une structure simple mais peu optimisée pour la machine (stocker, dans la BDD, 1 ligne par age d'habitants et par région, donc ayant des habitants de 0 à 120 ans et environ 5000 régions, cela faisait 600.000 lignes). Résultat: pas de soucis en local, mais une BDD de bien 30Mo: trop lourd pour mon offre d'hébergement. La meilleure solution, là, serait de changer d'offre (mais on peut ne pas avoir envie/les moyens), ou d'optimiser, ce que j'ai fait (1 ligne / région, avec 12 colonnes, 1 par tranche de 10 ans: table réduite à moins d'1Mo).

Mais en aucun cas il ne faut optimiser avant d'avoir réellement rencontré un problème, car maintenant, je m'en mors les doigts: impossible de faire évoluer le jeu, car il a été "sur-optimisé", il est impossible d'en relire le code et encore moins de l'améliorer...



Dans le cas présent, j'aurai plus vu:

Code :
GroupesBatiments:
id_groupe, id_planete, id_type_batiment, nombre, <infos-production>
PRIMARY KEY: id_groupe
INDEX: id_planete, id_type_batiment -- si nécessaires, sinon, ne mettre aucun des deux / seulement l'un des deux

Dans l'idée: sur une planète, on a des groupes de batiments. Dans un groupe, tous les bâtiments sont identiques et font la même chose. Un groupe ne peut donc être constitués que de N bâtiments de même type, dans le même état, avec les mêmes ordres de production. On pilote les bâtiments par groupe. Si on veut, on peut scinder un groupe en deux: le groupe initial perd P bâtiments (nombre est décrémenté de P) et on crée un nouveau groupe, identique au premier (même planète, même type de bâtiment, mêmes ordres de production) sauf l'id du groupe (auto-increment) et le nombre de bâtiments (P). On a donc deux lignes en BDD, une par groupe ainsi créé. On peut donc piloter les deux groupes séparément. De façon similaire, on peut fusionner deux groupes ayant des bâtiments identiques (même type, mêmes ordres de production). Un groupe peut très bien être constitué de 1 seul bâtiment (voire de 0 bâtiment, mais cela ne fait pas trop sens...)


RE: Ou stocker mes bâtiments ? ^^ - Max72 - 23-12-2014

Merci de ta réponse très complète Xenos, je vais essayer de te répondre dans l'ordre :


- Pour scinder la base, je pense ne pas en avoir besoin.

- J'essaye de développer au plus vite mon jeu, mais j'essaye dans le même temps de voir le plus loin possible : Lorsque je code une classe, une fonctionnalité, je cherche au maximum à laisser des portes ouvertes et à préparer le terrain pour les évolutions futures.
Par exemple, le jeu sera naturellement en français, mais je n'ai pas envie de me retaper tout le code si un jour je souhaite le proposer en anglais. Aussi, tout est déjà pensé/codé pour intégrer plusieurs langues, même si je ne traduis jamais le jeu.
Du temps de perdu pour la sortie de la première version, peut-être énormément de temps de gagné pour les MAJ/ ajout de fonctionnalité.

Quand à la taille de la BDD à proprement parler, ce n'est pas un soucis dans le sens ou j'héberge mon propre serveur (à moins que la BDD ne fasse plus de 160 Go ^^)

- Pour ton dernier paragraphe, je pense avoir saisi le sens mais que je ne procèderai pas ainsi :
Les productions ne seront jamais lancés exactement au même moment, donc chaque bâtiment de prod aura un groupe à lui tout seul :/

Par contre, je pense maintenant m'orienter vers un truc comme ça :
Code :
Table 'habitations' :

id_planete         id_batiment (id de référence de l'habitation dans ma table de référence)           nombre

Table 'batiments_prod'
id (unique)        id_planete         id_batiment            prod

En gros les habitations n'ont qu'une ligne par groupe, car elles n'ont pas besoin d'être représentées une par une.
En revanche, chaque batiment de prod aura sa propre ligne, son propre id et je pourrai gérer chaque prod indépendamment.

Comme ça je garde la légèreté pour les habitations, et l'accès rapide à mes bâtiments de prod Smile
Peut-être le bon compromis ?

Merci encore.