Files
vnengine/README.md
2026-02-12 15:25:40 -03:00

175 lines
4.4 KiB
Markdown

# 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 (`MaxImportNesting` em `internal/vn/script.go`)
- Execucao de script por cenas com ramificacoes
- Variaveis tipadas: `string`, `bool`, `int`, `float`
- Comando `if` com blocos `then`/`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
```bash
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 aperta `Enter` para pular)
- `F5`: salvar
- `F9`: carregar
- `Esc`: 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.
```yaml
title: "Minha Historia"
start: intro
imports:
- chapters/act1.yaml
```
Os imports podem ser aninhados recursivamente ate `MaxImportNesting`.
## Variaveis
Defina variaveis com valores YAML tipados:
```yaml
- 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):
```yaml
- type: say
if: "coins >= 2"
speaker: Narrador
text: "Voce consegue pagar o bonde."
```
`if/else` estruturado:
```yaml
- 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 `goto` e `choice` existem
- 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
- `say`
- `background` (`background` ou `background_image`)
- `character` (`character`, `emotion`, `sprite` opcional)
- `set`
- `if` (`if`, `then`, `else`)
- `goto`
- `choice`
- `end`
## Cena de menu interativo (`menu`)
Voce pode criar um menu em cena com sprites posicionados e navegacao por setas (`Left`/`Right`/`Up`/`Down`) + `Enter`.
```yaml
- 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`/`y` entre `0` e `1` sao tratados como proporcao da tela.
- `x`/`y` acima de `1` sao tratados como pixels absolutos.
- Itens com `if` falso nao aparecem.
- Itens com `selectable: false` aparecem, mas nao recebem destaque nem selecao.
- `commands` de um item aceitam qualquer fluxo suportado (`set`, `if`, `goto`, `say`, etc.).