TDFs do gamedata: tabelas de configuração do motor
Fonte: coreprime/kbot @ 0ab97bf · Editar no GitHub
Os arquivos de
gamedata/são arquivos de texto TDF que configuram o próprio motor: classes de movimento, categorias de dano das armas, dados de cada lado (disposição da interface, menus de construção, unidades iniciais), associações de som e algumas pequenas tabelas de consulta. Os mods que mudam as regras do jogo (em vez de acrescentar unidades) quase sempre mexem aqui.
Esta página documenta os arquivos de gamedata mais úteis. Todos usam a gramática TDF, no estilo INI. Veja TDF para os detalhes do analisador.
Tip
Experimente você mesmo.
ls $(kbot ctx path)/gamedata/
# The web UI renders these as collapsible section trees
kbot mount $(kbot ctx path) --server
# → browse to gamedata/sidedata.tdf, then sidedata > [CANBUILD]
Visão geral dos arquivos
| Arquivo | O que controla |
|---|---|
sidedata.tdf |
Disposição da interface de cada lado, Comandante inicial, menus de construção. O maior arquivo de gamedata/. |
moveinfo.tdf |
Classes de movimento: que terreno cada "MovementClass" consegue atravessar. |
weapons.tdf |
Documento de referência da gramática dos TDFs de armas (quase só comentários; não é uma tabela usada pelo jogo). |
category.tdf |
Descrições legíveis das categorias de unidades. Só cosmético. |
sound.tdf |
Categorias de som por unidade (referenciadas por SoundCategory= no FBI). |
allsound.tdf |
Sons da interface e de eventos do jogo (cliques de botão, avisos da barra de placar, música de fundo). |
los.tdf |
Ajuste da linha de visão (modificadores do raio de visão por terreno). |
meteor.tdf |
Parâmetros da chuva de meteoros (usada por alguns mapas da campanha). |
unitview.tdf |
Disposição do painel de informações da unidade durante o jogo. |
buildinfo.tdf |
Teclas de atalho e textos de dica do menu de construção. |
version.tdf |
A string de versão do jogo que o lobby informa. |
translate.tdf |
Tabela de consulta de localização das strings da interface. |
help.tdf |
Entradas do sistema de ajuda do jogo. |
Os três principais para criar mods são sidedata.tdf (menus de
construção, lados), moveinfo.tdf (classes de movimento) e
weapons.tdf (que é documentação, não dados: as armas de verdade
ficam em weapons/*.tdf).
moveinfo.tdf: classes de movimento
O FBI de uma unidade declara a sua MovementClass=KBOTSS2 (ou
algo parecido). O motor procura essa classe em moveinfo.tdf para decidir
que terreno ela consegue atravessar.
O TA 3.1c lê só as seções [CLASS0] a [CLASS31] (a primeira seção com
cada um desses nomes) e encontra uma classe pelo seu Name=, sem
diferenciar maiúsculas de minúsculas, começando pela posição mais baixa.
Quando a classe da unidade é encontrada, os valores da classe
substituem por completo os próprios FootprintX/FootprintZ,
MaxWaterDepth, MinWaterDepth e as chaves de inclinação da unidade (o
MaxSlope=20 do Comandante dá lugar aos 32 de TANKDS2), e uma chave que
a classe omite recebe o padrão do jogo indicado abaixo, não o valor do
FBI. Uma unidade sem classe, ou que nomeia uma classe que o jogo não
encontra, lê as suas próprias chaves do FBI com os mesmos padrões. Os
metadados de unidade, a sandbox e as partidas hospedadas do KBot Studio
resolvem o movimento dessa forma.
[CLASS0]
{
Name=KBOTSS2; // Class name referenced from FBIs
FootprintX=2; // Cells wide (16-px units)
FootprintZ=2; // Cells deep
MaxWaterDepth=12; // Deepest water it can enter
MaxSlope=32; // Steepest land slope it can climb
}
[CLASS3]
{
Name=TANKDH3;
FootprintX=3;
FootprintZ=3;
MaxWaterDepth=100; // Heavy tank — can ford deep water
MaxWaterSlope=30; // Slope limit *underwater* (separate from MaxSlope)
MaxSlope=15;
}
Campos
| Campo | Tipo | Significado |
|---|---|---|
Name |
string | Identificador da classe referenciado por MovementClass= nos FBIs das unidades. Não diferencia maiúsculas de minúsculas. |
FootprintX, FootprintZ |
int | Área ocupada para o cálculo de caminhos, em células de atributo de 16 px. Substitui a área ocupada do FBI da unidade; 0 quando a classe a omite. |
MaxWaterDepth |
int | Água mais profunda (em unidades de altura do terreno) em que a unidade consegue entrar. 0 = só terra. Padrão 10000 (qualquer profundidade): as classes de hovercraft o omitem, por isso um hovercraft anda sobre qualquer água, diga o FBI o que disser. |
MinWaterDepth |
int | Profundidade mínima de água exigida (barcos, submarinos). Padrão -10000 (sem mínimo). |
MaxSlope |
int | Inclinação máxima que a unidade consegue subir em terra (unidades = 2π / 256 radianos). Padrão 255; limitado por MaxWaterSlope. |
BadSlope |
int | Inclinação a partir da qual a unidade anda com velocidade reduzida (mais devagar, mas sem ser bloqueada). Padrão: metade de MaxSlope; limitado por MaxSlope. |
MaxWaterSlope |
int | O mesmo que MaxSlope, aplicado debaixo d'água. Padrão 255 (sem limite, usado para hovercrafts). |
BadWaterSlope |
int | Equivalente de BadSlope debaixo d'água; padrão: metade de MaxWaterSlope. |
Convenções de nomes
O nome da classe descreve a sua forma numa etiqueta curta, pela convenção da Cavedog:
| Prefixo | Significado |
|---|---|
KBOT |
Kbot bípede |
TANK |
Veículo de esteiras ou rodas |
BOAT |
Embarcação de superfície |
SPID |
Aranha / rastejador de muitas pernas |
HOVER |
Hovercraft |
Depois vem um sufixo SS / SF / DS / DH / SH (pequeno/fundo/
pesado etc.) e um dígito da área ocupada. Os nomes são só uma
convenção: o motor trata Name= como uma chave opaca.
Important
Duas unidades com a mesma MovementClass= compartilham o mesmo
comportamento de busca de caminho. Se você mudar KBOTSS2 para
MaxWaterDepth=50, todos os Kbots pequenos passam a atravessar a água.
Se quiser um ajuste por unidade, acrescente uma classe nova.
sidedata.tdf: configuração de cada lado
Este é o arquivo mais longo de gamedata/, porque reúne três assuntos
distintos:
- Declarações dos lados: nome, prefixo, Comandante, fontes, cores.
- Disposição do HUD: coordenadas em pixels de cada barra de estado, rótulo e botão da interface do jogo.
- Menus de construção: a seção
[CANBUILD], que lista o que cada construtor pode construir.
O bloco de lado
[SIDE0]
{
name=ARM;
nameprefix=ARM;
commander=ARMCOM; // UnitName of the commander unit
intgaf=ARMINT; // GAF used for intro screen
font=console; // FNT for general text
fontgui=armbutt; // FNT for buttons
energycolor=208; // Palette index for energy bars
metalcolor=224; // Palette index for metal bars
// …followed by ~60 HUD coordinate sub-sections
[LOGO] { x1=132; y1=5; x2=152; y2=25; }
[ENERGYBAR] { x1=471; y1=12; x2=598; y2=14; }
[METALBAR] { x1=218; y1=12; x2=345; y2=14; }
...
}
[SIDE1] { name=CORE; ... }
| Campo | Significado |
|---|---|
name |
Nome exibido do lado (também usado na correspondência de categorias). |
nameprefix |
Prefixo de string acrescentado às consultas de localização. |
commander |
UnitName da unidade Comandante do lado. |
intgaf |
Sequência GAF mostrada durante a escolha da facção. |
font / fontgui |
Arquivos FNT para o texto e os botões do HUD. |
energycolor / metalcolor |
Índices da paleta para as barras do HUD (índices de palette.pal). |
O TA 3.1c lê os lados [SIDE0], [SIDE1], … em ordem, parando no
primeiro número que falta e depois do quinto. Uma seção com qualquer outro
nome ([SIDE01], um [SIDE3] depois de um [SIDE2] ausente, um sexto
lado) nunca é lida, e cada lado lido precisa de todos os retângulos do
HUD descritos abaixo (ta.SideRectangles do kbot-io), senão o jogo não
carrega lado nenhum. O seletor de lado da sandbox do studio oferece os
mesmos lados.
Subseções de coordenadas do HUD
Cada elemento visível do HUD é um bloco [NAME] com coordenadas em pixels
x1/y1/x2/y2. Elas são relativas à resolução base de 640×480. Nos modos
maiores, o motor faz a escala.
[ENERGYBAR] { x1=471; y1=12; x2=598; y2=14; }
Para mudar a barra de energia de lugar, edite os quatro números. Para
mudar o visual dela, troque o GAF que o HUD usa para desenhar nessa
posição (definido em unitview.tdf).
[CANBUILD]: menus de construção
A definição estática do menu de construção. Cada construtor lista o que pode construir no início da partida:
[CANBUILD]
{
[ARMCOM]
{
canbuild1=ARMSOLAR; // Slot 1 on the build menu
canbuild2=ARMWIN;
canbuild3=ARMESTOR;
canbuild4=ARMMSTOR;
canbuild5=ARMMEX;
...
}
[ARMLAB]
{
canbuild1=ARMCK;
canbuild2=ARMPW;
...
}
}
O número da posição é o lugar na página do menu de construção. O menu de
construção do TA é uma grade de 2 colunas × 3 linhas, por isso cada
página comporta 6 posições: canbuild1–canbuild6 são a página 1,
canbuild7–canbuild12 são a página 2, e assim por diante.
Como o TA 3.1c lê a tabela (CanBuildBuilder.BuildList do kbot-io;
kbot document, o visualizador de unidades e o menu de construção da
sandbox seguem essa leitura):
- Só uma unidade cujo FBI define
Builder=1recebe uma lista. Uma subseção para qualquer outra unidade é ignorada. - O jogo lê a primeira seção
[CANBUILD]e, dentro dela, a primeira subseção com o nome do construtor (sem diferenciar maiúsculas de minúsculas). - Ele lê
canbuild1,canbuild2, … e para no primeiro número que falta:canbuild1=ARMSOLAR; canbuild3=ARMLAB;dá uma única entrada. - Um nome que não corresponde a nenhuma unidade é pulado, e uma lista guarda no máximo 30 unidades. As entradas de download (abaixo) podem levar o menu de um construtor a 31. (Documentações mais antigas às vezes diziam 12 posições por página. A grade real do jogo tem 6.) Veja a referência da árvore de construção do TA para a disposição por página de cada construtor do jogo base.
Important
Em mods, NÃO edite sidedata.tdf para acrescentar unidades. O
padrão aprovado pela Cavedog para pôr uma unidade no menu de construção
é distribuir um arquivo download/<UNITNAME>.tdf junto com o resto do
mod: o motor mescla todos os download/*.tdf sobre a tabela estática
[CANBUILD] de sidedata.tdf na inicialização.
Editar sidedata.tdf só faz sentido se você distribuir uma conversão
total que reescreve toda a disposição do HUD e do menu de construção.
Até a expansão Core Contingency da própria Cavedog acrescenta as suas
unidades novas por download/*.tdf, sem modificar sidedata.tdf.
Veja TDF: [MENUENTRY] e o
tutorial de criação de mods.
weapons.tdf: referência dos TDFs de armas
Apesar do nome, gamedata/weapons.tdf é quase só comentários: é a
referência publicada pela Cavedog para a gramática dos TDFs de armas, e o
jogo nunca o carrega. As definições reais das armas ficam em
weapons/*.tdf, uma seção por arma (veja TDF). kbot document
não lista as seções de gamedata/weapons.tdf como armas.
A tabela de armas
O TA 3.1c monta uma tabela de 256 posições de arma a partir dos arquivos
.tdf que estão diretamente em weapons/ (não nas subpastas), na ordem
em que os lista:
- Uma seção vai para a posição que o seu
ID=indica, de0a255. Uma seção semID, ou com um fora dessa faixa, é pulada. - Uma seção posterior com o mesmo
ID, no mesmo arquivo ou num arquivo posterior, substitui a anterior. Weapon1/Weapon2/Weapon3,ExplodeAseSelfDestructAsde uma unidade nomeiam uma seção. O nome (sem diferenciar maiúsculas de minúsculas) aponta para a posição mais baixa que tem uma seção com esse nome.- Os valores são lidos como prefixos numéricos:
weaponacceleration=13O;vale 13, e um valor inválido nunca descarta o resto do arquivo. - Uma estrutura quebrada faz o jogo recusar o arquivo inteiro, e
nenhuma das suas armas é carregada, nem as seções anteriores ao erro: um
cabeçalho de seção sem
]ou sem{, texto sem=ou um valor sem;antes do fim do arquivo, o arquivo terminando dentro de uma seção, ou um arquivo vazio. Os outros arquivos não são afetados. (Um}solto fora de qualquer seção não é recusado: o jogo para de ler ali e mantém o que veio antes.) - Um
rangeausente vale32767; umminbarrelangleausente vale-11.25graus;reloadtimeconta em ticks inteiros (30 por segundo,reloadtime*30truncado:0.35recarrega depois de 10 ticks, 0,333 s);turnrateé em unidades de ângulo por segundo (65.536 = uma volta completa).
O KBot Studio, os pacotes e o kbot host resolvem as armas por esta
tabela. Os arquivos que o jogo recusa e as seções que ele pula ou
substitui são informados como avisos (kbot pack os mostra; o studio os
serve em /api/studio/weapons/warnings).
Sprites de rendertype=4
Uma arma com rendertype=4 dispara um sprite 2D de anims/fx.gaf, e o
seu color= escolhe qual: 0 cannonshell, 1 plasmasm, 2 plasmamd,
3 ultrashell, 4 plasmasm de novo. Qualquer outro valor (como o
color=255 de EARTHQUAKE) não desenha sprite nenhum. O sprite avança um
quadro por tick do jogo a partir do momento do disparo, quaisquer que
sejam as durações dos quadros no GAF.
Os comentários de referência documentam:
- Três arquétipos de arma:
ballistic,lineofsight,dropped. Todo TDF de arma precisa definir um deles como1. - Alcance, velocidade, aceleração: em pixels e pixels/s.
- Área de efeito: raio em pixels, com
edgeeffectivenesscomo a fração de queda (por exemplo,0.5= metade do dano na borda). - Rajada e dispersão:
burst,burstrate,sprayangle. - Armas de duas fases:
twophase,weapontype2,flighttimepara projéteis do tipo starburst. - Tipo de renderização:
rendertype=Nescolhe modelo 3D, bitmap com paleta, feixe etc.
A subseção [DAMAGE] é onde ficam os modificadores de dano por
categoria de alvo:
[FLAMETHROWER] {
...
[DAMAGE]
{
default=10; // Damage applied to anything not listed
corpyro=2; // Pyros are nearly fire-proof
}
}
As chaves de [DAMAGE] são nomes de unidades: uma unidade listada
recebe esse dano em vez de default=, e todas as outras recebem
default=. Os valores são guardados em 16 bits. As explosões de morte
(ExplodeAs, SelfDestructAs) usam a mesma tabela: CORPYRO_BLAST causa
60 por padrão, mas 15 a um Pyro.
category.tdf: descrições das categorias de unidades
Uma lista simples e cosmética que associa marcadores de categoria a textos legíveis. O motor os mostra no painel de informações da unidade:
[Plant] { description = Unit Creation plant; }
[KBOT] { description = Some type of units; }
[Tank] { description = Some type of units; }
[Metal] { description = Some type of units; }
Os traços no lugar das descrições são um texto padrão deixado sem querer pela Cavedog. A maioria dos mods não mexe neste arquivo. Alguns trocam as descrições por textos de ambientação de verdade. Mudá-lo não afeta a jogabilidade.
sound.tdf e allsound.tdf
Tratados em WAV / Som. Em resumo:
sound.tdf: associações de som por categoria de unidade (as seções[ARM_COM],[ARM_KBOT]). Referenciadas porSoundCategory=no FBI. O jogo lê 23 eventos, cada um comoKEYe depoisKEY1,KEY2, … até o primeiro número que falta.allsound.tdf: associações de som globais da interface ([BIGBUTTON],[SKIRMISH],[BGM]).
Exemplo comentado: acrescentar uma classe de movimento
Para criar uma classe de "barco que consegue atravessar água muito rasa":
Acrescente ao fim de
gamedata/moveinfo.tdf:[CLASS20] { Name=AMPHIB3; FootprintX=3; FootprintZ=3; MaxWaterDepth=100; // Deep water OK MaxSlope=20; // Reasonable land climbing MaxWaterSlope=200; // Smooth underwater movement }No FBI da sua unidade:
MovementClass=AMPHIB3;A área ocupada e os limites da classe substituem os do FBI, por isso as chaves
FootprintX/FootprintZ/MaxWaterDepthda unidade deixam de importar.Empacote:
kbot hpi pack ./mymod --target mymod.ufo
Agora a unidade atravessa terra e água sem problemas.
Note
Só [CLASS0] a [CLASS31] são lidas. Uma classe em [CLASS32],
[CLASS100] ou [HOVERXL] nunca é encontrada, e as unidades que a
nomeiam recorrem às suas próprias chaves do FBI. Escolha uma posição
livre abaixo de 32 (a versão comercial usa de CLASS0 a CLASS14).
Uma segunda seção com o mesmo nome de posição é ignorada.
Tamanhos típicos
| Arquivo | Faixa observada em gamedata/ da Cavedog |
|---|---|
sidedata.tdf |
~50 KB |
moveinfo.tdf |
~3 KB (15–20 classes) |
sound.tdf |
~20 KB (mais de 300 categorias) |
weapons.tdf |
~2 KB (quase só comentários) |
category.tdf |
~1 KB |
| Outros arquivos de gamedata | < 5 KB cada |
Armadilhas
Warning
Muitos arquivos de gamedata são carregados uma vez, quando o motor inicia, e não a cada mapa. Para testar uma mudança, é preciso reiniciar o jogo: recarregar o lobby não basta. Isso pega muitos modders que acham que a mudança "não pegou".
- As posições das classes de movimento são fixas. Só
[CLASS0]a[CLASS31]são lidas. Lacunas na numeração dentro dessa faixa não são problema. - Os comentários usam
//, não/*…*/, na maioria dos arquivos, masweapons.tdfusa os dois. Os analisadores de teste aceitam os dois; algumas ferramentas de terceiros, não. - As coordenadas do HUD em
sidedata.tdfpartem da base de 640×480 e são ampliadas pelo motor nas resoluções maiores. Não escreva coordenadas em resoluções modernas. - A numeração de
[CANBUILD]não pode ter lacunas. O jogo para de ler a lista de um construtor no primeirocanbuildNque falta, entãocanbuild11seguido decanbuild14perde a entrada 14 e todas as seguintes, sem erro nenhum. - Uma
MovementClassque o jogo não encontra não é um erro. A unidade usa, sem aviso, as suas próprias chaves do FBI, com os padrões do jogo para as que faltam: uma unidade semMaxWaterDepthpassa então a entrar na água até a profundidade 10.000.