Criar um mutador
Um pequeno .oamut sobreposto ao jogo base ou a qualquer mod: a pasta, o manifesto, o plano que mutate devolve, as opções, a sandbox e a ordem pela qual uma pilha se aplica.
Este capítulo resume docs/mutators/authoring.md e docs/mutators/oamut-standard.md.
O que é um mutador
Um mutador é um pequeno pacote .oamut sobreposto ao jogo base ou a qualquer mod. Altera uma partida. A Biblioteca instala-o na pasta Mutators com o id do manifesto, e instalá-lo não o ativa. É o jogador que o ativa para uma escaramuça, uma sala de batalha ou uma campanha. works-with indica os mods com que é compatível, e um asterisco significa qualquer mod e o jogo base.
O pacote
O topo da pasta contém o oamut.yaml. O script de entrada fica ao lado: mutator.lua, a não ser que entry indique outro, e nunca dentro de files/, rules/ ou lua/. lua/ contém mais código-fonte Lua, os únicos ficheiros que require lê. files/ contém os bytes que a camada Ficheiros pode acrescentar. rules/ contém ficheiros de regras cujos nomes terminam em .sm. Um ícone é o PNG que o manifesto indica. Uma nota cujo nome termine em .md ou .txt é transportada para as pessoas, e o jogo não a carrega. Um ficheiro fora desta lista é recusado. A comparação ignora maiúsculas e minúsculas nas letras ASCII.
my-mutator.oamuto ficheiro que um jogador obtém├─ oamut.yamlobrigatório o manifesto├─ mutator.luao script de entrada, mutate(ctx)├─ lua/opcional; módulos Lua, os únicos ficheiros que require lê├─ files/opcional; modelos, scripts e outros bytes├─ rules/opcional; ficheiros de regras .sm├─ icon.pngopcional; o PNG indicado em icon└─ README.mduma nota; o jogo não a carregaO manifesto
YAML estrito, com as mesmas regras de um perfil de mod: um documento, um único mapeamento de nível superior, sem âncoras nem escalares de bloco. O ficheiro começa com oamut definido como o número inteiro 1. Uma chave que a norma não lista é recusada. Ponha entre aspas um valor que comece por um sinal de maior, e também um asterisco, ou o leitor toma-os por outra coisa. É por isso que requires.engine fica entre aspas. Uma versão também fica entre aspas: um número simples é recusado.
| Chave | Obrigatório | O que faz |
|---|---|---|
oamut | sim | O formato. O número inteiro 1. 1.0 e um 1 entre aspas são recusados. |
id | sim | Kebab-case minúsculo, de 1 a 64 bytes. Sem hífen no início, no fim ou duplicado. O nome da pasta de instalação. |
name | sim | De 1 a 64 bytes, sem caracteres de controlo. O nome que os jogadores veem. |
version | sim | Entre aspas, no máximo 32 bytes. Uma a três partes unidas por um ponto, cada uma um número de 0 a 65535 sem zeros à esquerda. |
author | sim | Um mapeamento. name é obrigatório, de 1 a 128 bytes. email é opcional. |
description | não | Opcional, de 1 a 2000 bytes. É permitida uma quebra de linha. A primeira linha, cortada a 200 bytes, é o resumo que o catálogo mostra. |
homepage | não | Opcional, de 1 a 256 bytes. Um endereço http ou https. |
icon | não | Opcional. O caminho, no pacote, de um PNG quadrado, terminado em .png. O instalador verifica a imagem. |
tags | sim | De um a quatro ids, sem repetições. Os oito que a Biblioteca desenha estão abaixo. |
works-with | sim | De uma 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. |
requires | não | Opcional. Apenas engine e mutators. engine é um intervalo entre aspas, comparado com esta compilação. mutators indica pacotes que têm de estar ativos. Estes aplicam-se antes deste, pela ordem em que estão escritos. |
conflicts-with | não | Opcional. Mutadores com os quais este se recusa a funcionar. Um id aqui não pode ser um dos indicados em requires.mutators, nem o próprio id deste mutador. |
layers | sim | De um a nove nomes, sem repetições: files, units, weapons, features, sides, tables, menus, maps e hacks. Um plano só pode escrever numa camada indicada aqui. |
clashes | não | Opcional, add ou replace: o que este mutador faz com uma unidade ou arma cujo nome já existe no jogo. Primeiro conta a escolha do jogador, depois esta chave, depois a preferência mutators.clash-default, que é replace quando não está definida. |
options | não | Opcional, no máximo 16. Definições que o jogador escolhe antes da partida. ctx.options lê-as. |
strings | não | Opcional, no máximo 16 etiquetas de idioma. Traduções do nome, da descrição e das etiquetas das opções. |
entry | não | Opcional. O script de entrada, um caminho no pacote terminado em .lua e fora de files/, rules/ ou lua/. mutator.lua, se for omitido. |
legacy | não | Opcional, de 1 a 16 registos de mutadores do TA: Mutation que este pacote substitui. Cada registo tem name, prefix, compatibility e files. Um mapeamento simples é recusado. |
As oito etiquetas
O leitor aceita qualquer etiqueta em kebab-case minúsculo, de 1 a 32 bytes, até quatro. A Biblioteca desenha um ícone e uma designação traduzida para estes oito ids, com correspondência exata. Qualquer outro id aparece tal como foi escrito, sem ícone. Quando o manifesto não indica um ícone, o emblema usa o ícone da primeira etiqueta, se esse id for um dos oito.
| Chave | O que faz |
|---|---|
statistics | Estatísticas |
economy | Economia |
commanders | Comandantes |
new-units | Novas unidades |
disable | Desativação |
gameplay | Jogabilidade |
ai | IA |
maps | Mapas |
O plano
O script de entrada define mutate. O motor chama mutate(ctx) uma vez, na fase de plano, e essa chamada, por si só, não altera o jogo. mutate devolve uma tabela. Uma tabela vazia não altera nada. Uma chave que o motor não conhece é recusada.
files é uma tabela com add e mask. Cada um é uma lista de texto, e qualquer um pode ser omitido. add indica pastas do pacote, por ordem, e uma pasta posterior prevalece num caminho que ambas contenham. mask oculta caminhos. rules é uma lista de blocos acabados, feitos com where, all, named ou on e depois :change, e de caminhos sm que indicam um ficheiro .sm. Uma alteração é set, scale, lock, remove ou append. scale pode receber um limite inferior e um superior, e esse limite restringe apenas esse fator. Os hooks são funções. Correm por esta ordem: units, weapons, features, sides, tables e, por fim, menus. maps corre depois de todos os mutadores, e só quando a partida já escolheu um mapa. hacks define, só para esta partida, um parâmetro que o registo de parâmetros abre aos mutadores. É declarar a camada que permite a escrita.
Opções e ctx
Durante mutate, ctx contém o mod (o seu id, versão e jogo), a versão do motor, as opções e ctx.incompatible. ctx.mod.id é ta-3.1c quando não há nenhum mod ativo. Chamar ctx.incompatible com um motivo para este mutador, e o motivo é o texto que o jogador vê. As coleções ainda não estão carregadas. Um hook pode ler units, weapons, features, sides, tables e menus em ctx sem declarar a camada. Para escrever numa, precisa da camada.
ctx.options tem um campo por cada id de opção. Um interruptor é true ou false. Um número, e uma escolha cujos valores são números, é um número. Uma escolha cujos valores são identificadores é texto. Uma opção que o jogador não alterou fica com a predefinição. type é toggle, choice ou number. Uma escolha lista de 2 a 16 valores, todos números ou todos identificadores, e labels quando as palavras diferem dos valores. Um número tem min, max, step e default. O jogador só pode escolher um valor entre min e max que caia num passo, por isso o script não precisa de testar de novo o intervalo: um valor fora de um passo é recusado antes de o script correr. O id da opção é um nome Lua, e uma palavra reservada do Lua é recusada.
A sandbox
O script corre como Lua numa sandbox. Não tem ficheiros, rede, relógio, ambiente nem processo. io, os, debug, package e coroutine não são abertos, e um chunk pré-compilado é recusado. Todos os chunks são código-fonte. Dois mutadores não partilham estado.
Cada fase recomeça com a quota completa de instruções, 50 000 000, e com o limite completo de tempo real de 10 segundos. O limite de memória é de 64 MiB e não é concedido de novo na fase seguinte. Uma cadeia de texto tem no máximo 65 536 bytes. Use fixed para um atributo que o script calcule. Conta em 65 536 avos, para que o mesmo script escreva o mesmo texto em todas as máquinas. pairs percorre as chaves por uma ordem fixa. O resultado não depende da máquina.
Empilhamento
O jogador ordena os mutadores numa lista, aplicada de cima para baixo. O primeiro aplica-se primeiro. Cada um dos seguintes vê o jogo tal como os de cima o deixaram. Os mutadores indicados em requires.mutators são ativados com este e aplicam-se antes dele, pela ordem em que essa lista os escreve. Mais de 32 mutadores, um id listado duas vezes, um requisito que nenhum dos de cima cumpre, ou dois em conflito, fazem recusar a lista inteira, e nada corre.
Primeiro são sobrepostos os ficheiros de todos os mutadores, pela ordem da lista, e um mutador posterior prevalece num caminho. Depois, cada mutador, pela mesma ordem, lê os seus próprios ficheiros de unidades, de armas e de download como registos, aplica as suas regras e corre os seus hooks. As regras aplicam uma alteração de cada vez, por uma ordem fixa. Um fator multiplica o número atual, e um limite restringe apenas esse fator, não um posterior. Uma atribuição substitui o valor atual. Um lock define o valor e impede todos os mutadores posteriores de alterar esse campo. Dentro de um bloco Lua, as alterações correm pelo nome do campo depois de convertido para minúsculas ASCII, e não pela ordem em que a tabela foi escrita. Não há médias entre mutadores. Depois de todos os mutadores se terem aplicado, um número de unidade ou de arma que exceda a largura que o jogo guarda, e um número de elemento que exceda o intervalo que o jogo lê, fica no extremo desse intervalo, uma única vez.