PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Der RPG-Reader



gRuFtY
20.01.2013, 14:54
Endlich ist es soweit. Hat auch lange genug gedauert. Wie auf dem Winter-BMT 12/13 angekündigt veröffentliche ich heute die erste Alpha meines RPG-Readers. Ich erhebe keinen Anspruch darauf, dass das Ding gut funktionieren würde oder jemand anderes außer mir schon sinnvoll damit arbeiten könnte, aber ich hoffe, dass sich das mit der Zeit bessert. ;-)


Was ist der RPG-Reader?

Wer schon einmal eine meiner Präsentationen auf dem BMT zum RPG-Reader gesehen hat, wird es wissen: Der RPG-Reader ist ein in Java geschriebener Parser für RPG-Maker-2000-Spiele. Für alle, die jetzt nur Bahnhof verstanden haben: Der RPG-Reader ermöglicht es Programmieren in der Programmiersprache Java auf RPG-Maker-2000-Projekte zuzugreifen, Dinge aus diesen auszulesen oder sie zu bearbeiten. Beispiel gefällig? Es ist zum Beispiel möglich, ein kleines Script bzw. Programm zu schreiben um ein ganzes Projekt nach der Verwendung eines bestimmten Swiches zu durchsuchen, wie es im RPG-Maker 2003 schon eingebaut ist. Oder schon mal gedacht: "Verdammt, bei dem Wort hab ich mich oft verschrieben. Muss ich das jetzt überall suchen und ändern?" - Nein, auch das kann der PRG-Reader automatisieren. Auch komplexere Abfragen wie "Welche Events, die auf Seite 5 die Grafik xy verwenden und Switch s als Startbedingung gesetzt haben, rufen auf Seite 7 das Commen Event c auf und kopieren anschließend den Inhalt von Variabel v nach Variabel w?" sind möglich. Oder schon mal ein Picture-basiertes Menü bauen wollen? Kommt euch folgender Codeschnipsel bekannt vor?


if id == 1:
showPicture 1
end
if id == 2:
showPicture 2
end
...

Bei 50 Pictures eine mühselige Arbeit, aber mit dem passenden RPG-Reader-Script könnt ihr diesen Code automatisch generieren lassen. (Oder ihr verwendet Cherrys PicPointerPatch, was in diesem Beispiel nützlicher wäre ;) ).


Was ist der RPG-Reader nicht?

All das oben genannte. All die Anwendungsbeispiele sind Ideen, was man mit dem RPG-Reader tun kann, aber er selbst ist nur eine Library, eine Bibliothek, auf die andere Programme zugreifen können. Er ist nicht dazu gedacht, dass man ihn starten kann oder er eine grafische Benutzeroberfläche anzeigt. Für alles, was oben aufgelistet wurde, bedarf es Programmierkenntnissen in Java, aber der RPG-Reader erlaubt es Leuten, die diese Sprache beherrschen, auf RPG-Maker-2000-Spiele zugreifen zu können, ohne sich selbst damit beschäftigen zu müssen, was die Bits und Bytes in den Dateien einen Maker-Projekts zu bedeuten haben.


Ein wenig Geschichte...

