JeuWeb - Crée ton jeu par navigateur
lire une map - 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 : lire une map (/showthread.php?tid=5311)

Pages : 1 2


lire une map - Asphodèles - 13-03-2011

Bonjour à tous !

Je suis en train de faire quelques tests pour un futur jeu. Comme dans beaucoup d'autres jeux j'ai une petite partie d'une grande map à afficher : ce que le joueur voit du monde.

pour l'instant j'ai créé un fichier map qui est en fait du php :

<?php
$map=array(
array(1,1,1,1,1,....1),
array(1,1,1,1,1.....1),
array(1,1,1,1,1,....1),
array(1,1,1,.........1),
....
array(1,1,1,.........1)
)
?>

du coup, c'est extrêmement simple de sélectionner la zone vue par le joueur, vu que je manipule un simple tableau.

Seulement quand je regarde les performances de la chose, petit problème, l'include qui charge cette map met 68ms ! C'est dommage, parce qu'en ressortit la zone qui m'intéresse ne met que 0,2ms...

Dans d'autres langages j'aurais plutôt fait un fichier binaire qu'un script, mais j'imaginais que le parser gèrerait ça facilement.

J'ai aussi vu des types dire qu'ils avaient leur carte en bdd, mais ça me semble encore plus critique que ma solution...

Qu'est-ce que vous me conseillez ? un fichier binaire aurait vraiment de bien meilleures performances ?

Je suis désolé de vous demander plutôt que de tester par moi même, mais vu que je débute, tout me prend beaucoup de temps, et je sais que je passerais longtemps à tester cette solution en binaire.

Merci beaucoup

EDIT : J'ai oublié de dire : la map fait 200*200 soit 100Ko de script, là. Si je la faisais en binaire, elle ferait 200*200*4=156Ko (ça semble paradoxal, mais pour l'instant j'ai bcp de '1' dans la map, alors qu'en fait chaque case serait codée sur 4 octets).


RE: lire une map - php_addict - 13-03-2011

euh...et tu ne comptes pas mettre ta map en base de donnée ? tu comptes faire ton include a chaque fois que tu a besoin de quelques cases???

tu t'es planté de façon de faire, ta map doit être dans une base de donnée comme cela tu peut récupérer uniquement ce que tu veut avec un SELECT id WHERE (x BETWEEN 10 AND 32) par exemple si c'est un base de donnée MYSQL

cela ne devrait pas etre trop dur a modifier car au final quand tu interroge ta base de donnée, elle te renvois un array() de donnée, mais nettement plus petit que tout ton include...


RE: lire une map - niahoo - 13-03-2011

que tu aies des 1 ou des 0, 4 octets ça pèse 4 octets, point barre non ?
Mais je ne suis pas convaincu que créer un parser maison aille plus vite que de simplement demander à php de parser un tableau. Ou disons le autrement, 68ms c'est que dalle donc bosse sur autre chose et si vraiment un jour tu veux réduire ça alors tu te fais un format de map perso avec parser.

bon en plus une base de données n'est pas obligatoire mais quand tu vas vouloir te faire un éditeur, générer dynamiquement du code php c'est plutot chiant.


RE: lire une map - Holy - 13-03-2011

(13-03-2011, 08:01 PM)php_addict a écrit : tu t'es planté de façon de faire, ta map doit être dans une base de donnée comme cela tu peut récupérer uniquement ce que tu veut avec un SELECT id WHERE (x BETWEEN 10 AND 32) par exemple si c'est un base de donnée MYSQL
Un système de fichiers fait tout aussi bien l'affaire. Y a aucune obligation d'utiliser une base de données.


RE: lire une map - Asphodèles - 13-03-2011

(13-03-2011, 09:19 PM)niahoo a écrit : bon en plus une base de données n'est pas obligatoire mais quand tu vas vouloir te faire un éditeur, générer dynamiquement du code php c'est plutot chiant.

Pour l'éditeur, il est déjà fait : Tiled. Après je peux récupérer la map générée par Tiled de plusieurs façons. Pour l'instant je l'ai récupérée en csv et un script me la convertit dans le code PHP que tu as vu plus haut. C'est donc presque entièrement automatisé, et surtout 1000 fois mieux que tous les éditeurs que je pourrais faire (je le sais, j'ai déjà essayé dans d'autres projets).

