City Builder – Parte 2: Custom Gridmap

Evoluindo seu City Builder na Godot 4: De Malhas Estáticas a Cenas Multidimensionais

No desenvolvimento de jogos de simulação e gerenciamento urbano, partir de um protótipo básico é um excelente passo inicial, mas logo esbarra-se nas limitações de sistemas puramente estáticos. Kits iniciais de desenvolvimento — como o aclamado City Builder Starter Kit do Kenney — são ferramentas fantásticas para validação rápida de hipóteses, estruturados tipicamente em cinco scripts principais:

  • Builder: Responsável pela lógica de montagem e posicionamento na cena.
  • DataMap: Responsável pela serialização (salvamento e carregamento) dos dados do mapa.
  • DataStructure: O script que atua como modelo de dados para cada tipo de construção.
  • Structure: A representação física do tile injetado no mundo.
  • View: O controlador da câmera e perspectiva do jogador.

Contudo, para criar um simulador comercial escalável e robusto, é preciso realizar um expressivo upgrade arquitetural. Neste artigo técnico, analisaremos as 5 principais mudanças estruturais para elevar o nível do seu projeto na Godot 4, concluindo com um guia prático para criar estruturas multidimensionais.

As 5 Grandes Mudanças Arquiteturais

1. Do Estático ao Dinâmico: Substituindo Meshes por Cenas

A abordagem tradicional do nó GridMap nativo da Godot baseia-se em uma MeshLibrary padrão, que renderiza elementos tridimensionais estáticos (meshes). A grande virada de chave do projeto consiste em trocar essa biblioteca por uma coleção de Cenas (PackedScene), gerenciada por uma classe customizada chamada StructureLibrary.

No motor de jogo, a StructureLibrary atua essencialmente como um dicionário onde a chave é um identificador numérico único (int) e o valor é um objeto contendo os dados estendidos da estrutura (StructureData).

GDScript

GDScript
# Estrutura base do dicionário da StructureLibrary
var library = {
    ID (int): StructureData
}

O recurso StructureData armazena informações vitais como ID, nome descritivo, custo e, crucialmente, a referência da cena (PackedScene) correspondente. A vantagem técnica dessa transição é imensa: ao utilizar cenas em vez de malhas puras, cada bloco construído no mapa ganha a capacidade de carregar scripts próprios, animações complexas, emissores de partículas, lógica de tráfego interna e efeitos visuais independentes.

2. Quebrando o Limite: Estruturas Multidimensionais

Em kits básicos, o jogador fica restrito a posicionar elementos que ocupam exatamente o espaço de uma célula unitária ($1 \times 1$). Para permitir construções complexas, como grandes indústrias, estádios ou aeroportos, faz-se necessário estender o nó nativo por meio de um Custom Grid Map.

Esse script estendido introduz duas funções centrais na lógica de assentamento de blocos:

  • set_composite_structure()
  • erase_composite_structure()

Essas funções interceptam os comandos clássicos de posicionamento e realizam cálculos geométricos para reservar ou liberar blocos adjacentes na malha tridimensional sempre que uma cena exige dimensões maiores do que a escala base.

3. Escala Unidade vs. Escala Real

Muitos protótipos utilizam uma escala geométrica estritamente unitária ($1 \times 1 \times 1$ metro). Embora simplifique os cálculos iniciais, essa métrica dificulta a integração de assets profissionais criados por terceiros no Blender ou outras ferramentas de modelagem, que costumam seguir padrões de proporção realistas.

O Custom Grid Map corrige essa limitação padronizando o tamanho das células para as proporções de $10 \times 10 \times 10$ metros nas configurações de propriedades. Essa mudança cria uma paridade com referências do mundo real e simplifica exponencialmente a importação de novos pacotes tridimensionais de variados artistas.

4. Feedback Visual Preciso: O Seletor Dinâmico Inteligente

Em sistemas rudimentares, o seletor (o indicador luminoso que mostra onde o mouse está apontando) é um sprite estático de tamanho fixo. Ao introduzir prédios modulares de tamanhos variados, o seletor antigo torna-se impreciso e prejudica a experiência do usuário (UX).

A solução é o desenvolvimento de um seletor dinâmico. Ele lê em tempo real a propriedade de tamanho (size) da estrutura selecionada na biblioteca do jogador e expande suas dimensões visuais proporcionalmente. Para evitar distorções no modelo do indicador, utiliza-se uma técnica de repetição de textura (texture repeating), garantindo que a grade do seletor se alinhe perfeitamente aos limites do grid, independentemente da escala do objeto.

5. Lógica de Ocupação Customizada: O Dicionário de Células Ocupadas

O maior perigo ao permitir construções de tamanhos livres é o risco de sobreposição física de objetos (fazer um prédio nascer dentro do outro). O comportamento padrão do GridMap valida apenas a célula central de clique.