Der RPG-Reader entstammt einer älteren Idee von mir, welche sicher schon 5 oder 6 Jahre alt, und seit 4-5 Jahren tot ist. Alles begann damit, dass ich einen Converter schreiben wollte, um RPG-Maker-2000-Spiele in RPG-Maker-XP-Spiele zu konvertieren. Anfangs noch ohne irgendwelche Dokumentationen machte ich mich mit einem Zettel, einen Stift und einem Hex-Editor daran, das Map-Format des RPG-Maker-2000 Byte für Byte zu lesen, zu entschlüsseln und zu verstehen. Schnell merkte ich, dass ich auch noch einen Taschenrechner brauchen würde, der Gott sei Dank auch sinnvoll Hexadezimalzahlen und Dezimalzahlen hin und her konvertieren konnte. Trotzdem stieß ich immer wieder auf Hindernisse.
Bald starb die Idee eines Converters und machte der Idee einer Software platz, die der heutigen Idee des Readers bereits sehr ähnelte, aber ein Kommandozeilen-Programm werden sollte. Die Idee verwarf ich schnell, denn wie die Syntax für die Befehle aussehen sollte, wusste ich nicht. Übrig blieb die Idee des RPG-Readers.
Anfangs schrieb ich den RPG-Reader noch in Ruby - einer Sprache, von der ich mir dachte, dass es in der RPG-Maker-Szene so einige Leute geben würde, die sie nutzten. Als ich jedoch das erste Mal einen großen Test laufen ließ, nachdem das Map-Format entschlüsselt war, gab ich die Ruby-Implementierung auf. Der "Test" bestand darin, im Spiel Sternenkind-Saga alle stellen zu finden, an denen noch EXP vergeben wurden (Sternenkind-Saga nutzt mittlerweile ein eigenes Leveling-System). Da der Test fast 45 Minuten lief, was viel zu lange war, gab ich Ruby auf und wechselte zu Java, in dem naiven Glauben, dass Java generell schneller als Ruby sei. (Ob dem so ist, ist natürlich Situationsabhängig. Heute glaube ich, dass ein Neuanfang in Ruby auch bessere Laufzeiten gehabt hätte, aber naja, ich bin halt zu Java gewechselt und hab's nie bereut).
Die Java-Implementierung ist nun mittlerweile auch mehr als 2 Jahre alt. Ich weiß es nicht so genau. Immer wieder hab ich behauptet, so gut wie fertig zu sein, bin es aber nie wirklich geworden, daher gibt es nun eine Alpha-Version des Readers ;-)


Zum Funktionsumfang

Der RPG-Reader ist vollständig benutzbar und kann alle drei relevanten Dateiformate (lmu, lmt, ldb) lesen und schreiben. Das Map-Format lmu sowie der Map-Tree lmt sind dabei vollständig unterstützt, beim Datenbankformat ldb fehlt derzeit noch eine Unterstützung für die Vocabular, diese wird aber hoffentlich zeitnah auch verfügbar werden.
Zu beachten ist, dass einige Listen/Arrays Null-Indiziert sind, andere bei Eins zu zählen anfangen. Hier wird versucht, den Maker zu mimen: Alle Dinge, deren Zählung im Maker bei 1 anfängt, sind auch im Reader Eins-Indiziert. Wäre ja auch seltsam, wenn im Maker eine Event-Seite Nr.1 ist, im Reader aber plötzlich die selbe Seite Seite 0 heißt. Ich bin mir aber noch nicht sicher, ob dies überall konsistent ist.
Viele Dinge sind noch unschön gelöst. Zum Beispiel sind EventCommands schwierig zu bauen, da man viele Informationen zum Befehl per Hand eintragen muss. Eine Factory für EventCommands wäre sinnvoll, Ideen existieren in meinem Kopf, sind aber nicht konkret. Wer dazu Gedanken hat, darf sie mir gern mitteilen.
Sicher gibt es weitere Dinge, die noch unschön gelöst sind, aber zumindest ist die Software verwendbar und hey: Je mehr Rückmeldung ich bekomme, um so motivierter bin ich, den Kram auszubessern ;)


Zukunft

Zwei Dinge sind für die Zukunft geplant. Zum einem RPGit, eine Software, die auf dem RPG-Reader aufbaut und es via Git ermöglichen soll, dass mehrere Entwickler gleichzeitig versionsverwaltet an einem RPG-Maker-2000-Projekt arbeiten können. Sobald sich in dieser Richtung mehr tut (was nicht lange dauern sollte, schließlich wollen wir die Software Mitte des Jahres bei Sternenkind-Saga einsetzen), werde ich euch darüber informieren.
Zum Anderen ist durchaus angedacht, den RPG-Maker 2003 zu unterstützen. Ich selbst nutze jedoch den 2k3 nicht und würde erst in einem Jahr frühestens dazu kommen, mich darum zu kümmern, daher: Wer Interesse daran hat, einen Fork, der den 2003er unterstützt, zu maintainen, der lege los. Wenn ich noch darüber informiert wäre, damit ich nicht doch selbst irgendwann anfange, wäre das klasse ;-)


Der Download

Einen Download im klassischen Sinne gibt es nicht, statt dessen einen Link zum Github des Projektes: https://github.com/Gotos/RPGReader
Hinweis: Ich werde in der kommenden Woche mal die Präsentation auf GitHub überarbeiten bzw. aufräumen.


Dokumentation

Der RPG-Reader ist mit JavaDocs verstehen, die allerdings teils nur automagisch generiert sind. Nach und nach werde ich diese verbessern, hoffe aber, sie reicht in der Zwischenzeit.
Ein kleines Getting Started will ich euch trotzdem anbieten:

Um eine Datenbank einzulesen, führt folgenden Code aus:


[...]
DataReader dr = DataReader.parseFile("/pfad/zum/projekt/rpg_rt.ldb");
try {
dr.nextUnitZeroID();
LuciferDatabase db = new LuciferDatabase(dr);
[...]
} catch (IOException e) {
e.printStackTrace();
}
[...]

Für Maps schreibt: LuciferMapUnit map = new LuciferMapUnit(dr);
Und für den Map-Tree: LuciferMapTree tree = new LuciferMapTree(dr);

Der Rest wird hoffentlich aus den Javadocs ersichtlich... ;)


Abschlussworte:

Ich werde hoffentlich ab in ca. 2 Wochen wieder mehr Zeit haben, mich um den Reader zu kümmern, als bisher dieses Jahr. Dennoch wollte ich mein Versprechen wahr machen und zeitnah nach dem BMT eine Alpha veröffentlichen. Ich hoffe sehr, dass man ihr nicht mehr als bei einer Alpha üblich anmerkt, dass es ein unaufgeräumtes Release ist, sondern es schon jetzt verwendbar ist und es überhaupt irgendwen außer mich interessiert ;)

Daen vom Clan
20.01.2013, 15:07
Oh ja, ich erinnere mich noch mit großer Freude daran wie extrem uns das geholfen hat bei SKS einige Sachen zu finden die noch Altlasten waren und von Denen wir wussten dass es richtig lange dauern würde sie mit konventionellen Methoden ausfindig zu machen, wie beispielsweise die oben beschriebene XP-Vergabe an den unmöglichsten Stellen im Spiel! ^^

Sehr faszinierend, was manche Leute aus dem Maker machen und herausholen können, wirklich gute Arbeit. :)

V-King
20.01.2013, 16:16
Ein Hoch auf die Technik \o/

Echt ein super Teil, ich finds super :)

Cherry
20.01.2013, 19:02
Hast du die Probleme jetzt ohne mich gelöst? Mäh. ;)

gRuFtY
20.01.2013, 22:59
@Cherry: Nein, hab ich nicht. Aber ich hatte noch nicht die Zeit gefunden, das mit dir komplett zu durchsprechen, deshalb ist ja noch kein Arbeiten mit dem Vocab möglich ;) Ich melde mich die Tage mal, sobald ich etwas Zeit finde, das Vocab steht nämlich jetzt weit oben auf meiner ToDo. :)

R.D.
21.01.2013, 14:57
<3

@Edit:
Du kannst auf GitHub zips mit dem Content erstellen! Sogar eigene zips hochladen wo dann nur noch die jar und die Doku drin ist :) (LONG LIVE GITHUB /o/)

netwarrior
23.01.2013, 21:00
Ich glaube ich habe dir diese Frage schon mal auf der BTM gestellt, aber ich frage trotzdem nochmal.

Auf dem Maker ist nur folgende IF-Abfrage möglich:


