Mit einem sehr kleinen Clojure-Programm lässt sich im Rahmen eines proof of concept aus sowas
Code:
<drasa_dialog>
<daten>
<inhalt id="alrik_sturmfels_id">Gespräch mit Alrik Sturmfels</inhalt>
<redner kennzeichen="a" id="loc01_alrik_sturmfels">Alrik Sturmfels</redner>
<redner kennzeichen="b" id="">Held</redner>
</daten>
<texte>
<a>Seid gegrüßt. Alrik Sturmfels mein Name. Ihr wollt sicher auch nach Ferdok?</a>
<b>Ich grüße Euch auch. Ich heiße <heldenname/>. Ja, ich werde dort erwartet.</b>
<a>So wie es aussieht, wird man dort noch länger auf Euch warten müssen. Ferdok ist abgeriegelt und die Gardisten lassen niemanden weiterreisen. Hoffentlich ist das bald vorbei.</a>
<b>Ja, das habe ich schon erfahren. Da ich jetzt auch hier festsitze, werde ich mich zunächst einmal umschauen.</b>
<a></a>
<a>Da seid Ihr zu beneiden. Ich kann hier nicht weg. Muss auf meine Sachen aufpassen. Sonst wird noch etwas gestohlen. Ich bin nämlich Händler, müsst Ihr wissen.</a>
<b>Tatsächlich? Kann ich dann Eure Waren einmal sehen?</b>
<a>Nein, leider nicht. Dazu müsste ich die Sachen erst mal auspacken. Danach steht mir überhaupt nicht der Sinn. Aber vielleicht...</a>
<b>Ja?</b>
<a>Wie schon gesagt, ich kann hier leider nicht weg. Und die Warterei hat mich hungrig und durstig gemacht. Ich mache Euch folgenden Vorschlag. Hier habt Ihr fünf Silbertaler. Damit geht Ihr für mich zum Avestreuer Gasthaus, dem Scharfen Schwert, und lasst Euch von Wirt Thalion ein kleines Proviantpaket für mich schnüren. Zum Dank lasse ich Euch meine Waren sehen und Ihr bekommt noch einen ordentlichen Rabatt von mir. Einverstanden?</a>
<b>Einverstanden. Bis später.</b>
</texte>
</drasa_dialog>
das hier
Code:
({:satz "Seid gegrüßt. Alrik Sturmfels mein Name. Ihr wollt sicher auch nach Ferdok?", :uuid "bf6da7fe-b3c7-4eb6-b232-0e3584401683"} {:satz "Ich grüße Euch auch. Ich heiße <heroName>. Ja, ich werde dort erwartet.", :uuid "8e86b3c9-2b82-4de7-969d-a9094a8e045c"} {:satz "So wie es aussieht, wird man dort noch länger auf Euch warten müssen. Ferdok ist abgeriegelt und die Gardisten lassen niemanden weiterreisen. Hoffentlich ist das bald vorbei.", :uuid "00105582-78e9-4b60-bd7c-14f16a0c492e"} {:satz "Ja, das habe ich schon erfahren. Da ich jetzt auch hier festsitze, werde ich mich zunächst einmal umschauen.", :uuid "b45348a0-bb00-4b74-8a34-815ed059e8d9"} {:satz "", :uuid "09a811ec-81ee-4559-a91f-7afda0322245"} {:satz "Da seid Ihr zu beneiden. Ich kann hier nicht weg. Muss auf meine Sachen aufpassen. Sonst wird noch etwas gestohlen. Ich bin nämlich Händler, müsst Ihr wissen.", :uuid "6fcb5a4b-95fd-4238-b640-107779c53a89"} {:satz "Tatsächlich? Kann ich dann Eure Waren einmal sehen?", :uuid "71134db2-bafb-459d-9bc4-537fbacd808b"} {:satz "Nein, leider nicht. Dazu müsste ich die Sachen erst mal auspacken. Danach steht mir überhaupt nicht der Sinn. Aber vielleicht...", :uuid "14d27f00-088b-403e-91a7-6cf0b4f47a97"} {:satz "Ja?", :uuid "d8b9b9b7-371e-46bb-8424-adb8a4fae000"} {:satz "Wie schon gesagt, ich kann hier leider nicht weg. Und die Warterei hat mich hungrig und durstig gemacht. Ich mache Euch folgenden Vorschlag. Hier habt Ihr fünf Silbertaler. Damit geht Ihr für mich zum Avestreuer Gasthaus, dem Scharfen Schwert, und lasst Euch von Wirt Thalion ein kleines Proviantpaket für mich schnüren. Zum Dank lasse ich Euch meine Waren sehen und Ihr bekommt noch einen ordentlichen Rabatt von mir. Einverstanden?", :uuid "e77f01d4-3895-4197-bdb3-fc7c61182d54"} {:satz "Einverstanden. Bis später.", :uuid "1993d641-a80b-4c78-9525-8fcb53295885"})
machen.
Damit das nützlich ist, muss natürlich noch einiges geschehen. Es müssen weitere Daten in die Datensätze. Diese müssen als SQL INSERT-staments ausgegeben werden, es muss Fallunterscheidungen geben usw. Die Frage ist z.B., ob das XML-Format so in Ordnung und welches Outputformat am sinnvollsten ist. Ich bin gespannt auf Kritik und Anregungen.
Ja, ich denke das sieht vom Ansatz her schon mal recht gut aus. Nur zum Verständnis: man legt eine XML Datei an und das Programm würde dann den entsprechenden SQL Code für die Datenbanken erzeugen?
11.11.2016, 23:11 (Dieser Beitrag wurde zuletzt bearbeitet: 11.11.2016, 23:20 von Rabenaas.)
Ja, der Input ist eine XML-Datei. Output ist eine Textdatei mit den entsprechenden SQL-Anweisungen. Das Programm greift aber nicht direkt auf SQLite zu (was theoretisch möglich wäre).
Kleines Update
Code:
({:satz "Seid gegrüßt. Alrik Sturmfels mein Name. Ihr wollt sicher auch nach Ferdok?", :redner "loc01_alrik_sturmfels", :uuid "e90ff2c0-6545-474c-81a9-59b88e70ef61"} {:satz "Ich grüße Euch auch. Ich heiße <heroName>. Ja, ich werde dort erwartet.", :redner "hero", :uuid "26370d0f-b9e8-455e-8fcf-4a711339ad89"} {:satz "So wie es aussieht, wird man dort noch länger auf Euch warten müssen. Ferdok ist abgeriegelt und die Gardisten lassen niemanden weiterreisen. Hoffentlich ist das bald vorbei.", :redner "loc01_alrik_sturmfels", :uuid "3bf987fa-9ecc-4cfd-b387-96bfb54f8dbd"} {:satz "Ja, das habe ich schon erfahren. Da ich jetzt auch hier festsitze, werde ich mich zunächst einmal umschauen.", :redner "hero", :uuid "278ec16c-d699-4a00-b7d6-1925c71f54ef"} {:satz "", :redner "loc01_alrik_sturmfels", :uuid "4499b965-7dbe-40f1-a158-3890168731a6"} {:satz "Da seid Ihr zu beneiden. Ich kann hier nicht weg. Muss auf meine Sachen aufpassen. Sonst wird noch etwas gestohlen. Ich bin nämlich Händler, müsst Ihr wissen.", :redner "loc01_alrik_sturmfels", :uuid "c630c690-1a12-414b-b99f-509ce036c5f2"} {:satz "Tatsächlich? Kann ich dann Eure Waren einmal sehen?", :redner "hero", :uuid "6bafd743-d177-48db-b6f0-80e74387f786"} {:satz "Nein, leider nicht. Dazu müsste ich die Sachen erst mal auspacken. Danach steht mir überhaupt nicht der Sinn. Aber vielleicht...", :redner "loc01_alrik_sturmfels", :uuid "490ee491-4694-4347-ab76-755ccaa746b3"} {:satz "Ja?", :redner "hero", :uuid "68f5248b-dd4c-471f-81d1-76ec1ec94117"} {:satz "Wie schon gesagt, ich kann hier leider nicht weg. Und die Warterei hat mich hungrig und durstig gemacht. Ich mache Euch folgenden Vorschlag. Hier habt Ihr fünf Silbertaler. Damit geht Ihr für mich zum Avestreuer Gasthaus, dem Scharfen Schwert, und lasst Euch von Wirt Thalion ein kleines Proviantpaket für mich schnüren. Zum Dank lasse ich Euch meine Waren sehen und Ihr bekommt noch einen ordentlichen Rabatt von mir. Einverstanden?", :redner "loc01_alrik_sturmfels", :uuid "7583dcb7-6f9a-4a01-830a-c00224973718"} {:satz "Einverstanden. Bis später.", :redner "hero", :uuid "fd2b9a8f-3cbd-46cc-b52e-bf5cdf5a80a4"})
EDIT: CSV oder eine anderes Tabellenformat wäre aber genau so möglich wie SQL.
Was hat es mit dem Feld DialogSpeaker in _Story_Dialogs auf sich? Ist das der NPC, den man anspricht, damit der Dialog losgeht?
Der Stand ist im Moment
Code:
INSERT INTO "_Locale" VALUES ("cde0a4c5-2e93-4d1a-9439-5bc01b9c0c63", "Seid gegrüßt. Alrik Sturmfels mein Name. Ihr wollt sicher auch nach Ferdok?")
INSERT INTO "_Locale" VALUES ("a9b78bbb-bc36-4dbf-a2c1-640495dc1d97", "Ich grüße Euch auch. Ich heiße <heroName>. Ja, ich werde dort erwartet.")
INSERT INTO "_Locale" VALUES ("0b2f2005-d7b5-4022-8132-dba053415b72", "So wie es aussieht, wird man dort noch länger auf Euch warten müssen. Ferdok ist abgeriegelt und die Gardisten lassen niemanden weiterreisen. Hoffentlich ist das bald vorbei.")
INSERT INTO "_Locale" VALUES ("91139843-869d-4938-9772-29c9834fbf63", "Ja, das habe ich schon erfahren. Da ich jetzt auch hier festsitze, werde ich mich zunächst einmal umschauen.")
INSERT INTO "_Locale" VALUES ("fd288617-d729-48d9-8521-62620de9ccd8", "")
INSERT INTO "_Locale" VALUES ("c7c24bf1-15d6-4849-b036-8995da879368", "Da seid Ihr zu beneiden. Ich kann hier nicht weg. Muss auf meine Sachen aufpassen. Sonst wird noch etwas gestohlen. Ich bin nämlich Händler, müsst Ihr wissen.")
INSERT INTO "_Locale" VALUES ("18e83be4-04e0-431a-ae9d-45046b65b325", "Tatsächlich? Kann ich dann Eure Waren einmal sehen?")
INSERT INTO "_Locale" VALUES ("a24bbae3-90b9-48c6-a035-235459175e60", "Nein, leider nicht. Dazu müsste ich die Sachen erst mal auspacken. Danach steht mir überhaupt nicht der Sinn. Aber vielleicht...")
INSERT INTO "_Locale" VALUES ("745faf28-d4ec-41c9-b5e1-b96641c0d38c", "Ja?")
INSERT INTO "_Locale" VALUES ("aef9b14b-10d7-47aa-af88-b7c7b050532a", "Wie schon gesagt, ich kann hier leider nicht weg. Und die Warterei hat mich hungrig und durstig gemacht. Ich mache Euch folgenden Vorschlag. Hier habt Ihr fünf Silbertaler. Damit geht Ihr für mich zum Avestreuer Gasthaus, dem Scharfen Schwert, und lasst Euch von Wirt Thalion ein kleines Proviantpaket für mich schnüren. Zum Dank lasse ich Euch meine Waren sehen und Ihr bekommt noch einen ordentlichen Rabatt von mir. Einverstanden?")
INSERT INTO "_Locale" VALUES ("4d2957db-f151-4b7b-b992-7b79dbe07caa", "Einverstanden. Bis später.")
Aber DialogSpeaker kommt doch in _Story_Dialogs vor, ist also für den gesamten Dialog eindeutig, da es insgesamt nur einen Eintrag in _Story_Dialogs gibt. Am Dialog können aber doch mehrere Sprecher beteiligt sein. Wo liegt mein Fehler?
Der Speaker in _StoryDialogs ist der NPC, den man anklicken muss, um den Dialog zu beginnen. Wer dann während des Dialogs etwas sagt, ist dann vom Dialog abhängig.
INSERT INTO "_Locale" VALUES ("6d5fe9de-2615-4e53-a9d4-6885ae24f84a", "Seid gegrüßt. Alrik Sturmfels mein Name. Ihr wollt sicher auch nach Ferdok?")
INSERT INTO "_Locale" VALUES ("a130243f-ba4f-49f5-a06d-388b5f70c07b", "Ich grüße Euch auch. Ich heiße <heroName>. Ja, ich werde dort erwartet.")
INSERT INTO "_Locale" VALUES ("94e79a06-1201-43bd-826e-3fb1de88b6f0", "So wie es aussieht, wird man dort noch länger auf Euch warten müssen. Ferdok ist abgeriegelt und die Gardisten lassen niemanden weiterreisen. Hoffentlich ist das bald vorbei.")
INSERT INTO "_Locale" VALUES ("cce1b9b0-e984-4063-8cd0-b1ccbf875036", "Ja, das habe ich schon erfahren. Da ich jetzt auch hier festsitze, werde ich mich zunächst einmal umschauen.")
INSERT INTO "_Locale" VALUES ("659b9803-6e4b-4f53-b476-cc4f6df4ffef", "")
INSERT INTO "_Locale" VALUES ("0829e3ab-f79d-4dbc-9823-662db0f4d446", "Da seid Ihr zu beneiden. Ich kann hier nicht weg. Muss auf meine Sachen aufpassen. Sonst wird noch etwas gestohlen. Ich bin nämlich Händler, müsst Ihr wissen.")
INSERT INTO "_Locale" VALUES ("82a2d0b5-8757-4bc5-a791-a0defaea5666", "Tatsächlich? Kann ich dann Eure Waren einmal sehen?")
INSERT INTO "_Locale" VALUES ("a276dbab-8eba-40e5-be78-876b091c8bbb", "Nein, leider nicht. Dazu müsste ich die Sachen erst mal auspacken. Danach steht mir überhaupt nicht der Sinn. Aber vielleicht...")
INSERT INTO "_Locale" VALUES ("c94dad7b-b978-4a0c-b95e-088b8e63ad52", "Ja?")
INSERT INTO "_Locale" VALUES ("adabef78-cd2d-431f-b6e7-b26d1e3e99ce", "Wie schon gesagt, ich kann hier leider nicht weg. Und die Warterei hat mich hungrig und durstig gemacht. Ich mache Euch folgenden Vorschlag. Hier habt Ihr fünf Silbertaler. Damit geht Ihr für mich zum Avestreuer Gasthaus, dem Scharfen Schwert, und lasst Euch von Wirt Thalion ein kleines Proviantpaket für mich schnüren. Zum Dank lasse ich Euch meine Waren sehen und Ihr bekommt noch einen ordentlichen Rabatt von mir. Einverstanden?")
INSERT INTO "_Locale" VALUES ("2bcba24c-26c4-4b36-87ff-0ae10f0bd325", "Einverstanden. Bis später.")
INSERT INTO "_Story_DialogTakes" VALUES (X'fabd3d3a677aec40bd82c6af9854f9e9', X'13b02b1178b7824f98c7126ea41dc051', "alrik_sturmfels_0", "loc01_alrik_sturmfels", "Take", "", ", 0, "", "", NULL, NULL, "X'dee95f6d1526534ea9d46885ae24f84a'", 0, X'000')
INSERT INTO "_Story_DialogTakes" VALUES (X'6385114b644a224a8a0f3191169a2d41', X'13b02b1178b7824f98c7126ea41dc051', "alrik_sturmfels_1", "hero", "Take", "", ", 0, "", "", NULL, NULL, "X'3f2430a14fbaf549a06d388b5f70c07b'", 0, X'000')
INSERT INTO "_Story_DialogTakes" VALUES (X'd45fb71abaa5ae4cafb9766a3d374d78', X'13b02b1178b7824f98c7126ea41dc051', "alrik_sturmfels_2", "loc01_alrik_sturmfels", "Take", "", ", 0, "", "", NULL, NULL, "X'069ae7940112bd43826e3fb1de88b6f0'", 0, X'000')
INSERT INTO "_Story_DialogTakes" VALUES (X'591eb5c11012544e8ff5fe72f55fbc0f', X'13b02b1178b7824f98c7126ea41dc051', "alrik_sturmfels_3", "hero", "Take", "", ", 0, "", "", NULL, NULL, "X'b0b9e1cc84e963408cd0b1ccbf875036'", 0, X'000')
INSERT INTO "_Story_DialogTakes" VALUES (X'3296bcd60a79ed4f8128fded2649fc00', X'13b02b1178b7824f98c7126ea41dc051', "alrik_sturmfels_4", "loc01_alrik_sturmfels", "Take", "", ", 0, "", "", NULL, NULL, "X'03989b654b6e534fb476cc4f6df4ffef'", 0, X'000')
INSERT INTO "_Story_DialogTakes" VALUES (X'830c79fd5016c94e8e1a35a044f34c4a', X'13b02b1178b7824f98c7126ea41dc051', "alrik_sturmfels_5", "loc01_alrik_sturmfels", "Take", "", ", 0, "", "", NULL, NULL, "X'abe329089df7bc4d9823662db0f4d446'", 0, X'000')
INSERT INTO "_Story_DialogTakes" VALUES (X'8834a06244d659448fd1aeaac2a77322', X'13b02b1178b7824f98c7126ea41dc051', "alrik_sturmfels_6", "hero", "Take", "", ", 0, "", "", NULL, NULL, "X'b5d0a2825787c54ba791a0defaea5666'", 0, X'000')
INSERT INTO "_Story_DialogTakes" VALUES (X'8b59694084ee2643b3e046be39ab0867', X'13b02b1178b7824f98c7126ea41dc051', "alrik_sturmfels_7", "loc01_alrik_sturmfels", "Take", "", ", 0, "", "", NULL, NULL, "X'abdb76a2ba8ee540be78876b091c8bbb'", 0, X'000')
INSERT INTO "_Story_DialogTakes" VALUES (X'74ba56625e178e4891b478590b473074', X'13b02b1178b7824f98c7126ea41dc051', "alrik_sturmfels_8", "hero", "Take", "", ", 0, "", "", NULL, NULL, "X'7bad4dc978b90c4ab95e088b8e63ad52'", 0, X'000')
INSERT INTO "_Story_DialogTakes" VALUES (X'09272469e6f2a842ad8295b621441d0d', X'13b02b1178b7824f98c7126ea41dc051', "alrik_sturmfels_9", "loc01_alrik_sturmfels", "Take", "", ", 0, "", "", NULL, NULL, "X'78efabad2dcd1f43b6e7b26d1e3e99ce'", 0, X'000')
INSERT INTO "_Story_DialogTakes" VALUES (X'61d49b411ea09749baae7b6d7983a025', X'13b02b1178b7824f98c7126ea41dc051', "alrik_sturmfels_10", "hero", "Take", "", ", 0, "", "", NULL, NULL, "X'4ca2cb2bc426364b87ff0ae10f0bd325'", 0, X'000')
13.11.2016, 19:29 (Dieser Beitrag wurde zuletzt bearbeitet: 13.11.2016, 19:33 von Lord Demon.)
Super. Die DialogTakes enthält aber noch ein paar Fehler. Zum einen hast du die Spalte DialogId als Text weggelassen und die Felder für ConditonRef und ConditionBlock dürfen nicht leer bleiben, sondern müssen ausgefüllt werden. Wenn ein Take nicht von einer Bedingung abhängig ist, steht hier X'00000000000000000000000000000000'. Ansonsten werden diese Felder mit den entsprechenden Guids aus der Tabelle _Scripts_Conditions ausgefüllt. Damit es nicht zu einem Absturz kommt, muss diese Condition natürlich vorher angelegt werden.
Für jeden Dialog wird ein eindeutiger Bezeichner als Blob und als Text angelegt. Beide Werte müssen auch in der _Story_DialogTakes angegeben werden. Danach kommt eine eindeutige Id für jeden Take. Um den Überblick zu behalten verwende ich die DialogId und hänge eine fortlaufende Zahl an. In deinem Beispiel ist die DialogId komm_mit_id, die TakeId für den ersten Take wäre dann komm_mit_01.
Das macht gar nichts, wenn TakeEmote gefüllt ist. Üblicherweise werden bei den Dialogen alle Felder mit einem leeren String ausgefüllt und bleiben nicht leer. TakeEmote ist übrigens für die Animation während des Sprechens zuständig. Das machen wir sowieso immer erst später.
Ich sag jetzt erst mal Danke für die Zeit, die du in die Entwicklung des Programms gesteckt hast. Es funktioniert alles wunderbar. Da ist nur noch ein kleiner Fehler bei der _Story_DialogTakes. Die erste Zeile dieser Tabelle dient zur Initiallisierung des Dialogs und hat keinen Bezug zu einer gesprochenen Textzeile. Deshalb weicht der Inhalt dieser Zeile von den anderen Zeilen ab. Die Felder TakeId und TakeType bekommen als Wert StartState und TakeLocaId bekommt X'00000000000000000000000000000000', da ja kein Text für diese Zeile vorhanden ist.
Hab's gerade mal etwa ausführlicher getestet. Zwei kleine Fehler sind noch drin: in der Tabelle _Story_Dialogs wird der Speaker ins falsche Feld gesetzt, er landet in DialogGroup, muss aber in DialogSpeaker. Außerdem fehlt bei der SQL Ausgabe das Semikolon am Ende jeder Anweisung.
(18.11.2016, 11:54)Lord Demon schrieb: Hab's gerade mal etwa ausführlicher getestet. Zwei kleine Fehler sind noch drin: in der Tabelle _Story_Dialogs wird der Speaker ins falsche Feld gesetzt, er landet in DialogGroup, muss aber in DialogSpeaker.
Ist erledigt.
(18.11.2016, 11:54)Lord Demon schrieb: Hab's gerade mal etwa ausführlicher getestet. Zwei kleine Fehler sind noch drin: in der Tabelle _Story_Dialogs wird der Speaker ins falsche Feld gesetzt, er landet in DialogGroup, muss aber in DialogSpeaker. Außerdem fehlt bei der SQL Ausgabe das Semikolon am Ende jeder Anweisung.
Ok, war mir nicht sicher. Manche Engines reicht ein newline.