VNLEWIKIGeschichten entwickeln. Welten verbinden.
Deutsch
VNLE Handbuch

GameMaker

← Inhalte ins Spiel einbauen

GameMaker · GML (struct_get / struct_exists)

Beginne mit einem sichtbaren Satz. Dieses kleine Beispiel liest direkt den echten Harbour-Export; es ist kein vollständiger Dialogplayer. Anschließend verbindest du die Daten mit deiner Spieloberfläche.

1 · Dateien und Szene vorbereiten

Füge story.json als Included File hinzu. Erstelle obj_dialogue und platziere eine Instanz im ersten Raum. Füge den Code in Create ein. Lege zusätzlich ein Draw GUI Event mit draw_text_ext(24, 24, dialogue_text, -1, 700); an. Der Einstieg verwendet den Desktop-Dateizugriff.

story.json · Exportdateien erklärt

2 · Den ersten Text anzeigen

// obj_dialogue: Create event. story.json is an Included File.
dialogue_text = "Cannot read story.json";
var file = buffer_load(working_directory + "story.json");
if (file >= 0) {
    var raw = buffer_read(file, buffer_text);
    buffer_delete(file);
    try {
        story = json_parse(raw);
        var locale = "en";
        var id = "fd7b61a3-8233-4ba7-8f77-b88b119a91bf";
        var record = struct_get(story.content.texts, id);
        var message = record.sourceMessage;
        if (struct_exists(story.content.translations, locale)) {
            var translations = struct_get(story.content.translations, locale);
            if (struct_exists(translations, id)) message = struct_get(translations, id).message;
        }
        dialogue_text = "";
        for (var i = 0; i < array_length(message.segments); i++) {
            var segment = message.segments[i];
            if (segment.kind != "text") throw "Text-only example";
            dialogue_text += segment.text;
        }
    } catch (error) { dialogue_text = "Cannot read this story text"; }
}
// Put the following line in the same object's Draw GUI event, not Create:
// draw_text_ext(24, 24, dialogue_text, -1, 700);

Erwartet: „Welcome to the harbour. I am Mira.“ Mit locale = "de" beziehungsweise dem Sprachparameter de: „Willkommen im Hafen. Ich bin Mira.“ Fehlt die Sprache, wird der Quelltext verwendet. Das Beispiel unterstützt Textsegmente; Platzhalter werden absichtlich nicht stillschweigend übersprungen.

3 · Von einem Satz zum Gespräch

Die feste Text-ID oben dient dem ersten Test. Im Spiel wählst du flowRef/entryRef aus story-index.json, liest execution.entries[entryRef].nodeRef und dann execution.nodes[nodeRef]. Der aktuelle Dialog liefert text.textRef und speakerRef. Fortsetzungen hängen vom Knotentyp ab.

Name/Dialog im Draw GUI Event zeichnen. Für Antworten Button-Instanzen mit gespeicherter Options-ID verwenden. Ende: eine dialogue_open-Variable auf false setzen und Zeichnen/Eingabe daran koppeln. Kein game_end() aufrufen.

  1. Weiter und Ende: Verbindungen verfolgen, Textbox schließen
  2. Choices: Antwort-ID, Reihenfolge und ausgewählter Ausgang
  3. Conditions und Variablen: zehn oder zwei Goldstücke
  4. Sprache: dieselben IDs, neu aufgelöste Inhalte
  5. Command: Gegenstand geben oder einen Shop öffnen
  6. Call/Return: Untergeschichte und zurückkehren
Antworten und Goldprüfung in dieser Sprache nachvollziehen

Die Daten einer Entscheidung lesen

Füge diesen Ausschnitt dort ein, wo story nach erfolgreichem Laden verfügbar ist (bei RPG Maker: const story = $gameTemp.vnleExample.story;). Er gibt IDs zum Nachvollziehen aus. Die Anzeige ersetzt du durch deine Antwortbuttons. Er ist auf die zwei Harbour-Antworten und deren nachfolgende Goldprüfung begrenzt, kein allgemeiner Interpreter.

// After story was loaded successfully.
var choice = struct_get(story.execution.nodes, "42edfff8-b8fe-46bf-ae0d-9e2347b6e726");
for (var i = 0; i < array_length(choice.optionOrder); i++) {
    var option_id = choice.optionOrder[i];
    var option = struct_get(choice.options, option_id);
    show_debug_message(option_id + " " + option.text.textRef);
    // Resolve text; keep option_id on your answer button instance.
}
var branch = struct_get(story.execution.nodes, "c1c3c372-0a73-4cd0-851d-ede59d5709bb");
var gold = 10; // Repeat with 2.
var next_step = gold >= branch.condition.right.value.value ? branch.whenTrue : branch.whenFalse;
show_debug_message(next_step.nodeRef);

Mit 10 Gold verweist next auf „Pay five gold“, mit 2 auf „Not enough gold“. Beim tatsächlichen Spielen führst du die Prüfung erst aus, wenn der gewählte Pfad diesen Knoten erreicht. Jede ausgewählte Antwort liefert dafür ihre eigene continuation.

4 · Eigene Bilder zuordnen

Dieses Ergänzungsstück setzt einen aktuellen dialogue-Knoten namens node und die im Kommentar genannten UI-Elemente voraus. Bei C++ und MonoGame ist speakerRef bereits als SpeakerId beziehungsweise speakerId ausgelesen. Der Schlüssel ist Miras tatsächliche Charakter-ID; der Bildname und sein Ablageort gehören deinem Spiel. Füge die Zeilen an den angegebenen Stellen ein.

// Import mira.png as sprite spr_mira. In Create:
portraits = {};
struct_set(portraits, "807b2957-7bab-4a28-83a4-1f3d1589bbc2", spr_mira);
// In Draw GUI, with node holding the current dialogue struct:
if (struct_exists(portraits, node.speakerRef)) {
    draw_sprite(struct_get(portraits, node.speakerRef), 0, 96, 180);
}

Sprechernamen über content.characters[speakerRef].nameTextRef genauso wie Dialogtexte auflösen. Eine fehlende Zuordnung soll das alte Porträt ausblenden oder ein Ersatzbild zeigen. Bilder werden nicht nach Sprache gewählt.

Bildverweise aus dem vollständigen Export verwenden

5 · Dateien mit dem Spiel ausliefern

Die Included File muss für das gewählte Ziel mitgeliefert werden. GML liest ID-Schlüssel über struct_get; Namen mit Bindestrichen sind keine Punkt-Eigenschaften. Für Browserziele den Dateiladeweg gesondert anpassen und prüfen.

Dein Ergebnis prüfen

  1. Der englische und deutsche Begrüßungstext erscheinen korrekt; eine nicht vorhandene Sprache fällt auf Englisch zurück.
  2. Beim Ergänzen des Ablaufs: beide Antworten, Gold 10/2, Rückkehr aus der Untergeschichte und Ende ausprobieren.
  3. Den gebauten Spielordner außerhalb deines Projekts starten. JSON, Schriften und Porträts müssen dort ebenfalls vorhanden sein.

Offizielle Dokumentation

API- und Einrichtungsreferenzen für diesen Weg: