Uma Certa Engine de Visual Novel Programável (Go)
Uma engine de visual novel implementada em Go usando ebiten, com scripts YAML para dialogos, ramificacoes, imports, variaveis tipadas, salvar/carregar, fundos e sprites de personagem.
Recursos
- Tela de carregamento na inicializacao + validação automatica
- A tela de titulo fica bloqueada ate o validação terminar
- Imports YAML recursivos para dividir a historia em varios arquivos
- Profundidade maxima de import configuravel (
MaxImportNestingeminternal/vn/script.go) - Execucao de script por cenas com ramificacoes
- Variaveis tipadas:
string,bool,int,float - Comando
ifcom blocosthen/else - Salvamento/carregamento do estado do jogo em JSON
- Modo debug (
F2) para inspecionar variaveis e pular para cenas - Fundos por chave de cor ou caminho de imagem
- Sprites de personagem por caminho de imagem
Inicio rapido
go mod tidy
go run ./cmd/vnengine
Por padrao, a engine sempre carrega default/script.yaml.
Todos os textos da interface/debug visiveis ao usuario sao carregados de default/ui.yaml.
Controles
- Tela de carregamento: validação automatica ao iniciar
- Tela de titulo:
Up/Down+Enter - Historia
Enter: avancar dialogo / confirmar escolha selecionada - Historia
Up/Down: navegar pelas escolhas - Historia
Left Click: avancar dialogo (quando nao estiver em escolhas) F2: alterna modo debug (mostra variaveis, digita ID da cena e apertaEnterpara pular)F5: salvarF9: carregarEsc: voltar para a tela de titulo
Imports de script
Use imports em qualquer arquivo de script. Os caminhos sao relativos ao arquivo que declara o import.
title: "Minha Historia"
start: intro
imports:
- chapters/act1.yaml
Os imports podem ser aninhados recursivamente ate MaxImportNesting.
Variaveis
Defina variaveis com valores YAML tipados:
- type: set
key: player_name
value: "Mira" # string
- type: set
key: trust
value: true # bool
- type: set
key: coins
value: 3 # int
- type: set
key: luck
value: 1.5 # float
Interpolacao em campos de texto/sprite/fundo usa {var_name}.
Condicoes e fluxo if/else
Condicao inline (guarda no nivel do comando):
- type: say
if: "coins >= 2"
speaker: Narrador
text: "Voce consegue pagar o bonde."
if/else estruturado:
- type: if
if: "trust == true"
then:
- type: say
speaker: Mira
text: "Entao me siga."
else:
- type: say
speaker: Mira
text: "Mantenha distancia."
Operadores suportados: ==, !=, >, <, >=, <=.
Validação
Na inicializacao, a engine verifica:
- se todos os arquivos de script carregados existem
- se todos os alvos de
gotoechoiceexistem - se os assets de fundo/sprite referenciados existem (para caminhos estaticos)
Caminhos dinamicos de asset contendo variaveis (ex.: {mood}.png) sao ignorados na verificacao estatica de existencia.
Referencia de comandos
saybackground(backgroundoubackground_image)character(character,emotion,spriteopcional)setif(if,then,else)gotochoiceend
Cena de menu interativo (menu)
Voce pode criar um menu em cena com sprites posicionados e navegacao por setas (Left/Right/Up/Down) + Enter.
- type: menu
background_image: assets/bg_hub.png
menu_items:
- id: oficina
sprite: assets/menu_oficina.png
x: 0.25
y: 0.45
selectable: true
commands:
- type: set
key: destino
value: oficina
- type: goto
target: cena_oficina
- id: mercado
sprite: assets/menu_mercado.png
x: 0.65
y: 0.45
if: "coins >= 2"
selectable: true
commands:
- type: say
speaker: Narrador
text: "Voce vai para o mercado."
- id: decoracao
sprite: assets/menu_estatua.png
x: 0.45
y: 0.2
selectable: false
commands:
- type: say
speaker: Narrador
text: "Isto nao deve executar porque nao e selecionavel."
Notas:
x/yentre0e1sao tratados como proporcao da tela.x/yacima de1sao tratados como pixels absolutos.- Itens com
iffalso nao aparecem. - Itens com
selectable: falseaparecem, mas nao recebem destaque nem selecao. commandsde um item aceitam qualquer fluxo suportado (set,if,goto,say, etc.).