Voltar para o Blog
Quest Log

Como Fazer um Jogo Souls-like no Godot: Os Sistemas que Importam

Cavaleiro com escudo e espada encarando um chefe gigante em uma arena sombria iluminada por brasas

Como fazer um jogo souls-like no Godot 4: stamina, esquiva com i-frames, fogueiras e bosses. Entenda os sistemas do gênero com GDScript tipado.

Como fazer um jogo souls-like no Godot: por onde a coisa realmente começa

Todo mundo que ama Dark Souls em algum momento pensa "e se eu fizesse o meu". A boa notícia é que como fazer um jogo souls-like no Godot é uma pergunta com resposta concreta: o gênero é uma soma de sistemas bem definidos, não uma mágica inatingível. A má notícia é que são vários sistemas conversando entre si, e é fácil se afogar tentando fazer tudo de uma vez.

Este guia separa o que define o gênero, como pensar cada peça dentro do Godot 4 e mostra código GDScript tipado de verdade para as duas engrenagens que mais importam: stamina e esquiva. No fim, você vai saber por onde cortar o escopo para chegar num protótipo jogável.

O que realmente define um souls-like

Antes de abrir a engine, vale destravar o gênero na cabeça. Um souls-like não é "jogo difícil com espada". Ele é a combinação de algumas decisões de design que se reforçam:

  • Combate deliberado. Cada ataque tem peso, tempo de recuperação e compromisso. Você não spamma botão; você escolhe a hora de atacar e paga o preço se errar.
  • Stamina como recurso central. Atacar, esquivar e correr consomem stamina. Ficar sem stamina te deixa exposto. É o que impede o jogador de agir sem parar.
  • Risco e recompensa. Avançar mais um pouco pode render um atalho ou um item, ou pode te matar e fazer perder o progresso da última corrida.
  • Fogueiras (checkpoints). Descansar recupera sua vida e seus recursos, mas ressuscita todos os inimigos comuns do mapa. Segurança tem custo.
  • Perder a moeda ao morrer. Você morre, sua moeda (almas, ecos, o nome que for) fica no chão. Você tem uma chance de voltar até lá e recuperar. Morreu de novo no caminho? Perdeu de vez.
  • Level design interconectado. Caminhos que voltam para si mesmos, atalhos que se abrem, a sensação de um mundo que se dobra em vez de um corredor linear.
  • Bosses como provas. Chefes com padrões que você aprende na base da tentativa. A vitória vem de leitura, não de estatística.

Se um sistema seu não serve a essa tensão de risco constante, provavelmente ele não é prioridade agora.

Stamina: o coração que bate atrás de tudo

A stamina é o primeiro sistema que eu construiria, porque ele muda a sensação do jogo inteiro. Ele é simples de modelar: um valor que cai quando você age e sobe quando você para, geralmente com um pequeno atraso antes de regenerar para punir quem só quer correr.

No Godot, isso vive num script do jogador (ou num nó de recurso separado, se você quiser reaproveitar). Um exemplo tipado que regenera após um atraso:

extends Node

@export var stamina_maxima: float = 100.0
@export var regen_por_segundo: float = 25.0
@export var atraso_regen: float = 1.0

var stamina_atual: float = stamina_maxima
var _tempo_desde_uso: float = 0.0

signal stamina_mudou(valor: float, maximo: float)

func _process(delta: float) -> void:
    _tempo_desde_uso += delta
    if _tempo_desde_uso >= atraso_regen and stamina_atual < stamina_maxima:
        stamina_atual = min(stamina_atual + regen_por_segundo * delta, stamina_maxima)
        stamina_mudou.emit(stamina_atual, stamina_maxima)

func gastar_stamina(custo: float) -> bool:
    if stamina_atual < custo:
        return false
    stamina_atual -= custo
    _tempo_desde_uso = 0.0
    stamina_mudou.emit(stamina_atual, stamina_maxima)
    return true

O detalhe que faz esse código "sentir souls" é o gastar_stamina devolver um bool. Antes de deixar o jogador atacar ou esquivar, você pergunta: if stamina.gastar_stamina(20.0):. Se voltar false, a ação simplesmente não acontece, e o jogador sente que ficou sem fôlego. O signal stamina_mudou deixa a barra de UI reagir sem o script do jogador precisar conhecer a interface.

Esquiva com i-frames: a ferramenta que define o skill

Se a stamina é o coração, a esquiva é a alma da defesa. O rolamento não é só movimento: durante uma janela curta dele, o personagem fica invulnerável. São os famosos i-frames (frames de invulnerabilidade). Acertar o timing da esquiva contra um ataque de boss é a fantasia central do gênero.

A implementação conceitual é: ao esquivar, você liga uma flag de invulnerabilidade, espera a janela de i-frames e desliga. Enquanto a flag estiver ligada, o sistema de dano ignora golpes.

extends CharacterBody3D

@export var duracao_iframes: float = 0.4
@export var custo_esquiva: float = 20.0

@onready var stamina: Node = $Stamina

var invulneravel: bool = false

func tentar_esquiva(direcao: Vector3) -> void:
    if invulneravel:
        return
    if not stamina.gastar_stamina(custo_esquiva):
        return
    _executar_esquiva(direcao)

func _executar_esquiva(direcao: Vector3) -> void:
    invulneravel = true
    # aqui você tocaria a animação de rolamento e aplicaria o deslocamento
    velocity = direcao.normalized() * 8.0
    await get_tree().create_timer(duracao_iframes).timeout
    invulneravel = false

func receber_dano(quantidade: float) -> void:
    if invulneravel:
        return
    # aplica o dano à vida do jogador
    print("Tomou %s de dano" % quantidade)

Note que receber_dano checa invulneravel logo na primeira linha e sai fora se a esquiva estiver ativa. Essa é a mecânica inteira num if. O await num SceneTreeTimer é a forma limpa de segurar a janela de i-frames sem inventar um contador manual no _process.

Próximo nível
Quer aprender isso na prática?

No CursoGame.Dev você sai dos tutoriais soltos e constrói jogos publicáveis, com trilha progressiva, quests práticas e feedback real.

Conhecer a plataforma
+500 alunos4.9/5Garantia 7 dias

Hitbox de ataque: como o golpe conecta

Combate souls-like precisa que o ataque só cause dano na janela ativa da animação, não o tempo todo. No Godot, o padrão é usar uma Area3D (a hitbox) que só fica com a colisão ativa durante alguns frames da animação de ataque, detectando outra Area3D no inimigo (a hurtbox).

O jeito prático é deixar a hitbox desativada por padrão e ligá-la com Call Method Tracks na AnimationPlayer: no frame em que a espada começa o corte, a animação chama um método que habilita a colisão; no frame em que termina, chama outro que desabilita. Assim o dano fica amarrado ao visual, e não a um timer solto.

A hurtbox do inimigo conecta o sinal area_entered e, ao receber a hitbox, chama o receber_dano dele. Como a hitbox carrega o valor do golpe, o mesmo sistema serve para ataque leve, pesado e de boss, só mudando o número. Esse desacoplamento entre "quem bate" e "quem apanha" é o que mantém o combate escalável quando você adiciona novos inimigos.

Lock-on: a câmera que trava no alvo

O lock-on (mirar e travar num inimigo) é o que torna o combate 3D legível. Conceitualmente ele faz duas coisas: mantém a câmera olhando para o alvo e reorienta o movimento do jogador em relação a ele, de modo que "esquerda" e "direita" viram um giro em torno do inimigo.

Você não precisa de nada exótico para isso. Guarde uma referência ao alvo atual, e a cada frame aponte a câmera com look_at na posição dele. Ao apertar o botão de lock-on, faça uma busca pelos inimigos dentro de um raio (uma Area3D grande no jogador resolve) e escolha o mais próximo do centro da tela. Ao morrer o alvo ou sair do alcance, você solta o lock e volta à câmera livre. O segredo aqui é começar simples: um único alvo, sem troca sofisticada entre inimigos, já entrega 90% da sensação.

Fogueiras, moeda e morte: o loop que prende

Esses três sistemas são um só loop emocional e é onde o gênero ganha identidade.

A fogueira é um ponto no mapa que, ao ser usado, salva sua posição de respawn, restaura vida e recursos, e reseta os inimigos comuns. Guarde num autoload (um singleton global) qual foi a última fogueira ativada e a quantidade de moeda do jogador. Autoloads são perfeitos para isso porque sobrevivem à troca de cena.

