Todas as páginas de formatos ↓
Unidades, scripts e configurações

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:

  1. Declarações dos lados: nome, prefixo, Comandante, fontes, cores.
  2. Disposição do HUD: coordenadas em pixels de cada barra de estado, rótulo e botão da interface do jogo.
  3. 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=1 recebe 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, de 0 a 255. Uma seção sem ID, 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, ExplodeAs e SelfDestructAs de 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 range ausente vale 32767; um minbarrelangle ausente vale -11.25 graus; reloadtime conta em ticks inteiros (30 por segundo, reloadtime*30 truncado: 0.35 recarrega 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 como 1.
  • Alcance, velocidade, aceleração: em pixels e pixels/s.
  • Área de efeito: raio em pixels, com edgeeffectiveness como 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, flighttime para projéteis do tipo starburst.
  • Tipo de renderização: rendertype=N escolhe 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 por SoundCategory= no FBI. O jogo lê 23 eventos, cada um como KEY e depois KEY1, 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":

  1. 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
    }
  2. 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/MaxWaterDepth da unidade deixam de importar.

  3. 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, mas weapons.tdf usa os dois. Os analisadores de teste aceitam os dois; algumas ferramentas de terceiros, não.
  • As coordenadas do HUD em sidedata.tdf partem 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 primeiro canbuildN que falta, então canbuild11 seguido de canbuild14 perde a entrada 14 e todas as seguintes, sem erro nenhum.
  • Uma MovementClass que 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 sem MaxWaterDepth passa então a entrar na água até a profundidade 10.000.

Veja também

  • TDF: a gramática do analisador, compartilhada com FBI/OTA.
  • Som: como sound.tdf e allsound.tdf se ligam.
  • FBI: as unidades referenciam MovementClass, SoundCategory e nomes de TDFs de armas.
  • Glossário: movement class (classe de movimento), footprint (área ocupada), side (lado).