Je travaille sur un outil d'édition de niveau qui enregistre ses données au format XML.
C'est idéal pendant le développement, car il est indolore d'apporter de petites modifications au format de données, et cela fonctionne bien avec des données arborescentes.
L'inconvénient, cependant, est que les fichiers XML sont plutôt gonflés, principalement en raison de la duplication des noms de balises et d'attributs. Également dû au fait que les données numériques prennent beaucoup plus d'espace que l'utilisation de types de données natifs. Un petit niveau pourrait facilement devenir 1 Mo +. Je veux réduire ces tailles de manière significative, surtout si le système doit être utilisé pour un jeu sur l'iPhone ou d'autres appareils avec une mémoire relativement limitée.
La solution optimale, pour la mémoire et les performances, serait de convertir le XML en un format de niveau binaire. Mais je ne veux pas faire ça. Je veux garder le format assez flexible. XML facilite l'ajout de nouveaux attributs aux objets et leur donne une valeur par défaut si une ancienne version des données est chargée. Je veux donc garder la hiérarchie des nœuds, avec des attributs comme paires nom-valeur.
Mais j'ai besoin de stocker cela dans un format plus compact - pour supprimer la duplication massive des noms de balises / attributs. Peut-être aussi pour donner des attributs aux types natifs, ainsi, par exemple, les données à virgule flottante sont stockées sous forme de 4 octets par flottant, pas sous forme de chaîne de texte.
Google / Wikipedia révèlent que le «XML binaire» n'est guère un nouveau problème - il a déjà été résolu un certain nombre de fois. Quelqu'un ici a-t-il de l'expérience avec l'un des systèmes / normes existants? - sont-ils idéaux pour les jeux - avec une bibliothèque d'analyseur / chargeur (C / C ++) gratuite, légère et multiplateforme disponible?
Ou devrais-je réinventer cette roue moi-même?
Ou est-ce que je ferais mieux d'oublier l'idéal et de simplement compresser mes données brutes .xml (elles devraient bien s'emballer avec une compression de type zip) et de simplement prendre la mémoire / performance en charge?
la source
Réponses:
Nous avons beaucoup utilisé le XML binaire pour Superman Returns: The Videogame . Nous parlons de milliers et de milliers de fichiers. Cela a bien fonctionné, mais honnêtement, cela ne semblait pas valoir la peine. Il a consommé une fraction notable de notre temps de chargement, et la «flexibilité» de XML n'a pas évolué. Après un certain temps, nos fichiers de données avaient trop d'identifiants étranges, de références externes qui devaient être synchronisées et d'autres exigences étranges pour qu'ils puissent vraiment être édités par l'homme.
De plus, XML est vraiment un format de balisage et non un format de données. Il est optimisé pour beaucoup de texte avec des balises occasionnelles. Ce n'est pas idéal pour des données entièrement structurées. Ce n'était pas mon appel, mais s'il l'avait été et que je savais alors ce que je sais maintenant, j'aurais probablement fait JSON ou YAML. Ils sont tous deux suffisamment concis pour ne pas nécessiter de compactage et sont optimisés pour représenter les données , pas le texte .
la source
Stockez et modifiez vos niveaux en XML normal, mais laissez votre moteur de jeu le faire paresseusement en XML binaire pendant le chargement, et enregistrez le XML binaire sur le disque afin qu'il puisse le charger la prochaine fois (si le XML brut n'a pas changé) .
Quelque chose comme ça:
De cette façon, vous obtenez le meilleur des deux mondes. À la sortie, il vous suffit de vous assurer que tous les fichiers binaires sont là.
la source
Les tampons de protocole Google semblent être la voie à suivre, mais je ne les ai pas utilisés moi-même.
http://code.google.com/p/protobuf/
Vous définissez un fichier .proto qui décrit le format de fichier:
Il est ensuite compilé avec un outil en ligne de commande qui génère des classes C / C ++ pour écrire et analyser des fichiers de données binaires dans le format de données défini précédemment. Il existe également quelques extensions pour différents langages de programmation.
L'inconvénient de ProtocolBuffer est qu'ils ne sont pas au format texte brut. Vous auriez besoin d'un outil pour les générer, les lire et les modifier. Mais cela ne devrait pas être un problème si vous ne les utilisez que pour échanger des données entre votre éditeur de jeu et votre jeu. Je ne l'utiliserais pas pour définir des fichiers de configuration;)
La compression des fichiers xml bruts devrait également fonctionner. Quel type de jeu faites-vous? S'il est basé sur le niveau, vous ne devez charger toutes les ressources nécessaires qu'une seule fois lorsque le niveau est chargé.
mise à jour: il existe plusieurs projets pour d'autres langages tels que C # pour travailler avec ProtocolBuffers:
http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns
la source
.proto
fichier, ce qui élimine presque les problèmes de mauvaise communication. Les protos sont beaucoup plus faciles à lire / maintenir qu'un schéma xml, si vous avez même la discipline (et le temps) pour utiliser les schémas xml.Et le format JSON?
http://www.json.org/xml.html
la source
"cars":{"ford":[8C,FA,BC,2A,384FFFFF],"holden":[00,00,04,FF,04FF54A9]}
vous pouvez même omettre l'identifiant "cars" et aller directement dans un tableau si vous savez où se trouvera le champ cars. Vous pouvez même omettre les noms « gué » et « holden » si vous n'avez pas besoin d'enregistrer ces données, vous laissant avec:[...,[[8C,FA,BC,2A,384FFFFF],[00,00,04,FF,04FF54A9]]]
. Est-ce que ça devient plus compact?Utilisez JSON.
(S'appuyant sur la réponse de Munificent, et en grande partie en réponse à vos préoccupations exprimées ailleurs)
Vous avez mentionné que JSON a le problème de gaspiller des éléments de nommage d'espace, comme XML. Ce n'est pas le cas.
JSON est construit sur deux structures: les paires nom / valeur ( objets ) et les listes ordonnées de valeurs ( tableaux ). XML est construit uniquement sur des paires nom / valeur.
Si vous pensez que JSON repose sur des objets que vous avez lus, JSON est conçu pour être auto-descriptif et lisible par l'homme, comme ceci (en utilisant des paires de chiffres octaux pour représenter des octets uniques):
Cependant, vous avez également la possibilité de l'écrire comme ceci, tant que vous savez où tout sera (et que vous pouvez donc rechercher l'index 4, plutôt que l'objet "voitures", pour obtenir votre liste de voitures):
Est - il obtenir plus concis que d' avoir simplement
[
,]
,,
et vos valeurs?Eh bien, c'est le cas si vous êtes prêt à vous rapprocher de plus en plus d'un flux binaire pur.
Ne vous tirez pas une balle dans la jambe en optimisant trop.
la source
Je sais que vous avez accepté une réponse, mais Google à la fois "Fast Infoset" (XML binaire) et vtd-xml.
Bien que ce dernier (VTD) ne puisse pas résoudre l'aspect de compression de votre utilisation XML, il peut accélérer considérablement l'accès aux nœuds sur de gros fichiers (il utilise un dictionnaire de décalages binaires pour accéder aux nœuds et ne crée pas d' objets pour chaque nœud. , travaillez plutôt sur la chaîne XML d'origine). Par conséquent, sa recherche XML est [dit être] à la fois plus rapide et ne nécessite pas autant de mémoire en cours pour accéder / manipuler le document XML.
Les deux ci-dessus ont des liaisons dans les langages populaires (qui incluent C #).
À votre santé
Riches
la source
Vous pouvez essayer la Karvonite . C'est censé être agile. C'est un framework de persistance qui s'adaptera assez bien aux changements de vos données (ce qui est bien par rapport à la gestion binaire de vous-même). Je ne sais pas vraiment comment les données sont structurées, mais les fichiers sont beaucoup plus petits que les fichiers gonflés xml. (Je suppose qu'il enregistre les données dans un format binaire au lieu de texte comme xml)
Le seul inconvénient auquel je peux penser est que si vos données sont corrompues ou si elles sont gâchées d'une manière que Karvonite n'aime pas, votre type est à la merci de ses créateurs à moins que vous ne compreniez comment la structure du les données fonctionnent.
La façon dont vous spécifiez comment enregistrer / charger vos données est d'ouvrir simplement leur éditeur de persistance, d'importer votre assemblage avec tous les objets de données et de cocher certaines cases pour afficher les objets que vous souhaitez prendre en charge et les champs / propriétés à enregistrer.
Cela pourrait valoir le coup d'essayer. Depuis que vous utilisez C #, cela correspond parfaitement à votre langage car il fonctionne avec XNA (Windows, Xbox360 et Windows Phone 7 qui, je pense, vous intéressent depuis que vous avez mentionné l'iPhone?).
Edit: Je viens de remarquer que vous n'utilisez que C # pour les outils. Cela ne s'intégrerait probablement pas très bien dans votre flux de travail. Pour une raison quelconque, j'avais XNA dans ma tête.
la source