VNLEWIKICrie histórias. Conecte mundos.
Português (Brasil)
Manual do VNLE

Defold

← Integre o conteúdo ao seu jogo

Defold · Lua · GUI

Comece exibindo uma frase. Este pequeno exemplo lê diretamente a exportação real do porto; ele ainda não é um sistema completo de diálogos. Depois, conecte os dados à interface do seu jogo.

1 · Prepare os arquivos e a cena

Copie story.json para /story/. Adicione /story a project → custom_resources em game.project. Crie uma GUI com um nó de texto chamado dialogue, escolha um recurso de fonte e adicione a GUI ao objeto do jogo. Atribua first_text.gui_script à GUI e execute o projeto.

story.json · Entenda os arquivos exportados

2 · Exiba o primeiro texto

-- first_text.gui_script: attach to a GUI containing a text node named dialogue.
function init(self)
    local raw, error = sys.load_resource("/story/story.json")
    if not raw then
        gui.set_text(gui.get_node("dialogue"), "Cannot load story.json")
        return
    end
    local ok, story = pcall(json.decode, raw)
    if not ok then
        gui.set_text(gui.get_node("dialogue"), "Invalid JSON")
        return
    end
    local locale = "en"
    local id = "fd7b61a3-8233-4ba7-8f77-b88b119a91bf"
    local content = story.content
    local translation = (content.translations[locale] or {})[id]
    local message = translation and translation.message or content.texts[id].sourceMessage
    local parts = {}
    for _, segment in ipairs(message.segments) do
        assert(segment.kind == "text", "Text-only example")
        parts[#parts + 1] = segment.text
    end
    gui.set_text(gui.get_node("dialogue"), table.concat(parts))
end

Resultado esperado: “Welcome to the harbour. I am Mira.” Com locale = "de" ou o parâmetro de idioma de: “Willkommen im Hafen. Ich bin Mira.” Se o idioma não estiver disponível, será usado o texto original. Este exemplo aceita segmentos de texto e não descarta placeholders silenciosamente.

3 · De uma frase a uma conversa

O ID de texto fixo acima serve para o primeiro teste. No seu jogo, escolha flowRef/entryRef em story-index.json, leia execution.entries[entryRef].nodeRef e depois execution.nodes[nodeRef]. O diálogo atual fornece text.textRef e speakerRef. A continuação depende do tipo de nó.

Nome e diálogo: gui.set_text. Respostas: nós de GUI, foco de entrada e gui.pick_node em on_input; mantenha o ID da opção separadamente. End: desative o nó pai compartilhado da GUI com gui.set_enabled(node, false) e libere o foco de entrada.

  1. Continue e End: siga as conexões e feche a caixa de texto
  2. Escolhas: ID da resposta, ordem e continuação selecionada
  3. Condições e variáveis: dez ou duas moedas de ouro
  4. Idioma: mesmos IDs, conteúdo resolvido novamente
  5. Command: entregar um item ou abrir uma loja
  6. Call/Return: entrar em uma sub-história e voltar
Examine as respostas e a verificação de ouro nesta linguagem

Leia os dados de uma escolha

Insira este trecho onde story estiver disponível após o carregamento (no RPG Maker: const story = $gameTemp.vnleExample.story;). Ele exibe IDs para conferência. Substitua a saída pelos seus botões de resposta. O trecho cobre as duas respostas do porto e a verificação de ouro seguinte; não é um interpretador genérico.

-- Inside a function where the decoded story table is available.
local choice = story.execution.nodes["42edfff8-b8fe-46bf-ae0d-9e2347b6e726"]
for _, option_id in ipairs(choice.optionOrder) do
    local option = choice.options[option_id]
    print(option_id, option.text.textRef)
    -- Resolve the text; retain option_id for the corresponding GUI button.
end
local branch = story.execution.nodes["c1c3c372-0a73-4cd0-851d-ede59d5709bb"]
local gold = 10 -- Repeat with 2.
local next_step = branch.whenFalse
if gold >= branch.condition.right.value.value then next_step = branch.whenTrue end
print(next_step.nodeRef)

Com 10 moedas de ouro, next aponta para Pay five gold; com 2, para Not enough gold. No jogo, execute a verificação somente quando o caminho escolhido chegar a esse nó. Cada resposta tem sua própria continuação.

4 · Mapeie suas próprias imagens

Este trecho complementar espera um objeto de diálogo atual chamado node e os elementos de interface indicados nos comentários. Em C++ e MonoGame, speakerRef já foi lido como SpeakerId ou speakerId. A chave do mapeamento é o ID real da personagem Mira; o nome e a localização da imagem pertencem ao seu jogo. Insira as linhas nos locais indicados.

-- Add mira.png to an atlas and register that atlas as portraits in the GUI Textures.
local portraits = { ["807b2957-7bab-4a28-83a4-1f3d1589bbc2"] = "mira" }
local portrait = gui.get_node("portrait") -- GUI Box node using the portraits texture
local animation = portraits[node.speakerRef]
gui.set_enabled(portrait, animation ~= nil)
if animation then gui.play_flipbook(portrait, hash(animation)) end

Resolva o nome do personagem por content.characters[speakerRef].nameTextRef, como faz com o texto do diálogo. Se faltar um mapeamento, o jogo deve ocultar o retrato anterior ou mostrar uma imagem substituta. As imagens não são selecionadas pelo idioma.

Use as referências de imagem da exportação completa

5 · Distribua os arquivos com o jogo

custom_resources inclui o JSON bruto no pacote. Os arrays de Lua começam em 1: percorra optionOrder com ipairs. Leia os mapas de IDs do JSON com table[id]. Adicione imagens à GUI por meio de recursos de atlas.

Confira o resultado

  1. As saudações em inglês e alemão devem aparecer corretamente; um idioma indisponível deve usar o inglês.
  2. Ao implementar o fluxo, teste as duas respostas, 10 e 2 moedas de ouro, a volta da sub-história e End.
  3. Execute o jogo compilado fora da pasta do projeto. JSON, fontes e retratos também devem estar disponíveis ali.

Documentação oficial

Referências de API e configuração usadas nesta abordagem: