Konvertierung der Map von Minecraft 1.12 auf 1.13 durchführen

Vor einigen Wochen erschien Version 1.13 des Open-Word-Spieles Minecraft. Im Zuge dieser Aktualisierung wurden unter anderem die Daten der Blöcke verändert. Beim Erzeugen der Weltkarte über die freie Minecraft-Rendersoftware Mapcrafter traten nach dem Update Probleme auf.

Nur die bereits konvertierten Chunks werden gerendert

Während der Server ohne Probleme lief, wurden in der Karte nur bestimmte Chunks gerendert. Der Grund hierfür war das nur die Chunks in das neue Format der Version 1.13 konvertiert wurden, die von den Spielern auf dem Server besucht worden waren. Alle anderen Chunks lagen noch im Format der Version 1.12 vor. Eine Lösung für dieses Problem schafft der mit 1.13 neu eingeführte Kommandozeilen-Parameter –forceUpgrade des Minecraft-Servers. Wenn man diesen entsprechend startet:

java -Xmx4096M -Xms2048M -jar minecraft_server.jar nogui --forceUpgrade

beginnt der Server alle Chunks in das neue Format zu überführen:

[06:42:34] [Server thread/INFO]: Starting minecraft server version 1.13.1
...
[06:42:34] [Server thread/INFO]: Forcing world upgrade!
[06:42:34] [Server thread/INFO]: Counting chunks...
[06:42:48] [Server thread/INFO]: Upgrading structure data...
[06:42:48] [Server thread/INFO]: 0% completed (0 / 1630135 chunks)...
[06:42:49] [Server thread/INFO]: 0% completed (0 / 1630135 chunks)...
..
[08:52:58] [Server thread/INFO]: 99% completed (1629866 / 1630135 chunks)...
[08:52:59] [Server thread/INFO]: 99% completed (1630017 / 1630135 chunks)...
[08:53:00] [pool-4-thread-1/INFO]: World optimizaton finished after 7812721 ms

Je nach der Größe der eigenen Welt kann dieser Vorgang durchaus einige Stunden in Anspruch nehmen. Nachdem alle Chunks konvertiert wurden, funktioniert das Rendering der Weltkarte wieder wie gewohnt.

3DS Bibliothek für C#

Es gibt unter http://code.google.com/p/lib3ds/ ein Google Code Projekt welches eine Bibliothek zum lesen und schreiben von 3DS implementiert. Leider gab es bis vor kurzem keine freie 3DS Bibliothek für .NET respektive Mono. Nun gibt es unter http://code.google.com/p/lib3dsnet/ eine Portierung der lib3ds, welche wie das Original unter LGPL steht.

Die Bibliothek unterstützt dabei nicht nur das lesen und schreiben, sondern auch alle möglichen Arten von 3DS Nodes wie Kameras oder Meshes. Auch die Transformation der Objekte zueinander wird in dieser Bibliothek vorgenommen. In Grenzen kommt lib3ds.Net auch mit defekten 3DS Dateien zurecht. Nach den ersten Tests funktioniert die Bibliothek tadellos :)

Weitere Informationen gibt es unter:
http://en.wikipedia.org/wiki/.3ds

Das TMX Format

Auf der Website http://www.mapeditor.org gibt es einen freien Tilebasierten Mapeditor names Tiled. Der Editor wurde in Java geschrieben und wird unter anderem von Projekten wie The Mana World (http://www.themanaworld.org) benutzt.

Das Standardformat dieses Editores ist TMX. Dabei handelt es sich um eine XML Datei in der die Daten kodiert sind. Vor einiger Zeit war ich damit beschäftigt einen Reader für das Format zu schreiben. Leider ist die Dokumentation des Formates sehr lückenhaft, aber dank einiger tatkräftiger Hilfe auf der Mailingliste war der Reader nach einer Weile dann doch fertig. Doch nun zum TMX Format. Eine TMX Datei könnte z.B. so aussehen: ow-testmap.tmx

Als erstes kommt der map Tag in dem alle anderen tags untergeordnet sind. Der erste Tag von Interesse ist dann der tileset Tag. In diesem Tag stehen der Name des Tilesets, die FirstGID (dazu später mehr), die Breite und Höhe der Tiles sowie das Quellbild des Tilesets.

Nachdem die Tilesets definiert sind beginnen auch schon die Layer Definitionen. Eine Karte kann aus mehreren Layern bestehen z.B. einem Kollisionlayer. Im Layer Tag stehen der Name, die Breite und Höhe des Layers. Darunter folgt bei komprimierten Karten (die Standardeinstellung von Tiled) der Tag data mit dem Attribut encoding. In unserem Beispiel ist die Kodierung Base64 und die Kompression gzip. Um an die Daten des Layers zu kommen muss man den von den Data Tags eingeschlossen String nehmen und mittels Base64 decodieren. Anschließend erhält man ein Byte Array. Dieses Byte Array muss dann noch mittels des gzip Algorithmus dekomprimiert werden. Bei dieser Aktion kommt am Ende auch wieder ein Byte Array heraus.

In diesem Byte Array stehen dann die Tilenummern drin und zwar in Form von 4 Byte Integers (Little Endian). Hat man z.B. eine 2×2 Karte so würden die Tiles in folgender Reihenfolge kommen: 0,0 – 0,1 – 1,0 – 1,1.

Nun stellt sich nur noch die Frage wie man diese Tilenummern interpretiert. Und dabei kommt jetzt die FirstGID des Tileset zum tragen. Nehmen wir an das wir die Tilenummer 270 auslesen. Um nun zu ermitteln zu welchem Tileset die Nummer gehört prüfen wir in welches Tileset in diesem Bereich liegt und stellen fest das das Tileset desert2 genau in diesem Bereich liegt. Dann rechnet man noch Tilesetnummer – FirstGID und schon hat man die Tilesetnummer und das Tileset (in diesem Fall 11). Nun wissen wir das das Tile das elfte Tile im Tileset desert2 ist.