Para solucionar isso de forma robusta, foi criada uma matriz lógica paralela chamada _occupied_cells, estruturada como um dicionário customizado. Sempre que um prédio multidimensional é erguido, a função mapeia todas as coordenadas de grade que aquele volume cobre e adiciona essas chaves ao dicionário como “bloqueadas”. Antes de permitir qualquer nova construção, o Builder faz uma varredura instantânea nesse dicionário para verificar se alguma das células necessárias já está ocupada por outra entidade jurídica ou física do mapa.

Tabela Comparativa: Versão Base vs. Nova Versão

Abaixo, resumimos como as atualizações arquiteturais transformaram a infraestrutura do simulador de cidades:

Característica TécnicaVersão Base (Kenney Kit)Nova Versão (Aprimorada)
Elemento ConstrutivoMeshes Estáticas (MeshLibrary)Cenas Completas (PackedScene)
Dimensões PermitidasSomente 1×1Tamanhos Variados (Ex: 2×1, 2×2, 10×10)
Escala de ReferênciaEscala Unitária (1×1 metro)Escala Baseada no Mundo Real (metros)
Visual do SeletorSprite Simples com Escala FixaSprite Dinâmico com Repetição de Textura
Lógica de OcupaçãoPadrão Nativa do GridMapCustomizada via Dicionário _occupied_cells

Guia Prático: Criando uma Estrutura Multidimensional

Para demonstrar a simplicidade de operação do novo sistema na prática, vamos acompanhar o passo a passo para a criação e injeção de uma nova estrutura multidimensional: uma cena que representa a metade de um campo de futebol, ocupando o espaço correspondente a 2 células de largura por 1 de comprimento

Passo 1: Preparação da Cena 3D

  1. Crie uma nova cena 3D na Godot e dê o nome de facility_football.
  2. Posicione os modelos tridimensionais tracionados do seu diretório de assets para montar a metade do campo desejada. Salve o arquivo final.

Passo 2: Criação do Recurso de Dados (Resource)

  1. Navegue até a pasta de recursos do seu projeto (resource/structures/facility/).
  2. Clique com o botão direito na área vazia do sistema de arquivos e selecione Create New Resource.
  3. Busque pelo tipo customizado do script de dados do projeto: StructureData (ou DataStructure) e clique em criar.
  4. Salve o arquivo com o nome descritivo correspondente, por exemplo: facility_football.tres.

Passo 3: Parametrizando o Recurso no Inspector

Dê um duplo clique no arquivo .tres recém-criado para abrir suas propriedades no painel do Inspector e preencha-o detalhadamente:

  • ID: Insira o próximo número sequencial livre da sua biblioteca (ex: 13).
  • Name: Defina o nome de exibição (ex: facility_football).
  • Type: Categorize como facility.
  • Cost: Defina o custo financeiro do objeto (ex: 1500).
  • Size: Altere o vetor de tamanho informando as proporções multidimensionais exatas para a grade: X = 2 e Y = 1.
  • Scene: No campo reservado para a cena, arraste e solte o arquivo da cena 3D criado no Passo 1 (facility_football.tscn). Salve as alterações do recurso.

Passo 4: Registro na Biblioteca Global

  1. Abra o arquivo central que gerencia a biblioteca de estruturas do jogo (sua StructureLibrary ou o nó central do Builder).
  2. Localize a matriz ou array de estruturas exposto no Inspector e aumente o tamanho do array para abrir uma nova vaga.
  3. Arraste o recurso facility_football.tres para dentro do slot livre criado (neste exemplo, o slot de número 13).

O Resultado Prático

Ao executar a cena principal do jogo, navegue pelo catálogo até selecionar o campo de futebol. Você notará imediatamente que o seletor dinâmico se expandirá automaticamente no chão cobrindo o tamanho exato de duas células adjacentes. O sistema de dicionário de ocupação garantirá que nenhuma outra estrutura seja assentada incorretamente sobre os dois blocos protegidos pelo novo complexo esportivo virtual.

Conclusão e Próximos Passos

Modularizar a lógica do seu projeto substituindo malhas rígidas por cenas dinâmicas, adotando escalas globais realistas e implementando dicionários de ocupação customizados é o que diferencia um protótipo simples de um motor de simulação comercialmente viável.

Com a fundação de dados estruturada e a capacidade de assentar prédios de dimensões livres operando sem problemas, o projeto adquire o alicerce necessário para evoluções complexas de jogabilidade. O próximo grande marco arquitetural para o projeto é o desenvolvimento do RoadBuilder, o gerenciador inteligente de malhas rodoviárias que simplificará a construção de vias no mapa através de algoritmos de conexão automática de vizinhos (autotiling).


Revisado em

em

,

por

Comments

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *