Ich arbeite an einem Level-Editing-Tool, das seine Daten als XML speichert.
Dies ist ideal während der Entwicklung, da es schmerzlos ist, kleine Änderungen am Datenformat vorzunehmen, und es funktioniert gut mit baumartigen Daten.
Der Nachteil ist jedoch, dass die XML-Dateien ziemlich aufgebläht sind, was hauptsächlich auf die Duplizierung von Tag- und Attributnamen zurückzuführen ist. Dies ist auch darauf zurückzuführen, dass numerische Daten erheblich mehr Platz beanspruchen als native Datentypen. Ein kleiner Pegel kann leicht 1 MB + betragen. Ich möchte diese Größen erheblich reduzieren, insbesondere wenn das System für ein Spiel auf dem iPhone oder anderen Geräten mit relativ begrenztem Speicher verwendet werden soll.
Die optimale Lösung für Speicher und Leistung besteht darin, das XML in ein Binärformat zu konvertieren. Aber ich möchte das nicht tun. Ich möchte das Format ziemlich flexibel halten. Mit XML ist es sehr einfach, Objekten neue Attribute hinzuzufügen und ihnen einen Standardwert zuzuweisen, wenn eine alte Version der Daten geladen wird. Ich möchte also bei der Hierarchie der Knoten bleiben und Attribute als Name-Wert-Paare verwenden.
Ich muss dies jedoch in einem kompakteren Format speichern, um die massive Verdoppelung von Tag- / Attributnamen zu vermeiden. Vielleicht auch, um Attributen native Typen zu geben, so werden beispielsweise Gleitkommadaten als 4 Bytes pro Gleitkomma gespeichert, nicht als Textzeichenfolge.
Google / Wikipedia zeigen, dass 'binäres XML' kaum ein neues Problem darstellt - es wurde bereits mehrmals gelöst. Hat hier jemand Erfahrung mit einem der vorhandenen Systeme / Standards? - Gibt es eine ideale Lösung für Spiele - Mit einer kostenlosen, leichten und plattformübergreifenden Parser / Loader-Bibliothek (C / C ++)?
Oder soll ich dieses Rad selbst neu erfinden?
Oder ist es besser für mich, das Ideal zu vergessen und nur meine rohen XML-Daten zu komprimieren (es sollte sich gut mit einer zip-ähnlichen Komprimierung packen lassen) und nur den Speicher- / Leistungstreffer beim Laden zu berücksichtigen?
quelle
Antworten:
Wir haben für Superman Returns: The Videogame viel binäres XML verwendet . Wir sprechen von Tausenden und Abertausenden von Dateien. Es hat gut funktioniert, aber ehrlich gesagt schien es die Mühe nicht wert zu sein. Es hat einen beachtlichen Teil unserer Ladezeit in Anspruch genommen, und die "Flexibilität" von XML hat sich nicht vergrößert. Nach einer Weile hatten unsere Datendateien zu viele seltsame Bezeichner, externe Referenzen, die synchron gehalten werden mussten, und andere seltsame Anforderungen, damit sie wirklich nicht mehr von Menschen bearbeitet werden konnten.
XML ist auch wirklich ein Markup-Format und kein Datenformat. Es ist für viel Text mit gelegentlichen Tags optimiert. Es ist nicht gut für vollständig strukturierte Daten. Es war nicht mein Anruf, aber wenn es gewesen wäre und ich wusste, was ich jetzt weiß, hätte ich wahrscheinlich JSON oder YAML gemacht. Sie sind so kurz, dass keine Komprimierung erforderlich ist, und sie sind für die Darstellung von Daten und nicht von Text optimiert .
quelle
Speichere und bearbeite deine Levels als normales XML, aber lasse deine Spiel-Engine es während des Ladens träge in binäres XML backen und speichere das binäre XML zurück auf die Festplatte, damit es das nächste Mal geladen werden kann (falls sich das rohe XML nicht geändert hat). .
Etwas wie das:
So bekommen Sie das Beste aus beiden Welten. Bei der Veröffentlichung müssen Sie nur sicherstellen, dass alle Binärdateien vorhanden sind.
quelle
Google Protocol Buffers scheinen der richtige Weg zu sein, aber ich habe sie selbst nicht verwendet.
http://code.google.com/p/protobuf/
Sie definieren eine .proto-Datei, die das Dateiformat beschreibt:
Dies wird dann mit einem Befehlszeilentool kompiliert, das C / C ++ - Klassen zum Schreiben und Parsen von Binärdatendateien im zuvor definierten Datenformat generiert. Es gibt auch einige Erweiterungen für verschiedene Programmiersprachen.
Der Nachteil von ProtocolBuffer ist, dass es sich nicht um ein Nur-Text-Format handelt. Sie benötigen ein Tool, um sie zu generieren, zu lesen und zu bearbeiten. Dies sollte jedoch kein Problem sein, wenn Sie sie nur zum Datenaustausch zwischen Ihrem Spieleditor und Ihrem Spiel verwenden. Ich würde es nicht verwenden, um Konfigurationsdateien zu definieren;)
Das Komprimieren der unformatierten XML-Dateien sollte ebenfalls funktionieren. Welche Art von Spiel machst du? Wenn es ebenenbasiert ist, sollten Sie alle erforderlichen Ressourcen nur einmal laden, wenn die Ebene geladen wird.
Update: Es gibt mehrere Projekte für andere Sprachen, z. B. C #, für die Zusammenarbeit mit ProtocolBuffers:
http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns
quelle
.proto
Datei, wodurch Probleme mit der Kommunikation nahezu beseitigt werden. Protos sind viel einfacher zu lesen / zu pflegen als ein XML-Schema, wenn Sie sogar die Disziplin (und Zeit) haben, XML-Schemas zu verwenden.Was ist mit dem JSON-Format?
http://www.json.org/xml.html
quelle
"cars":{"ford":[8C,FA,BC,2A,384FFFFF],"holden":[00,00,04,FF,04FF54A9]}
Sie können sogar die Kennung "cars" weglassen und direkt in ein Array wechseln, wenn Sie wissen, wo sich das Feld cars befindet. Sie können sogar die Namen "ford" und "holden" weglassen, wenn Sie diese Daten nicht speichern müssen[...,[[8C,FA,BC,2A,384FFFFF],[00,00,04,FF,04FF54A9]]]
. Wird es kompakter?Verwenden Sie JSON.
(Aufbauend auf der Antwort von Munificent und vor allem auf Ihre Bedenken, die Sie an anderer Stelle geäußert haben)
Sie haben die Besorgnis erwähnt, dass JSON das Problem hat, Speicherplatz-Benennungselemente wie XML zu verschwenden. Das tut es nicht.
JSON baut auf zwei Strukturen auf: Name / Wert-Paare ( Objekte ) und geordnete Wertelisten ( Arrays ). XML basiert nur auf Name / Wert-Paaren.
Wenn Sie glauben, JSON stützt sich auf Objekte, die Sie in JSON gelesen haben, und die so aufgebaut sind, dass sie selbsterklärend und für den Menschen lesbar sind (wobei einzelne Bytes durch oktale Ziffernpaare dargestellt werden):
Sie haben jedoch auch die Möglichkeit, es so zu schreiben, solange Sie wissen, wo sich alles befinden wird (und daher nach Index 4 anstatt nach Objekt "Autos" suchen können, um Ihre Liste der Autos zu erhalten):
Ist es prägnanter als nur mit
[
,]
,,
und Ihre Werte?Nun, wenn Sie gewillt sind, einem reinen Binärstrom immer näher zu kommen.
Schießen Sie sich einfach nicht ins Bein, indem Sie zu viel optimieren.
quelle
Ich weiß, dass Sie eine Antwort akzeptiert haben, aber Google sowohl "Fast Infoset" (binäres XML) als auch vtd-xml.
Obwohl letzteres (VTD) den Komprimierungsaspekt Ihrer XML-Nutzung möglicherweise nicht auflöst, kann es den Knotenzugriff über große Dateien erheblich beschleunigen (es verwendet ein binäres Offsetwörterbuch, um zu Knoten zu springen, und erstellt keine Objekte für jeden Knoten stattdessen an der ursprünglichen XML-Zeichenfolge arbeiten). Daher ist die XML-Suche schneller und es wird nicht so viel In-Process-Speicher benötigt, um auf das XML-Dokument zuzugreifen bzw. es zu bearbeiten.
Beide oben genannten haben Bindungen in den gängigen Sprachen (einschließlich C #).
Prost
Reich
quelle
Sie könnten Karvonite versuchen . Es soll agil sein. Es handelt sich um ein Persistenz-Framework, das sich gut an die Änderungen in Ihren Daten anpasst (was im Vergleich zum Umgang mit Binärdateien bei Ihnen selbst nützlich ist). Ich bin mir nicht sicher, wie die Daten strukturiert sind, aber die Dateien sind viel kleiner als aufgeblähte XML-Dateien. (Ich gehe davon aus, dass es die Daten in einem binären Format anstelle von Text wie xml speichert)
Der einzige Nachteil, den ich mir dabei vorstellen kann, ist, dass wenn Ihre Daten verfälscht oder in einer Weise durcheinander gebracht werden, die Karvonite nicht mag, Sie dem Schöpfer ausgeliefert sind, es sei denn, Sie wissen, wie die Struktur der Daten aufgebaut ist Daten funktionieren.
Wenn Sie angeben, wie Ihre Daten gespeichert / geladen werden sollen, öffnen Sie einfach den zugehörigen Persistenz-Editor, importieren Ihre Assembly mit allen Datenobjekten und aktivieren einige Kontrollkästchen, um anzuzeigen, welche Objekte unterstützt werden sollen und welche Felder / Eigenschaften gespeichert werden sollen.
Es könnte einen Versuch wert sein. Da Sie C # verwenden, passt dies genau zu Ihrer Sprache, da es mit XNA funktioniert (Windows, Xbox360 und Windows Phone 7, an denen Sie meines Erachtens interessiert sind, seit Sie das iPhone erwähnt haben?).
Bearbeiten: Gerade bemerkt, dass Sie nur C # für die Tools verwenden. Dies würde wahrscheinlich nicht sehr gut in Ihren Workflow passen. Aus irgendeinem Grund hatte ich XNA im Kopf.
quelle