Como Fazer um City Builder: Sistemas, Escopo e Primeiro Passo

Como fazer um city builder: o que define o gênero, escopo realista para indie, grid, economia por tick, população e código GDScript no Godot 4.
Todo mundo que passou horas em Cities Skylines ou SimCity já teve a mesma ideia: fazer o próprio jogo de construir cidade. Um city builder parece simples por fora, você coloca construções num mapa e vê números subirem, mas por dentro é um dos gêneros mais interconectados que existem. Este guia mostra o que define o gênero, por que ele engana quem está começando, qual escopo faz sentido para um indie e como implementar os sistemas centrais no Godot 4, com código real de colocação em grid.
O que define um city builder
Quatro pilares aparecem em praticamente todo jogo do gênero, de SimCity a Against the Storm.
Construção em grid. O mapa é dividido em células e cada construção ocupa uma ou mais delas. O grid pode ser quadrado, isométrico ou hexagonal, mas a lógica é a mesma: o jogador escolhe uma construção, o jogo mostra onde ela cabe e valida se a célula está livre. Esse snap em células é o que dá a sensação tátil de "montar" a cidade.
Economia de recursos. Construções produzem e consomem. Uma fazenda gera comida, casas consomem comida, uma serraria transforma árvores em madeira que vira mais casas. A cidade cresce quando a produção supera o consumo e trava quando não supera. Esse loop de fontes e drenos é o coração do gênero, e os mesmos princípios de economia de jogo que valem para RPGs e jogos de gestão valem aqui.
Simulação de agentes e necessidades. Nos grandes jogos do gênero, cada habitante é simulado: acorda, trabalha, consome, reclama. Nos menores, a população é só um número com necessidades agregadas. Nos dois casos, a população reage ao estado da cidade e pressiona o jogador a responder.
Progressão por desbloqueio. O jogador não começa com tudo. Novas construções abrem conforme a população cresce ou metas são batidas, o que transforma a partida numa escada: cada degrau desbloqueado cria um problema novo que pede o próximo degrau.
Se você já leu sobre como fazer um jogo tycoon, vai notar a sobreposição: tycoon e city builder dividem a economia por tick e a progressão, mas o city builder adiciona o espaço como recurso. Onde você constrói importa tanto quanto o que você constrói.
Por que o gênero é traiçoeiro como primeiro projeto
City builder é um dos gêneros que mais atrai iniciante e um dos que mais derruba iniciante. Três motivos.
Tudo depende de tudo. Num jogo de plataforma, o pulo funciona sozinho e você testa em minutos. Num city builder, a economia depende da população, que depende da felicidade, que depende da economia. Você não consegue validar um sistema isolado: precisa de três ou quatro funcionando juntos antes de saber se o jogo é divertido. Isso alonga o tempo até o primeiro protótipo jogável, que é exatamente onde a maioria dos projetos morre.
A UI é metade do jogo. O jogador de city builder passa o tempo inteiro lendo estado: quanto tem de cada recurso, o que cada construção faz, por que a população está insatisfeita. Painéis, tooltips, indicadores sobre o mapa. Se a UI não comunica, o jogo parece quebrado mesmo com a simulação correta. E fazer boa UI de simulação dá tanto trabalho quanto fazer a simulação.
Performance escala contra você. Cem agentes com pathfinding e necessidades individuais rodam de boa. Dez mil, não. Jogos como Cities Skylines existem porque equipes experientes gastaram anos otimizando simulação de multidão. Um iniciante que promete "cada cidadão é simulado" está assinando um contrato que não vai conseguir pagar.
Nada disso significa que você não deve fazer um city builder. Significa que você não deve fazer um SimCity.
O escopo realista para um indie
O corte que funciona: um village builder minimalista. Não uma metrópole, uma vila.
- Grid pequeno. Algo como 20x20 ou 32x32 células. Mapa pequeno força decisão de posicionamento, que é onde mora a graça do gênero, e mantém a simulação barata.
- 3 ou 4 recursos. Comida, madeira, ouro e talvez pedra. Cada recurso a mais multiplica as conexões que você precisa balancear e explicar na UI.
- Meia dúzia de construções. Casa, fazenda, serraria, mercado, armazém. Cada uma com um papel claro no loop.
- População agregada. Um número, não agentes andando pelo mapa. Habitantes "trabalham" nas construções por atribuição lógica, sem bonequinho caminhando até lá.
- Uma condição de progressão. Chegar a X habitantes, sobreviver Y estações, ou simplesmente sandbox com desbloqueios.
Against the Storm é uma boa referência cultural desse recorte: assentamentos pequenos, partidas curtas, foco em decisões econômicas em vez de simulação de trânsito. Você não vai fazer um Against the Storm no primeiro projeto, mas a filosofia de vila em vez de cidade é o caminho.
Os sistemas centrais, um a um
Com o escopo cortado, sobram quatro sistemas. Nessa ordem.
Grid e colocação de construções
No Godot 4, você tem duas opções. A primeira é usar o TileMapLayer para o terreno e converter coordenadas com local_to_map e map_to_local (no Godot 3 esses métodos se chamavam world_to_map e map_to_world, se você encontrar tutorial antigo). A segunda é um grid custom: um Dictionary que mapeia Vector2i para a construção ocupante, com a conversão de posição feita por divisão pelo tamanho da célula. Para um village builder, o híbrido funciona bem: TileMapLayer desenha o chão, Dictionary controla ocupação.
O fluxo de colocação é sempre o mesmo: mouse vira célula, célula é validada (livre? terreno permitido?), recurso é cobrado, construção é instanciada com snap na posição central da célula.
Economia por tick
Não simule por frame. Crie um Timer que dispara a cada 1 ou 2 segundos e processe a economia inteira nesse tick: cada fazenda soma comida, cada casa consome, o estoque é atualizado uma vez. Isso deixa o balanceamento legível (você raciocina em "comida por tick") e a performance trivial, porque a simulação roda poucas vezes por segundo em vez de sessenta.
População e felicidade simplificadas
População agregada com duas regras: cresce um habitante por tick se houver casa vaga e comida sobrando, encolhe se faltar comida. Felicidade pode ser um único valor de 0 a 100 derivado de dois ou três fatores (comida em estoque, casas suficientes, um prédio de bônus como o mercado). Felicidade alta acelera o crescimento, baixa trava. Só isso já produz o drama central do gênero: expandir rápido demais quebra a comida, que quebra a felicidade, que pune a expansão.
Save/load do estado
O estado de um village builder é pequeno: estoque de recursos, população, felicidade e a lista de construções com tipo e célula. Serialize isso num Dictionary, salve com FileAccess e JSON.stringify, e no load limpe o mapa e reconstrua a partir da lista. Implemente cedo. Save/load tardio é fonte clássica de refatoração dolorosa, porque força você a saber exatamente o que é estado e o que é derivado.
Colocação em grid no Godot 4, na prática
Um exemplo curto e tipado do sistema de colocação, usando TileMapLayer para conversão de coordenadas e um Dictionary para ocupação:
extends Node2D
@export var chao: TileMapLayer
@export var cena_casa: PackedScene
@export var custo_madeira: int = 20
var madeira: int = 100
var celulas_ocupadas: Dictionary = {}
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("construir"):
tentar_construir(get_global_mouse_position())
func tentar_construir(posicao_global: Vector2) -> void:
var celula: Vector2i = chao.local_to_map(chao.to_local(posicao_global))
if celulas_ocupadas.has(celula):
print("Célula ocupada")
return
if madeira < custo_madeira:
print("Madeira insuficiente")
return
madeira -= custo_madeira
var construcao: Node2D = cena_casa.instantiate()
construcao.position = chao.map_to_local(celula)
add_child(construcao)
celulas_ocupadas[celula] = construcao
O que importa aqui: local_to_map converte a posição do mouse em coordenada de célula, o Dictionary responde em tempo constante se a célula está livre, o custo é validado antes de qualquer instanciação e map_to_local devolve o centro da célula para o snap perfeito. Esse esqueleto aguenta o jogo inteiro; construções diferentes viram um recurso exportado a mais e uma tabela de custos.
O tick econômico segue a mesma simplicidade: um nó Timer com timeout conectado a uma função que percorre celulas_ocupadas.values() somando produção e subtraindo consumo.
Dicas de MVP: o que cortar sem dó
- Comece sem estradas. Estradas parecem essenciais porque todo city builder famoso tem, mas elas só existem para servir o pathfinding. Sem agentes andando, estradas são decoração cara. Adicione depois, se sobreviverem ao corte.
- Comece sem pathfinding. Habitante atribuído logicamente a uma construção entrega o mesmo loop econômico que habitante caminhando até ela, por uma fração do custo de desenvolvimento.
- Uma construção de cada tipo primeiro. Faça casa e fazenda funcionarem de ponta a ponta (colocar, produzir, consumir, salvar) antes de adicionar a terceira construção.
- UI feia, informação certa. Labels de texto cru mostrando recursos e felicidade bastam para validar o jogo. Polimento visual de UI é a última etapa, não a primeira.
- Balanceie numa planilha. Produção e consumo por tick cabem numa tabela. Dez minutos de planilha economizam horas de tentativa e erro dentro da engine.
O teste de que o MVP está pronto: uma sessão de 10 minutos em que o jogador coloca construções, quase quebra a economia, se recupera e cresce. Se esse loop prende, o resto é expansão.
Por onde começar
City builder recompensa quem constrói por camadas: grid primeiro, economia depois, população em seguida, e só então desbloqueios, eventos e estética. Cada camada é jogável sozinha, o que mantém o projeto vivo e testável do primeiro dia ao lançamento.
Se você ainda está montando a base para chegar nesse tipo de projeto, do GDScript aos padrões de arquitetura de jogo, um curso de criação de jogos para iniciantes encurta o caminho: você aprende os fundamentos com projetos guiados e chega no seu village builder sabendo exatamente onde cada sistema se encaixa.
Vila pequena, loop fechado, save funcionando. É assim que se faz um city builder de verdade: começando por um que você consegue terminar.
Perguntas frequentes
Como fazer um jogo de construir cidade?
Comece por quatro sistemas: um grid para posicionar construções, uma economia de produção e consumo rodando por tick, uma população com necessidades simples e save/load do estado. No Godot 4, o TileMapLayer resolve o grid com local_to_map e map_to_local, e um Timer resolve o tick econômico. Faça uma vila pequena antes de pensar em cidade.
Qual engine usar para city builder?
Godot 4 é uma ótima escolha para um city builder indie: o sistema de TileMap resolve grid e snap de posição, o Timer resolve o tick da economia e o GDScript é rápido de iterar. Unity também funciona bem. O que menos importa é a engine; o que decide o projeto é o corte de escopo.
City builder é difícil de fazer?
O gênero é mais difícil do que parece porque tudo se conecta: economia alimenta população, população alimenta produção, e a UI precisa mostrar esse estado o tempo todo. A dificuldade despenca quando você corta o escopo para um village builder com grid pequeno, 3 ou 4 recursos e sem pathfinding no início.
Como funciona a economia de um city builder?
A base é um loop de produção e consumo por tick: a cada intervalo fixo, construções produtoras adicionam recursos ao estoque e construções e habitantes consomem. Se a produção supera o consumo, o jogador cresce; se não, precisa reequilibrar. Fontes, drenos e conversões entre recursos formam o resto do sistema.
Dá pra fazer city builder 2D?
Dá, e é o caminho recomendado para o primeiro projeto do gênero. Um city builder 2D com visão de cima ou isométrica simplifica arte, câmera e colocação em grid, e o TileMap do Godot 4 já entrega quase tudo de graça. Against the Storm e vários village builders de sucesso provam que 2D não limita a profundidade.


