Executando verificação de segurança...
8

Problemas que enfrentei sobre desenvolvimento de jogos na Godot Engine

🤝 Quero compartilhar minha experiência ao lançar o Capítulo 1 do meu game ALONE e perceber um erro que pode piorar durante o desenvolvimento do Capítulo 2.

Então, bora?


1. Alpha α

Enquanto eu estava desenvolvendo o ALONE Alpha Demo em janeiro de 2020, lançando-o posteriormente em abril do mesmo ano, o algoritmo que fiz funcionou muito bem para o tamanho inicial do projeto.

Porém, à medida que o projeto crescia, enfrentei uma das principais brigas ao longo de três anos: Game Events.

Sabe quando você pega algum item no cenário, ou avança em um local específico, ocorre alguma ação?

Por exemplo, no jogo Resident Evil (1996) no quarto tem um armário que fica fazendo barulho e na frente tem uma carta. Você lê a carta e em seguida aparece um zumbi saindo do armário barulhento. E para previnir que esse evento ocorra novamente, ele é registrado internamente no jogo.

Com isso em mente, no meu jogo é declarado uma variável chamada event que recebe um valor, em inteiro, 0.

var event = 0

Parece simples não é? Mas complica depois, então senta aí.

2. Beta β

Enquanto o desenvolvimento progredia, mais ideias apareciam para agregar na narrativa. Mas então, imagine-se que eu estou trabalhando no event 30 e eu tive uma ideia lá pro event 15. Ou seja, sou forçado mover o event 15 para event 16, event 16 para event 17 e assim por diante.

Era tão entediante e cansativo que criei outra variável chamada sideevent que recebe um valor em Object.

var sideevent = {
    'chase1': false,
    'password1Found': false,
    'mainHall_blood': false,
    ...
}

Com esse sideevent até funcionava bem, mas quando buildei (compilei o jogo em um arquivo .exe) para pessoas próximas testarem o meu jogo (em versão Beta). Ocorria mais um problema:

Se mais tarde eu adicionasse outro sideevent com um jogo já salvo em um arquivo .json anteriormente, o arquivo .json posteriormente seria corrompido e o jogo crasha pois o sidevent adicionado na versão mais recente não existia antes.

Ficou confuso? Pergunte abaixo na sessão de comentários.

Além disso, declarei variáveis para coisas específicas, como por exemplo:

  1. Quais livros havia na estante em uma parte específica do mapa.
var bookShelf = [false, false, false]
  1. Quantas vezes o jogador usou uma chave específica para depois descartá-la.
var key3Uses = 4
  1. Quais cartas específicas o jogador leu.
var passFile = [false, false, false, false]

E tem muito mais. Foi ficando uma bagunça, mas funcionou.

3. Futuro Omega Ω

Porém, depois de suportar essas dores e analisar após o lançamento oficial de ALONE: Chapter 1, tive uma ideia:

Unificar todas essas variáveis em uma só:

var events = []

Exato, uma Array. Vazio, simples, mas elegante e poderoso.

Conforme o jogador avança, Strings serão adicionadas a esse Array.
Como por exemplo, o jogador entra em um quarto e interage com a mesa de cabeceira:

if !is_event("PUZZLE001_DONE"): // Caso não tiver o evento PUZZLE001_DONE.
    $UI._showText(["A box locked with a password."])
    yield($UI, "event_finished" ) // Espera até o Text fechar.
    
    $UI._showChoose("Do you want to operate?", "Yes", "No")
    yield($UI, "event_finished" ) // Espera até o Choose fechar.
    
    // ...
    add_event("PUZZLE001_DONE") // Quando o puzzle for resolvido.
    
else: // Caso tiver o evento PUZZLE001_DONE.
    $UI._showText(["It is not necessary."])

Com esta função is_event() é versátil para cada situação. Posso verificar se o jogador:

  1. Possui um evento necessário.
if is_event("PUZZLE002_DONE"):
    // ...
  1. Possui dois ou mais eventos necessários.
if is_event(["PUZZLE002_DONE", "CHASE001_DONE"]):
    // ...
  1. Ou apenas uma da lista de eventos obrigatórios, graças ao atributo "OR".
if is_event(["PUZZLE002_DONE", "CHASE001_DONE"], "OR"):
    // ...

4. Omega Ω

Apesar de ser um algoritmo melhor que a solução alternativa anterior, ainda há um problema: O jogo já foi lançado, o que significa que a estrutura do arquivo é antiga. Portanto, preciso portá-lo para a nova estrutura. E não só apenas para o Capítulo 2, mas também para o Capítulo 1 atual.

Assim, creio que é tudo por agora. Espero sinceramente que este tópico seja útil para outros desenvolvedores que se deparem com o mesmo problema que eu.


🎮 Quer jogar o meu jogo?

Está disponível de graça nas duas plataformas comumente utilizadas para jogos independentes: itch.io e GameJolt.

o protagonista com sua lanterna com medo e com o título "ALONE: Capítulo 1" atrás dele

Carregando publicação patrocinada...
2
1

Sim, sem dúvida.
Todo o ambiente da Godot Engine é simplificado. Até o binário dele é pequeno e que não precisa fazer a instalação. Só simplesmente baixar o .exe (no Windows) e executar.

Até a linguagem de programação é própria, nomeada GDScript que é inspirada no Python.

1

legal, valeu pelo seu retorno
estou vendo uma engine para fazer algo em 3d que ande por uma casa a noite
É mais específico e estou vendo uma opção mais simples possível

1
1

É bom pesquisar sobre máquina de estados em jogos, tem um vídeo muito bom sobre isso, não estou com o link agora mas assim que possível eu te passo, reduz muito a complexidade de eventos ou ifs no jogo.

0
2
1
1
1

Estou estudando a codificação da engine, e me deparei com esse problema de otimização. Pra minha sorte ou não, identifiquei esse problema em "mim" enquanto estudava. Por curiosidade o chatgpt recomendo a mesma coisa na otmização, com a criação de uma Lista de Eventos. Você pode adicionar, remover ou reordenar eventos de maneira mais simples.

exemplo que ele sugeriu:

var eventos = []

func _ready():
    # Adicione eventos à lista
    eventos.append(evento1)
    eventos.append(evento2)
    eventos.append(evento3)
    # Adicionando um novo evento em uma posição específica
    eventos.insert(1, novo_evento) # Insere o novo_evento na posição 1

func executar_eventos():
    for evento in eventos:
        evento.chamar()  # Chama a função de cada evento