VNLEWIKIBuild stories. Connect worlds.Deutsch
VNLE Handbook

GDevelop

← Bring content into your game

GDevelop 5 · JavaScript event

Start with one visible sentence. This small example reads the real Harbour export directly; it is not a complete dialogue player. Then connect the data to your game UI.

1 · Prepare files and scene

Add story.json as a JSON resource named story.json in the project resources. Create a Text object named DialogueText and place it in the scene. Add an At the beginning of the scene event with the JavaScript event below it. The load callback fills the display.

story.json · Export files explained

2 · Show the first text

// JavaScript event under "At the beginning of the scene".
// Register story.json as a JSON resource named story.json first.
const label = runtimeScene.getObjects('DialogueText')[0];
const manager = runtimeScene.getGame().getJsonManager();
manager.loadJson('story.json', (error, story) => {
  if (error || !story) { label.setString('Cannot load story.json'); return; }
  try {
    const locale = 'en';
    const id = 'fd7b61a3-8233-4ba7-8f77-b88b119a91bf';
    const content = story.content;
    const translation = content.translations[locale]?.[id];
    const message = translation ? translation.message : content.texts[id].sourceMessage;
    const line = message.segments.map(segment => {
      if (segment.kind !== 'text') throw new Error('Text-only example');
      return segment.text;
    }).join('');
    label.setString(line);
  } catch (error) { label.setString('Cannot read this story text'); }
});

Expected: “Welcome to the harbour. I am Mira.” With locale = "de" or the language parameter de: “Willkommen im Hafen. Ich bin Mira.” A missing language uses source text. This sample supports text segments; it deliberately does not silently discard placeholders.

3 · From one sentence to a conversation

The fixed text ID above is for the first test. In your game choose flowRef/entryRef from story-index.json, read execution.entries[entryRef].nodeRef, then execution.nodes[nodeRef]. The current dialogue supplies text.textRef and speakerRef. Continuations depend on node kind.

Text object: setString(). Answer-button events retain the option ID; JavaScript can evaluate the same JSON objects. End: hide(true) dialogue objects and gate their input events with a scene variable.

  1. Continue and End: follow connections, close the text box
  2. Choices: answer ID, order and selected continuation
  3. Conditions and variables: ten or two gold
  4. Language: the same IDs, newly resolved content
  5. Command: give an item or open a shop
  6. Call/Return: visit a substory and return
Inspect answers and the gold check in this language

Read the data for a choice

Insert this fragment where story is available after loading (for RPG Maker: const story = $gameTemp.vnleExample.story;). It prints IDs for inspection. Replace the output with your answer buttons. It covers the two Harbour answers and their following gold check, not a general interpreter.

// story is already loaded. Keep each optionId on its answer button.
const choice = story.execution.nodes['42edfff8-b8fe-46bf-ae0d-9e2347b6e726'];
for (const optionId of choice.optionOrder) {
  const option = choice.options[optionId];
  console.log(optionId, option.text.textRef); // Resolve text, then create your button.
}
// Inspect the actual purchase check. This particular node is Gold >= 5.
const branch = story.execution.nodes['c1c3c372-0a73-4cd0-851d-ede59d5709bb'];
const gold = 10; // Repeat with 2, using your current game value.
const next = gold >= branch.condition.right.value.value ? branch.whenTrue : branch.whenFalse;
console.log(next.nodeRef);

With 10 gold, next refers to “Pay five gold”; with 2 it refers to “Not enough gold”. In the actual game, run the check only when the selected path reaches this node. Each selected answer supplies its own continuation.

4 · Map your own images

This supplementary excerpt expects a current dialogue object named node and the UI elements named in its comments. For C++ and MonoGame, speakerRef has already been read as SpeakerId or speakerId. The key is Mira’s actual character ID; the image name and location belong to your game. Insert the lines at the indicated locations.

// Add the image to a Portrait Sprite animation named Mira in the editor.
const animations = {'807b2957-7bab-4a28-83a4-1f3d1589bbc2': 'Mira'};
const portrait = runtimeScene.getObjects('Portrait')[0];
const animation = animations[node.speakerRef];
portrait.hide(!animation);
if (animation) portrait.setAnimationName(animation);

Resolve speaker names through content.characters[speakerRef].nameTextRef just like dialogue text. Missing mappings should hide the previous portrait or show a placeholder. Images are not selected by language.

Use image references from the complete export

5 · Ship files with the game

Register and retain the file as a project resource on export; do not use a hard-coded local disk path. The callback is asynchronous: later events must wait for successful loading before using the data.

Check your result

  1. English and German greetings display correctly; an unavailable language falls back to English.
  2. When adding flow: try both answers, gold 10/2, the return from the substory and End.
  3. Run the built game outside your project folder. JSON, fonts and portraits must be available there too.

Official documentation

API and setup references for this approach: