Montag, 5. September 2011

[TechBlog] Einfach und schnell zum eigenen Dateiformat (Teil 1)


Einführung
Es gibt kaum ein Programm, das keine Daten speichern muss. Manche nutzen dafür Datenbanken oder auch Webservices, aber am häufigsten werden Dateien benutzt. Wenn es für die Daten bereits ein Format gibt, dann kann man natürlich dieses verwenden. Wenn man aber – wie wir – die Map eines Tower Defence-Spiels speichern möchte, dann muss man sich ein eigenes Format ausdenken.

Aufstellen der Anforderungen
Bevor man sein Format definiert, muss man sich zuerst klar machen, was es überhaupt leisten soll. Unser Mapformat, welches wir OTDM getauft haben, muss von unseren Programmen einfach zu verarbeiten sein, da wir nicht zu viel Zeit mit dem Lese- und Schreibcode verbringen wollen. Außerdem sollte das Format auch für Menschen lesbar sein, sodass man per Hand Änderungen vornehmen kann. Genauso sollte OTDM aber auch für andere Programmierer einfach zu implementieren sein. Zu guter Letzt muss es auch größere Maps in wenigen Kilobyte unterbringen können, da die Maps vom Server an die Clients verschickt werden sollen, falls sie dort nicht vorhanden sind.

Definieren des Formats
Wenn die Anforderungen klar sind, kann man sich daran wagen, das eigene Format festzulegen. Zuerst hat man die Wahl, etwas komplett eigenes zu erschaffen oder sein Format aus bereits vorhandenen Formaten zusammen zu setzen. Ein komplett eigenes Format ist unserer Meinung nach nur in wenigen Fällen sinnvoll, vor allem, weil es einen enormen Aufwand benötigt, bis das Programm es lesen und schreiben kann. Wir haben uns deshalb für die zweite Variante entschieden.
Dabei fiel unser Blick auf XML, da es sowohl von Menschen als auch von Computern verarbeitet werden kann. Gleichzeitig ist XML standardisiert und es gibt für fast alle Programmiersprachen fertige Bibliotheken. XML nimmt aber auch eine gewisse Sonderstellung ein, da es zwar einen XML-Standard gibt, der schreibt aber nur einige wenige Rahmenbedingungen vor, während der Rest vollkommen frei ist. Das ermöglicht eine große Flexibilität durch die man viele Daten (vor allem tabellarische oder baumstrukturähnliche) in XML darstellen kann.
Der Nachteil an XML ist, dass es als textbasiertes Format und durch seine Struktur viel Overhead speichert und so die Dateien sehr groß werden können. Für ein Format, das per Internet übertragen werden soll, ist das natürlich denkbar schlecht. Um nun trotzdem die Vorteile von XML nutzen zu können, haben wir uns dafür entschieden die XML-Daten zu komprimieren. Durch seinen Aufbau bedingt lässt sich XML sehr gut komprimieren, zum Teil auf nur 10% der Originalgröße. Dabei hatten wir die Wahl zwischen Zip, GZip und BZip2. BZip2 schied direkt am Anfang aus, da es nur minimal bessere Komprimierung bei erheblich größerem Rechenaufwand bietet. Zip und GZip dagegen sind ungefähr gleich (in unseren Tests). Der Unterschied für uns ist folgender: Zip kann mehrere Dateien speichern, die sich ohne temporäres Entpacken einzeln auslesen lassen. GZip dagegen speichert nur einen Stream, welcher komplett entpackt werden muss, selbst wenn man nur eine Datei lesen möchte. Wir haben uns deshalb für Zip entschieden.

In Teil 2
In Teil 2 zeigen wir, wie man solch ein Dateiformat mithilfe der #ziplib in C# lesen und speichern kann.

Eigene Erfahrungen, Anregungen und Verbesserungsvorschläge sind natürlich erwünscht!

2 Kommentare:

  1. XML ist eine sehr gute Wahl. Wenn ihr eine platzsparender Variante wollt, dann baut euch ein Tool, was aus XML Binary macht und andersrum. Dieses könnt ihr zum Konvertieren nutzen (wenn ihr eine dll draus macht und die exe des tools diese nur nutzt) und im Spiel hat ihr einen BinaryReader und einen XMLReader. Ich unterstütze euch da auch gerne ;) Mit zip halte ich für unpassend.

    AntwortenLöschen
  2. @Trommlbomml
    Klingt sehr interessant. Wenn du möchtest, kannst du mich / uns gerne persönlich kontaktieren. Dann könnten wir mal genauer über deine Idee diskutieren, würde mich sehr interessieren.
    Kontaktdaten: http://marius-stiller.de/other/OTD/phpbb/viewtopic.php?f=6&t=5

    Viele Grüße, Phil.

    AntwortenLöschen