A moeda perdida funciona assim: ao morrer, você instancia um objeto "mancha" na posição da morte carregando toda a sua moeda, zera a moeda do jogador e o teleporta para a última fogueira. Se ele tocar a mancha, recupera tudo. Se morrer antes, a mancha antiga some com a moeda dentro. Essa regra crua de "segunda chance única" é o que dá tensão a cada passo depois de acumular recursos.

O respawn dos inimigos ao descansar completa o círculo: a fogueira é alívio e custo ao mesmo tempo. Esse desenho de progressão interconectada tem muito em comum com outro gênero, e se ele te interessa vale ver como pensamos level design de metroidvania, porque as ferramentas de mapa e atalho se sobrepõem bastante.

Escopo: o inimigo mais difícil não é o boss

Preciso ser direto porque isso mata mais projetos souls-like do que qualquer dificuldade de código: o escopo. Um souls-like completo tem combate, inventário, progressão de atributos, múltiplos inimigos, bosses com várias fases, mundo interconectado e narrativa ambiental. Cada um desses é um projeto por si. Tentar tudo junto no primeiro jogo é receita de abandono.

O caminho que funciona é o vertical slice: uma sala, um inimigo, um boss. Faça o jogador atacar, esquivar com i-frames e gastar stamina numa única arena bem feita. Se essa luta de trinta segundos for gostosa de repetir, você tem um souls-like. Se não for, nenhum inventário vai salvar. Só depois que o núcleo estiver bom você expande em largura.

Duas decisões cortam custo pela metade sem tirar a essência. A primeira: considere fazer em 2D. O gênero é definido pelas mecânicas, não pela terceira dimensão, e um souls-like 2D elimina o pesadelo de animação e câmera 3D. A segunda: antes de escolher a engine em definitivo, entenda o terreno com nosso comparativo entre Godot e Unity: para um solo dev, a leveza e o GDScript do Godot 4 costumam ser um baita atalho.

O próximo passo prático

Você viu que um souls-like é uma pilha de sistemas pequenos e claros: stamina que regenera, esquiva com i-frames, hitbox amarrada à animação, lock-on simples e o loop de fogueira, moeda e morte. Nenhum deles é impossível. O trabalho é conectar todos com equilíbrio, e isso se aprende construindo, medindo se está divertido e ajustando.

Se o código tipado deste artigo ainda parece um idioma estrangeiro, é aí que você começa. Aprender a lógica por trás do if stamina.gastar_stamina(20.0) é o que destrava tudo o mais, e nosso guia de GDScript do zero foi feito para essa base. E quando quiser sair de tutoriais soltos e seguir um caminho estruturado até publicar seu jogo, o curso de criação de jogos para iniciantes da CursoGame.Dev te leva do primeiro Vector3 ao seu primeiro boss em pé.

Comece pequeno. Faça uma sala. Faça ela doer na medida certa. O resto do mundo você constrói depois.

Perguntas frequentes

O que define um jogo souls-like?

Combate deliberado baseado em stamina, alto risco e recompensa, checkpoints tipo fogueira que reiniciam os inimigos, perda da moeda ao morrer com chance de recuperá-la, level design interconectado e chefes que exigem aprender padrões.

Godot 4 aguenta um souls-like?

Sim. Godot 4 tem física 3D com Jolt, sistema de animação robusto e nós de área para hitbox e hurtbox. O gargalo de um souls-like é design e balanceamento, não desempenho de engine.

O que são i-frames na esquiva?

i-frames (frames de invulnerabilidade) são o curto período durante a esquiva em que o personagem não recebe dano. É o que transforma o rolamento em uma ferramenta defensiva de timing, não só em movimento.

Preciso saber programar para fazer um souls-like?

Sim. Os sistemas de stamina, esquiva, hitbox e estados de inimigo exigem lógica. GDScript é acessível para começar, mas você vai escrever código de verdade desde o primeiro protótipo.

Por onde começar um souls-like sem me perder no escopo?

Comece com uma sala, um inimigo e três verbos: atacar, esquivar e gastar stamina. Um vertical slice pequeno e gostoso de jogar vale mais que dez sistemas pela metade.

Souls-like precisa ser em 3D?

Não. O gênero é definido pelas mecânicas, não pela dimensão. Existem souls-likes 2D excelentes. Fazer em 2D reduz muito o custo de animação e câmera, e é um ótimo caminho para o primeiro projeto.