Início › Info de modding › Criar um cérebro
Capítulo 07

Criar um cérebro

Um .oabrain que joga num lugar de computador: a pasta, todas as chaves do manifesto, as etiquetas, os níveis, a visão total, onde o script corre, as quotas e o que acontece quando para.

Este capítulo resume docs/brains/oabrain-standard.md, docs/brains/authoring.md e docs/playing-with-brains.md. Esses documentos são o texto normativo.

O que é um cérebro

O computador do próprio motor continua a ser a predefinição e continua no motor. Um cérebro joga num lugar de computador, e só num lugar em que um jogador o tenha colocado. Um id de cérebro vazio é esse jogador integrado. Um lugar sem cérebro, um cérebro incompatível e um cérebro que para são todos jogados por esse mesmo jogador. O Classic está escrito em Lua e joga como esse jogador. É documentação desse jogador, não um substituto.

Só a máquina que coloca o computador no lugar corre o script, por isso os outros jogadores não precisam de ter nada instalado. As máquinas deles espelham as unidades do lugar. Uma gravação reproduzida não corre o script. Um cérebro é código-fonte Lua e dados. Não tem código nativo, ficheiros, rede nem relógio. A visão total é uma marca no manifesto. Um cérebro pode defini-la e pode jogar com ela numa partida em rede, e o lugar mostra a marca.

O pacote

Um cérebro é um ficheiro .oabrain, ou a pasta para onde esse ficheiro se descompacta. O manifesto usa o YAML estrito de um perfil de mod: um documento, um único mapeamento de nível superior, sem âncoras nem escalares de bloco. O topo do pacote contém o oabrain.yaml. Ao lado dele, cada ficheiro é um dos seguintes. Um ficheiro fora desta lista é recusado.

my-brain.oabraino ficheiro que um jogador obtém├─ oabrain.yamlobrigatório o manifesto, no máximo 256 KiB├─ brain.luao script de entrada. O nome predefinido é brain.lua. entry indica outro, e esse ficheiro tem de estar no pacote├─ lua/mais código-fonte Lua. require só lê estes ficheiros. Cada parte tem letras minúsculas, algarismos e _├─ nets/uma rede que o manifesto indica, nets/ e um nome terminado em .oann├─ data/uma tabela de dados, a um nível de pasta: .csv, .tdf, .json ou .txt├─ icon.pnga imagem, só quando icon a indica. Sem essa chave, o ficheiro fica fora da lista├─ README.mduma nota no topo. O jogo não a carrega└─ LICENSEa licença no topo. O nome licence, e um readme numa subpasta, ficam fora da lista

A comparação ignora maiúsculas e minúsculas nas letras ASCII, exceto onde a norma diz que os bytes têm de coincidir. brain.lua fica fora da lista quando entry indica outro ficheiro. Um ficheiro Lua tem no máximo 1 MiB. O ícone é um PNG quadrado, com no máximo 256 píxeis de lado e 256 KiB. O OA instala um cérebro em Brains/ com o id do manifesto.

O manifesto

O leitor recolhe todas as regras infringidas e deixa o manifesto inalterado quando alguma regra é infringida. Uma chave que a norma não lista é recusada. Uma chave de perfil pertence a um mod. Uma chave de mutador é recusada como chave de mutador. Ponha uma versão entre aspas, porque um 1.0 simples é um número, e ponha um asterisco entre aspas, porque um asterisco simples é um alias de YAML.

ChaveObrigatórioO que faz
oabrainsimO formato. O número inteiro 1. 1.0 e um 1 entre aspas são recusados.
idsimKebab-case minúsculo, de 1 a 64 bytes. Sem hífen no início, no fim ou duplicado. O nome da pasta dentro de Brains/.
namesimDe 1 a 64 bytes, sem caracteres de controlo. O nome que os jogadores veem.
versionsimEntre aspas, de uma a três partes, como uma versão de mutador, por exemplo “2.0”. Um número simples é recusado. 2, 2.0 e 2.0.0 são considerados iguais.
authorsimUm mapeamento. name é obrigatório, de 1 a 128 bytes. email é opcional.
descriptionsimObrigatório, de 1 a 2000 bytes. É permitida uma quebra de linha. Qualquer outro caráter de controlo é recusado. A primeira linha, cortada a 200 bytes, é o resumo.
homepagenãoUm endereço http ou https.
iconnãoApenas icon.png, a imagem no topo do pacote. Qualquer outra coisa é recusada.
tagssimDe 1 a 4 das nove etiquetas abaixo, sem repetições.
works-withsimDe 1 a 32 condições, sem ids repetidos. Um asterisco significa qualquer mod e o jogo base, e nesse caso é a única entrada. ta-3.1c significa o jogo base sem mod. Qualquer outro id é um mod, com um intervalo de versões opcional.
requiresnãoApenas engine e expansions. engine é um intervalo, entre aspas quando começa por um sinal de maior. expansions tem de 1 a 16 ids de conjunto. Um cérebro não pode exigir um mutador.
levelssimDe 1 a 6 níveis. Cada mapeamento tem exatamente id, name e difficulty.
fullAwarenessnãotrue ou false. Se faltar, é false. Um true entre aspas é recusado.
networksnãoDe 1 a 16, cada uma com exatamente id, file e sha256. file é nets/ e um nome terminado em .oann. sha256 são 64 algarismos hexadecimais minúsculos entre aspas.
optionsnãoNo máximo 16, com as regras de opções do mutador. Um interruptor é true ou false, um número é um número e uma escolha é o seu texto. me.options lê-as.
stringsnãoNo máximo 16 idiomas. Um idioma pode conter name, description, options, labels e levels.
entrynãoUm ficheiro Lua no topo do pacote, com um nome de letras minúsculas, algarismos e _. Se faltar, é brain.lua.