If Switch1= ON {
If Switch2= ON {
DO THIS
}
}
Könnte man ihn auf JAVA auch so schreiben und er könnte ihn zurück in den Maker richtig konvertieren:


If Switch1= ON && Switch2= ON {
DO THIS
}

netwarrior

gRuFtY
23.01.2013, 22:33
Das ginge so nicht direkt, da der Reader ja nicht die Technik des Makers verändert. Man kann aber natürlich zum Beispiel eine "Sprache" entwickeln, und einen Converter um diese in Makercode zu konvertien und dann für diese Sprache && als Sprachkonstrukt vorsehen.
Kurze Antwort also: Eher nicht, zumindest nicht so, wie ich vermute, dass du es meinst.

gRuFtY
28.01.2013, 21:38
Achtung!

Sowohl im Alpha-Release als auch in der aktuellen git-Fassung vom RPG-Reader haben sich noch große Bugs beim Schreiben der Datenbank versteckt. Nutzt diese Funktion vorerst nicht, ich versuche möglichst bald den oder die Fehler zu beheben. Allerdings hab ich derzeit viel Unistress, es kann also ein wenig dauern.

Aber als Entschädigung ein kleines Codebeispiel:


package tests;

import java.io.File;
import java.io.IOException;

import com.github.gotos.rpgreader.engine.DataReader;
import com.github.gotos.rpgreader.engine.LuciferEventCommand;
import com.github.gotos.rpgreader.engine.LuciferMapEvent;
import com.github.gotos.rpgreader.engine.LuciferMapEventPage;
import com.github.gotos.rpgreader.engine.LuciferMapUnit;

/**
* Main Class, the class that will be started.
*
* @author alina
*
*/
public class Main {


private Main() { }

/**
* This loops through the maps, hunting for switch 748
*
* @param args ignored
*/
public static void main(String[] args) {
DataReader dr;

//get Maps
for (String filename : new File("/home/alina/Downloads/SternenkindSaga").list()) {
if (filename.toLowerCase().startsWith("map")) {
dr = DataReader.parseFile("/home/alina/Downloads/SternenkindSaga/" + filename);
try {
dr.nextUnitZeroID();
LuciferMapUnit map = new LuciferMapUnit(dr);

for (LuciferMapEvent event : map.getEvents()) {
if (event != null) {
int i = 1;
for (LuciferMapEventPage page : event.getPages()) {
if (page != null) {
for (LuciferEventCommand command : page.getCommands()) {
if (command.type == LuciferEventCommand.CHANGE_SWITCH && command.data[1] == 748) {
System.out.println(
"Found on Map: " + filename + "! Event: "
+ event.getName() + " (" + event.getxPos()
+ "|" + event.getyPos() + "), Page: " + i);
}
}
}
}
i++;
}
}
} catch (IOException e) {
System.out.print("Map broken! ");
System.out.println(filename);
}
}
}
}
}

Dieser Code durchsucht alle Maps von Sternenkind-Saga nach Change Switch befehlen, die den Switch 748 oder mehrere Switches, beginnend bei 748, betreffen und gibt aus, wo das passiert. Die Ausgabe könnte dann so aussehen:

Found on Map: Map0001.lmu! Event: EV0094 (39|9), Page: 1
Found on Map: Map0001.lmu! Event: EV0096 (40|8), Page: 1
Found on Map: Map0001.lmu! Event: EV0097 (40|10), Page: 1

Daen vom Clan
28.01.2013, 22:26
Wie geil!
Ein so schlimmes Spiel wie SKS mit seinen uralten Fehlern ist im Grunde die perfekte Spielwiese für so ein geniales Tool! ^^

gRuFtY
28.01.2013, 22:40
Wenn der Reader irgendwann scheinbar fehlerfrei SkS kopieren kann (sprich: einlesen und wieder schreiben kann), dann wird die Version, die das kann, den Namen 1.0.0 tragen ;)