(13-03-2011, 09:19 PM)niahoo a écrit : que tu aies des 1 ou des 0, 4 octets ça pèse 4 octets, point barre non ?

Mon exemple t'a induit en erreur, pardon. Ma map n'est pas juste des 1 et des 0. Donc oui, en php, '1' ou '0' ça sera toujours la même taille (1 char), mais la case '325542' prendra plus de place, et à terme (quand j'aurais plus de cases différentes) ce sera donc probablement un plus gros fichier .php que .bin

(13-03-2011, 09:19 PM)niahoo a écrit : Mais je ne suis pas convaincu que créer un parser maison aille plus vite que de simplement demander à php de parser un tableau. Ou disons le autrement, 68ms c'est que dalle donc bosse sur autre chose et si vraiment un jour tu veux réduire ça alors tu te fais un format de map perso avec parser.

d'accord, merci beaucoup ! 68ms c'est donc pas beaucoup ?
En fait je me suis posé cette question après un petit coup de flip : je testais tout en local, et évidemment ça tournait bien. Là j'ai fini par le tester chez un hébergeur (j'ai mis quelques temps à comprendre que free était encore sur php4 et ne supportait pas json_encode...), et ça me fait peur comme c'est lent... Je vous ferais bien tester, mais j'ai encore quelques petits doutes sur ma sécurité avant de vous envoyer une url...
Je ne compte pas faire comme ça, mais avec une table bien indexée, sur une map contenant 40.000 cases, et en sélectionnant quelque chose comme 600 cases par vue (je comptais que les joueurs voient environ 33*19 cases), on peut espérer des performances correctes ?

En plus, il y aura plusieurs maps, donc ça rallonge la table. Enfin, ça serait possible de faire une table par map, donc c'est un faux problème.


RE: lire une map - niahoo - 14-03-2011

ce que je voulais dire c'est que si tu prévois un fichier binaire, et que tu prévois également d'avoir des valeurs comme 325542 dedans, alors les valeurs '1' prendront auant de place que '325542', tu seras obligé d'enregistrer toutes les valeurs sur le même nombre d'octets.

sur deux octets tu peux aller à 65 536, et 200 * 200 * 2 octets = 80 000 octets.

Ensuite, fais le calcul, si tu trouves que c'est lent, penses tu que ça vienne des 68ms de ta map ? non. Enfin, vérifie que sur free les 68 ne se soient pas transformées en 2000.

par contre je ne sais pas si tu as commencé par créer des valeurs de carte genre herbe:1, herbe+arbre:2, etc... mais si c'est le cas alors change et raisonne par couche.
d'abord le sol, herbe:1, sable:2, eau:3,
puis la végétation, avec un code d'objet de végétation: sapin:1, sapin2:2, hêtre:3, hêtre2:4, etc..

enfin si Tiled le parmet, ça m'a l'air sympa je vais l'installer.


RE: lire une map - Sephi-Chan - 14-03-2011

Une question qui a son importance : pourquoi ne pas utiliser une base de données ?


Sephi-Chan


RE: lire une map - Asphodèles - 14-03-2011

(14-03-2011, 12:27 AM)Sephi-Chan a écrit : Une question qui a son importance : pourquoi ne pas utiliser une base de données ?

En fait c'est une question que je ne m'étais pas posée ! Je n'en suis qu'à mon premier projet web, mais j'ai fait le même genre de projet en client et serveur lourds auparavant. Évidemment quand tu programmes ton serveur toi-même, tu as plus intérêt à charger les cartes en mémoire une bonne fois pour toutes plutôt que de les mettre en bdd. Du coup j'ai gardé l'habitude sans réfléchir, mais effectivement, évaluer le fichier php à chaque requête, c'est dommage.