As nove etiquetas

Uma etiqueta é uma destas nove, comparada byte a byte. Mais de quatro, quando a regra comum das etiquetas já foi cumprida, é um problema à parte. Uma etiqueta que não seja uma das nove é recusada.

Chave
classic
economy
rush
turtle
air
naval
learned
teaching
experimental

Níveis e dificuldade

levels é uma lista de 1 a 6 mapeamentos. Cada um tem exatamente id, name e difficulty, todos obrigatórios. id está em kebab-case minúsculo, de 1 a 32 bytes, e nenhum id se repete. name tem de 1 a 64 bytes, sem caracteres de controlo. difficulty é easy, medium ou hard, byte a byte.

Esses três nomes correspondem aos valores 0, 1 e 2. Um lugar que escolha o nível usa esse valor como regras de rendimento, a mesma dificuldade que o jogo já usa.

Visão total

fullAwareness é true ou false. Se faltar, é false. Um cérebro com a marca vê unidades que um lugar no nevoeiro não veria, tal como o computador integrado, e as suas verificações de local não precisam de um jogador que coloque. A marca é permitida numa partida em rede. A Biblioteca mostra Vê todas as unidades do mapa, como o computador do próprio Total Annihilation. A marca pertence ao próprio manifesto. Não é concedida pelo id do pacote, nem é uma das coisas que só o Classic recebe.

Onde um cérebro corre

Só a máquina que coloca o computador no lugar precisa do pacote, e só essa máquina corre o script. Um lugar é um computador desta máquina. Um lugar humano é recusado. game.mode é skirmish, campaign ou network.

SituaçãoO que corre
EscaramuçaCada lugar de computador que esta máquina joga, quando um jogador lhe atribuiu um cérebro. Um id vazio é o computador integrado.
Missão de campanhaO lugar da campanha segue o cérebro predefinido que o jogador escolheu. Uma missão não ignora essa predefinição.
Partida em redeA máquina dona do lugar de computador corre o cérebro, incluindo a visão total. As outras máquinas não.
Jogo guardado carregado mais tardeO jogo guardado indica cada lugar. A norma diz o que acontece quando falta o pacote ou a versão é diferente.
Gravação reproduzidaA gravação guarda o texto dos cérebros. A reprodução aplica os pacotes de rede gravados. Não coloca nenhum cérebro num lugar nem chama os seus hooks.
Deathmatch ou torneioO arranque da partida não coloca nenhum computador.

O cérebro que um lugar joga não entra no hash da simulação. Duas partidas que só difiram no cérebro colocado mantêm o mesmo hash do estado da partida. Os valores dos ajustes ai.* do mod fazem parte do perfil do mod que esse hash abrange, por isso continuam a chegar a todas as máquinas.

As quotas do runtime

Um cérebro corre como Lua numa sandbox. Dois cérebros não partilham módulos, variáveis globais nem quotas. O script não tem ficheiros, relógio, ambiente, processo nem rede. Todos os chunks são carregados como texto. pcall e xpcall não conseguem manter viva uma fase esgotada. Um turno é uma chamada que gasta do saldo acumulado, no ponto de controlo do lugar, depois da varredura de unidades. As ordens que um hook dá produzem efeito no tick seguinte.

QuotaValor
Instruções em load, fits, start, save e report50,000,000
Instruções que cada tick acrescenta2,000,000
Ticks que o saldo pode acumular, incluindo o tick atual30, por isso o saldo começa em 60,000,000
Memória Lua64 MiB (67,108,864 bytes). Não é reposta entre fases.
Memória das redes64 MiB, à parte do limite do Lua
Tempo real de uma fase que não é um turno, em milissegundos10,000
Tempo real de um turno, em milissegundos250
Uma cadeia de texto, em bytes65,536

Quando um cérebro falha

Um cérebro para por um erro num hook ou num temporizador, por esgotar a quota de instruções, pelo limite de segurança de tempo real, pelo limite de memória do Lua, por uma cadeia de texto com mais de 65 536 bytes ou por um carregamento que o lugar recusa. Um turno falhado fecha a sandbox e limpa os hooks antes de esse turno terminar. O turno que falhou conta na mesma como jogado. O tick de ordens seguinte já não tem hooks, por isso é o computador integrado que o joga. Um cérebro que é recusado, que não consegue arrancar ou que é incompatível nunca tem hooks, por isso esse jogador joga desde o início. O aviso usa o nome do manifesto e o motivo, cortado a 160 bytes:

- `{brain} stopped ({reason}); the engine plays this seat on`
- `{brain} could not start ({reason}); the engine plays this seat`
- `{brain} does not fit this game ({reason}); the engine plays this seat`

Quando o lugar não tem um motivo próprio, o motivo é the brain could not be seated. Um jogador derrotado deixa simplesmente de ser chamado. A sandbox fecha-se com a partida.