Ce qui me pousse à vous poser d'autres questions encore :
-ma map semble prendre 786432bytes (j'ai été surpris de voir que sizeof() ne retournait pas l'utilisation mémoire, d'ailleurs), ça se fait de garder ça en session ? Si c'est possible, ça veut dire que le traitement de la vue d'un joueur ne prend que 0,2 ms, alors évidemment, c'est tentant.
-en python, les fichiers sources sont 'compilés' dans un état intermédiaire (fichier .pyc) que python sait utiliser plutôt que le .py s'ils sont à jour. Est-ce qu'un tel truc est possible en php ?


niahoo a écrit :ce que je voulais dire c'est que si tu prévois un fichier binaire, et que tu prévois également d'avoir des valeurs comme 325542 dedans, alors les valeurs '1' prendront auant de place que '325542', tu seras obligé d'enregistrer toutes les valeurs sur le même nombre d'octets.

sur deux octets tu peux aller à 65 536, et 200 * 200 * 2 octets = 80 000 octets.
D'accord, on ne s'était pas compris, je pense. En fait, Tiled compte 4 octets par case, d'où mon calcul "200*200*4=156Ko" du premier post.

niahoo a écrit :raisonne par couche.
d'abord le sol, herbe:1, sable:2, eau:3,
puis la végétation, avec un code d'objet de végétation: sapin:1, sapin2:2, hêtre:3, hêtre2:4, etc..

enfin si Tiled le parmet, ça m'a l'air sympa je vais l'installer.
Tiled permet ça (et plein d'autres bonnes choses), mais je m'étais dit que j'allais éviter d'alourdir tout avec plusieurs couches.

Enfin pour ça, il n'est jamais trop tard


RE: lire une map - php_addict - 14-03-2011

(14-03-2011, 02:04 PM)Asphodèles a écrit : -ma map semble prendre 786432bytes (j'ai été surpris de voir que sizeof() ne retournait pas l'utilisation mémoire, d'ailleurs), ça se fait de garder ça en session ?

non c'est nul, si tu as 300 joueurs connectés tu aura 300 fois ta map en session...les variables de sessions ne sont pas faites pour ca...


RE: lire une map - Sephi-Chan - 14-03-2011

Justement, ton système ne charge pas la carte en mémoire une seule fois, il la charge en mémoire pour chaque script et libère cette mémoire à la fin du script.
  • Si tu veux travailler en mémoire une bonne fois pour toute, c'est plutôt vers Memcached ou Redis qu'il faut se tourner ;
  • Il y a également d'autres approches très efficaces pour stocker de gros volumes de données : MongoDB par exemple ;
  • Les bases de données relationnelles, plus traditionnelles, sont très efficaces ;

À mon sens, beaucoup de créateurs amateurs ont un problème avec le stockage des données : vous cherchez souvent à réinventer la roue alors que vous n'avez pas d'expérience dans ce domaine. Les systèmes de fichiers, l'utilisation de la mémoire, et tout ce qui concerne les entées/sorties en général est un domaine complexe.

Vous devriez plutôt utiliser les systèmes existants : ils sont construits par des ingénieurs compétents et leurs caractéristiques spécifiques sont connues et reconnues. Certains sont conçus pour être rapide en écriture et/ou lecture, d'autres pour stocker des masses de données importantes, d'autres pour supporter la concurrence, etc.

Ne vous arrêtez pas à des observations que vous faîtes quand vous chargez une malheureuse page qui ouvre un malheureux fichier. Imaginez (et testez) ce que ça donne avec la masse de joueurs que vous attendez.

Je n'ai pas cette expérience non plus, et c'est précisément pour ça que je ne réinvente pas ces systèmes. Seulement, je m'intéresse aux outils et je lis beaucoup pour essayer de déterminer quand utiliser quoi.


Je n'ai pas de solution directe à ton problème. Pour avancer, il faudrait savoir comment fonctionne ta carte : ce que tu as besoin de stocker, le volume d'information, comment on doit récupérer les informations (va-t-on tout charger d'un coup ? Ou va-t-on découper l'espace ?), etc.

Ne cherche pas tout de suite à savoir comment stocker telle ou telle information : ce n'est pas important de savoir si tu vas indiquer que telle case est une forêt grâce à un entier que tu feras correspondre à quelque chose ou directement avec une chaîne de caractère.


Sephi-Chan