← Bonemark

Modding

Adicione conteúdo escrevendo pequenos arquivos de texto. Não é preciso programar nem compilar. Em cinco partes: instalar o mod de outra pessoa, seu primeiro mod, mudar o jogo que já existe, uma referência com cada família e cada código de diagnóstico, e conviver com isso. A tabela do que você pode criar é medida na build, não prometida.

Usando mods

Onde está a pasta mods

Abra Mods no menu principal. O caminho está escrito na parte superior da tela, com um botão próximo a ele que abre a pasta no seu gerenciador de arquivos.

Está ao lado dos seus salvamentos e é a mesma pasta, quer você esteja instalando o mod de outra pessoa ou escrevendo o seu próprio. Nada é lido enquanto o jogo está em execução, então não importa se o jogo está aberto enquanto você move os arquivos.

Instale um

Um mod é uma pasta com mod.json no topo. A maioria dos downloads é aquela pasta dentro de um zip.

1. Extraia-o Para que a pasta que contém mod.json fique diretamente dentro da pasta mods. Um zip extraído para northern_reach/northern_reach/mod.json é um nível muito profundo e o jogo não o verá.
2. Reinicie o jogoOs pacotes são lidos na inicialização. Não há instalação a quente.
3. Ligue Abra Mod e use o switch. Uma pasta copiada é encontrada e deixada desativada: nada carrega simplesmente por aparecer em uma pasta.
4. Reinicie novamente A linha diz Ativo — reinicie para carregar até que você faça isso. Então aparece Carregado.

Um mod para o qual você copia permanece desativado até que você o diga. O jogo rejeita executáveis ​​sem questionar, mas um pacote de dados ainda pode alterar preços, itens e pessoas de maneiras que você não solicitou, e um pacote que aparece sozinho dentro de um jogo já em execução é um problema que ninguém quer diagnosticar. Então o jogo pergunta. É uma reinicialização extra na primeira vez e nunca mais para esse pacote.

Não há iniciador, não há arquivo de ordem de carregamento para editar e não há nada para gravar. A ordem de carregamento é um número dentro de cada embalagem, escolhido pelo seu autor.

Comece uma nova partida para um pacote que adicione pessoas, lugares ou missões. Um save já em andamento mantém o mundo com que foi criado. Pacotes que mudam apenas números, imagens ou cores são visíveis em uma partida já iniciada. Arquivos de áudio e fontes são validados, mas nenhuma superfície de pacote em execução os consome ainda.

Carregou?

Mod, no menu principal. Cada pacote encontrado fica em uma linha, com status de uma palavra: carregado, desabilitado, inválido, conflitante, requer outro mod, ignorado.

Um mod também pode desligar sozinho e diz o porquê. A opção que você coloca se aplica ao pacote em que você o colocou, não ao seu nome na pasta. Os mod ids são escolhidos pelos autores e não há nada para coordená-los, então dois mods não relacionados, ambos chamados northern_reach, são um acidente comum - e sem isso o segundo herdaria a opção do primeiro. Se o mod sob um id não for aquele que você ativou, a linha diz: este não é o mod que você ativou. Atualizar um mod preserva sua mudança; exclua-o e copie outro não.

Se você é o autor de um mod e vê essa linha em seu pacote, você tem uma colisão de ID com o mod de outra pessoa. Escolha uma identificação menos óbvia.

Duas dessas palavras são sobre uma reinicialização que você deve, não sobre o pacote. Ativo — reiniciar para carregar significa que você ligou e ninguém leu ainda; Desligado — reiniciar para baixar significa o contrário, e seu conteúdo ainda estará no jogo até você reiniciar. São palavras separadas propositalmente: uma tela que diz “Carregado” no momento em que você aperta um botão o enviaria a uma busca pelo mundo por algo que ainda não existe.

Quando o estado não está "carregado", a linha abaixo informa por que, no idioma em que você está jogando e sem identificadores, você não escreveu: qual arquivo o jogo se recusa a executar, qual pacote está faltando, qual versão ele deseja. Abaixo, o que fez o conteúdo do pacote: quantas entradas entraram, quantas foram rejeitadas. Mostrar detalhes abre o restante, ou seja, os ids e a regra exata que cada registro rejeitado quebrou.

Na telaNo relatórioO que isso significa
CarregadoactiveCarregável, sem obstáculos.
InválidoinvalidO manifesto traz scripts bloqueados ou arquivos executáveis.
Requer outro modskipped_missing_dependencyUma dependência declarada está ausente ou desabilitada.
Requer outro modskipped_incompatible_dependencyUma dependência declarada está fora do seu alcance.
IgnoradoincompatibleO mod tem como alvo uma versão mais recente do jogo.
ConflitanteconflictDois mods carregáveis ​​apontam para o mesmo ID de substituição (eles permanecem carregáveis; load_order vence, ambos relatados).
DesabilitadodisabledVocê desligou ou nunca ligou. Os pacotes são de escolha livre: colocar um na pasta instala e não liga.
Ligado — reinicie para carregarVocê ligou e ninguém leu ainda. Seu conteúdo não estará no jogo até você reiniciar.
Desligado – reinicie para baixarVocê desligou e ainda está carregado. Seu conteúdo permanece no jogo até você reiniciar.

Duas linhas compartilham uma palavra propositalmente: Requer outro mod É o mesmo problema para um jogador, quer o pacote que ele precisa esteja faltando ou seja a versão errada, e a linha abaixo diz qual. E quando dois pacotes reivindicam o mesmo registro, aquele com o load_order mais alto escreve por último e vence — mas uma aquisição que ninguém declarou é um erro, não uma nota. Ambas as linhas são relatadas, e a linha do perdedor nomeia o vencedor, e o vencedor ainda é calculado em vez de ser deixado ao acaso: uma rejeição não precisa ser também um sorteio. Quando dois mods querem a mesma coisa explica como declarar um de propósito.

“Carregado” ainda não significa que você pode vê-lo no mundo. Para isso, leia as contagens abaixo da linha, e Agora encontre no jogo informa onde cada tipo de coisa aparece.

As contagens sempre somam. Camas são aplicadas, mais rejeitadas, mais substituídas por outro mod, mais esperando por suas próprias condições - e as duas últimas são nomeadas em vez de permanecerem um buraco. Um registro que outro pacote escreve por último não é rejeitado, porque não há nada de errado com ele, e nem mesmo é aplicado, porque não foi isso que o jogo manteve. É a diferença entre ler uma linha e passar uma noite procurando um bug em um arquivo que não contém nenhum. Mostrar detalhes informa qual registro e qual pacote o possui agora.

Um número está próximo a essa soma em vez de dentro: arquivos que ninguém leu. Um arquivo cuja família não está em content_types nunca foi aberto, portanto não há registro para contar e não há como saber quantos estão nele. É uma contagem de arquivos, não de registros, e é exatamente por isso que não pode ser um sexto termo: a soma começa em lido, e estes nunca foram lidos.

Antes de pedir ajuda a alguém

Abra Mod e pressione Copiar relatório. Cole tudo em sua mensagem e diga o que você esperava.

Texto simples, pronto para um fórum, uma mensagem do Discord ou um relatório de bug: a versão em que você está, a pasta mods, cada pacote com sua versão, sua ordem de carregamento e status, o motivo de cada rejeição, as contagens para cada tipo de conteúdo e qual pacote venceu cada batalha.

the report the Mods screen copies

Bonemark mod report
game build: 0.0.0-dev
mods folder: C:/Users/you/AppData/Roaming/Godot/app_userdata/Bonemark/mods
packages: 2 found, 1 loaded

PACKAGES
  northern_reach  v0.1.0  order 100  active
    goods: 12 read, 12 applied, 0 rejected
  winter_roads  unreadable manifest
    - game_version must not be empty

CONTENT (1 families: 12 read, 12 applied, 0 rejected)
  goods: 12 read, 12 applied, 0 rejected

Nove em cada dez vezes a resposta está no bloco e ninguém precisa fazer uma única pergunta primeiro. Ele não lê nada fora da pasta mods, não altera nada e não contém informações pessoais.

Está em inglês mesmo quando você está jogando em outro idioma. Isso é intencional: a pessoa que está ajudando você pode não ler o seu, e todos os fatos que ele contém — ids, versões, contagens — ainda são os mesmos em todos os idiomas.

Remover um

Exclua sua pasta e reinicie. A desinstalação está toda aqui.

Nada seu é excluído junto com ele. Um salvamento mantém os ids que não pode mais resolver, sinaliza-os e retorna itens se o pacote for reinstalado. Uma sessão que não consegue entender um salvamento nem mesmo o sobrescreve: o arquivo original permanece exatamente como estava, e é a diferença entre uma tarde perdida e um jogo perdido. Saves é o relatório completo.

Se o jogo parar de funcionar após você instalar algo, a saída não precisa do jogo. Abra a pasta mods e remova a última coisa que você adicionou. Os pacotes só podem ser lidos nessa pasta, portanto, uma pasta que não existe é um pacote que não pode ser carregado e a próxima inicialização é a mesma de antes. Você não precisa de um menu de trabalho, console ou inicialização para fazer isso.

Até o jogo tenta sozinho - Se o jogo não iniciar é um número limitado de tentativas e depois um caminho de volta sem nenhum pacote carregado - mas esse é o cinto, e mover a pasta são os suspensórios.

Comece aqui

O que você pode construir hoje

Agora, sem pedir nada a ninguém: mercadorias e os comerciantes que as vendem, itens, pessoas e onde ficam, edifícios e seus serviços, lugares no mapa, conversas, cenas, planos de missão, mapas desenhados no Tiled, imagens e cores, e todas as palavras para isso em sete idiomas. Arquivos de áudio e fontes são verificados e lidos, mas suas superfícies de pacote ainda não os consomem; a tabela de status diz isso claramente em vez de chamá-los de prontos. Todas as famílias são a lista medida, e seu status vem do build, não de uma promessa.

Ainda não, e O que você ainda não pode fazer explica cada caso: a família quests, áudio de pacote, fontes de pacote, conversões totais empacotadas e um pacote que seja uma funcionalidade em vez de conteúdo.

Nunca, devido à escolha do projeto: código. Sem scripts, sem cenas, sem arquivos de recursos, nada para o jogo rodar. É isso que torna seguro baixar o mod de um estranho, e não é uma fase pela qual o projeto está passando. O que um mod nunca pode fazer.

Tempo para a primeira coisa que você pode ver no jogo: Cerca de dez minutos, a maior parte gasto para encontrar a pasta. Um mod em dez minutos está completo, e a espada no final é real.

O que você ainda não pode fazer e por quê

Está escrito aqui, perto do começo, em vez de ficar para ser descoberto no fim. Isto é o que o build valida sem colocar atualmente em uma superfície de pacote voltada ao jogador, além do que não é conteúdo de pacote.

O quePor que nãoIsso vai mudar
A família questsEle é reconhecido e verificado e não há nenhum mapeador de tempo de execução por trás dele, portanto, um pacote direcionado a ele ignora todas as verificações e não instala nada. Em vez disso, escreva Suas missões: quest_plans é uma família viva e é isso que o jogo realmente diz.Sim, quando o mapeador é público
Áudio de pacoteDescritores e arquivos de áudio são validados e lidos, mas nenhuma superfície em execução consome ainda um sinal de áudio do pacote; um mod pode fornecer som que permanece silencioso.Sim
Fontes de pacoteDescritores de fontes e cobertura de idiomas são validados, mas nenhum tema em execução consome ainda uma fonte do pacote.Sim
Um pacote de conversão totalA construção entende o manifesto e traz consigo o acessório Ashen Reach. O que falta é o fluxo de trabalho empacotado para os criadores, não o mecanismo. Uma conversão total.Sim
Um pacote que é um recursoDecidido na íntegra e nenhuma família o carrega, então nenhum cartaz pode solicitá-lo. Every family lista-o entre as coisas que ainda não têm uma pasta.Sim
O que quer que seja feitoUma camada de script não virá. O manifesto carrega um tipo de pacote que envia comportamento, a única coisa que poderia autorizar sua execução o rejeita, não há sandbox por trás dele e um pacote que o declara é rejeitado hoje. O que um mod nunca pode fazer.Não

Uma mecânica que o jogo nunca teve é ​​a quarta linha com outro chapéu. Uma espada que bate com mais força é um número e é sua; uma arma que dispara um raio precisa das regras do raio, e as regras são códigos que alguém escreve e testa.

O que é um mod

Uma pasta de arquivos de texto. Você não escreve código. Você escreve listas de coisas que deseja no jogo e o jogo as lê quando começa.

PalavraO que isso significa
PacoteSeu mod. Uma pasta com seu nome.
Manifestomod.json, no topo dessa pasta. Quem é você, o que você traz.
RegistroUma coisa você adiciona. Uma espada é um recorde.
FamíliaTipo de coisa. Espadas, capacetes e pão são todos items. Cada família tem sua própria pasta.
Eu iayour_package:the_thing — por exemplo northern_reach:frost_blade.

A única regra da qual todo o resto segue: você pode adicionar e alterar dados. Você não pode fazer o jogo executar código. É isso que torna seguro baixar um mod: o pior que um mod de um estranho pode fazer é colocar uma espada boba em você.

34 famílias estão prontas para usar hoje, entre elas items, buildings, pois, npc_definitions, vendor_inventories, quest_plans, caravans e perks. Todas as famílias formam a tabela completa com o que cada uma faz; As famílias, uma por uma mostra seus campos e um registro para copiar.

Escolha o seu caminho

Este é o índice de todo o guia — onde cada tópico é escrito, esteja você construindo-o hoje ou não. No topo da Parte 3 há um segundo índice mais curto: são os seis tutoriais, na ordem em que se complementam. Se você está aqui para fazer alguma coisa e não para procurar alguma coisa, vá direto para lá.

Você querVá para
Construindo algo do início ao fimComece pelo que você quer fazer — os seis tutoriais, apenas um pacote
Carregue um arquivo em dez minutosUm mod em dez minutos
Pesquise campos para uma família e um exemploAs famílias, uma por uma
Veja tudo o que você tem permissão para fazerToda família
Mudando algo que o jogo já traz consigoMudar o que o jogo já tem
Adicione sua própria arte, som, letras ou corImagens, som, letras, cor
Desenhe um lugar no TiledSeus mapas
Escreva uma missão[Suas missões](#missões próprias)
Entenda por que nada apareceu[Nada apareceu](#nada apareceu)
Procure um código de erroCada código de diagnóstico
Saiba o que um mod nunca pode fazerO que um mod nunca pode fazer
Não quebre o salvamento de alguémSalva
Coloque-o onde as pessoas possam levá-loCompartilhe

Ou o que está em sua mente. Essa orientação é organizada na ordem em que o trabalho acontece – manifesto, depois validação, depois conteúdo e depois relatório – que é a ordem que alguém que já conhece o sistema escolheria. Quem não o conhece está pensando Quero adicionar um comerciante, e procura a palavra comerciante:

Você está adicionandoAs famílias que fazem issoOnde estão escritos
Comércio e mercadoriasgoods, vendor_inventories, caravans, recipesCoisas, comércio e os números por trás de uma briga
Coisas que um jogador traz consigoitems, combat_balanceCoisas, comércio e os números por trás de uma briga
Pessoasnpc_definitions, mercenary_templates, noble_houses, relationships, perks, enemy_archetypes, enemy_variants, group_archetypesPessoas, casas e o que podem fazer
Lugares e edifíciosbuildings, pois, maps, world_generationO mundo e os lugares nele
Palavras que um jogador lêlocales, dialogue, scenes, lore, mr_lines, quest_plans, quest_metadata, progressHistória, missões e as palavras que um jogador lê
Como parece e como soaimages, audio, fonts, themes, effects, presentation_bindings, screensComo tudo parece e soa
Comandos e dificuldadesinput_bindings, settings, adaptiveO que o jogador controla e o que assiste

O que você precisa

O jogoNecessárioSem Godot, sem compilador, sem etapas de construção.
Um editor de texto que entende JSONNecessárioVS Code, Sublime, Notepad++ — tudo grátis. O Bloco de Notas do Windows funciona e não irá ajudá-lo.
Um editor de pixel artApenas pela sua arteAseprite (~20 €), ou grátis: LibreSprite, Piskel, Krita, GIMP.
Um editor de áudioApenas pelo seu somAudacity. Efeitos curtos do nada: sfxr, ChipTone.
LadrilhadoSomente para seus mapasLivre. Exporte para .tmj.

Um editor que colore JSON mostra uma vírgula faltando enquanto você ainda está olhando para ela, em vez de fazer com que o jogo informe mais tarde que o arquivo estava ilegível.

Python e o console são opcionais. O jogo basta: coloque o pacote, reinicie e abra Mods, que informa cada registro recusado e o motivo. O checkout para autores é público. Quem quiser iterar mais rápido ou automatizar lançamentos pode clonar o checkout público do Bonemark e executar as ferramentas offline em Ferramentas offline; jogadores que instalam um pacote lançado não precisam de Python nem Godot. O mesmo checkout público contém o validador e as declarações do runtime, então as duas seções descrevem uma única cadeia de ferramentas. As ferramentas usam as mesmas declarações do jogo — os esquemas de registros e o limite de segurança têm uma fonte cada — e por isso respondem mais cedo, nunca de forma diferente. Um console de depuração ajuda a inspecionar um pacote carregado, mas não é necessário para escrever um.

Crie um

Comece com o que você quer fazer

Tudo abaixo desta linha está organizado na ordem em que o trabalho acontece: cartaz, depois arquivos, depois famílias e depois relatórios. É a ordem certa para procurar algo e a ordem errada para começar, porque ninguém começa com um manifesto. Começa com Quero um comerciante.

Depois: escolha a frase que mais se assemelha ao que você está tentando fazer.

Você querVá paraQuanto tempo leva
Adicione algo para comprar e vender[Um produto bom para vender](#um produto bom para vender)15 minutos
Adicione algo que um jogador carregue consigoUm item para carregar10 minutos, depois do acima
Adicione uma pessoa que vendeUm comerciante que o detém30 minutos
Adicione uma porta em um assentamentoO serviço de um edifício20 minutos
Adicione um lugar no mapa mundialUm lugar no mapa20 minutos
Mudando algo que o jogo já possuiMudando o que já existe15 minutos
Desenhe um mapa, escreva uma missão, traga arteSeus mapas, Suas missões, Imagens, som, letras, corpor mais tempo, e todos os três são famílias vivas
Traga a família quests, um pacote de conversão total ou um pacote que seja um recursoAinda não. [O que você ainda não pode fazer e por que](#o que você não pode fazer ainda e por que) dá o motivo de cada um e diz quais deles mudarão.
Adicione uma regra que o jogo nunca teveNada aqui acontece e nada acontecerá. O que um mod nunca pode fazer diz o porquê, em um parágrafo.

Os seis tutoriais são um pacote único, construído uma peça de cada vez: uma vela de cera de abelha, o pacote que um jogador carrega consigo, o fabricante de cera que a vende, a porta de sua loja, o poço atrás do curtume de onde vem o sebo e, finalmente, uma modificação na vela que o jogo já tinha. Faça-os em ordem e termine com um mod que alguém possa baixar. Coloque um no meio e ele funcionará sozinho.

Onde estão os números do jogo

Cada tutorial aqui avalia uma coisa nova comparando-a com algo que o jogo já vende, porque um número sem nada próximo a ele é uma suposição, e uma suposição em uma economia que negocia entre cidades não fica onde você a coloca.

Você não pode abrir os arquivos do jogo. Seus registros são ativos Godot dentro do pacote de compilação — um formato diferente do JSON que você escreve, com category = 1 onde seu arquivo diz "MANUFACTURED". Não há pasta para copiar e descompactar uma não é um fluxo de trabalho que alguém precise documentar.

Você não precisa disso. O catálogo publica o conteúdo do jogo, gerado a partir desses mesmos registros a cada construção: 270 itens com sua categoria, peso, valor de moeda e tamanho da pilha, 49 armas, 42 peças de armadura, 37 localizações. É a referência na qual este guia está ancorado, não pode divergir do jogo e o nome do campo está impresso ao lado de cada linha.

Uma dúzia de valores para saber antes de colocar preço em algo:

O jogo já está vendendoMoedasE
Argila, pedra, junco1o chão. Cavar ou cortar, não há trabalho dentro
Grão, madeira2
Vela3uma noite leve
Lã, peixe, uvas4
Pão6comida de um dia
Sal, mel, corda8
Pano (peça)10tecido com 2 lãs e 1 junco
Ferro refinado, peixe salgado12
Pimenta preta14uma importação, e você pode sentir isso
Couro, queijo15
Vinho25
Armas de uma mão50–300a banda, nem um único valor
Armas de duas mãos150–600
Prato pesado500–1500o teto de toda a economia

Se a sua novidade custar mais do que uma armadura de placas, algo deu errado e o jogo não lhe dirá - ela se tornará silenciosamente a carga mais lucrativa do mundo, e todas as caravanas a carregarão.

Uma mercadoria para vender

Você terá uma mercadoria que a economia sabe precificar, atrelada à vela que o jogo já vende, pronta para um comerciante segurar.

Captura de tela: Ainda não tirada. Este espaço permanece vazio até que haja um espaço real: um desenho de sua aparência seria a única coisa na página que não é real.

Leia primeiro: [O que é um mod](#o que é um mod) · [Um mod em dez minutos](#um mod-em-dez-minutos) · Nomes e ids

Copiar de: a pasta chamada chandlery, que já está na sua pasta mods. O jogo coloca lá na primeira vez que inicia, desligado, e é o resultado final desses seis tutoriais: todos os registros abaixo estão lá. É também o pacote que a pista de teste do repositório gira contra o carregador, então não há registro aqui de que o jogo rejeitaria. Ligue-o para ver funcionar ou copie a pasta, renomeie-a e torne-a sua.

Para onde vão os arquivos:

where the files go

mods
└ chandlery
  ├ mod.json
  └ content
    └ economy
      └ goods
        └ goods.json

Comece pela vela que o jogo já possui. Chama-se candle, custa 3, pesa 0,5, é MANUFACTURED e PRESERVED, e é feita pelo boticário. A sua é a mesma coisa feita de cera melhor, então guarde todas essas respostas e troque duas.

Antes de mod.json:

mod.json

{
  "id": "chandlery",
  "name": "The Chandlery",
  "version": "0.1.0",
  "game_version": "0.0.0-dev",
  "dependencies": [],
  "load_order": 100,
  "content_types": ["goods"],
  "overrides": [],
  "canon_safe": true
}

Então content/economy/goods/goods.json:

a goods record

[
  {
    "id": "chandlery:beeswax_candle",
    "display_name": "Beeswax Candle",
    "category": "MANUFACTURED",
    "decay_tier": "PRESERVED",
    "base_price": 9,
    "weight": 0.4,
    "production_class": "chandler",
    "daily_consumption_class": "household",
    "tags": ["light", "household"]
  }
]
CampoPor que esse valor
idO nome do seu pacote, dois pontos e depois sua palavra. Qualquer coisa sem o seu namespace na frente é rejeitada, então você não pode pegar a identidade de outra pessoa por acidente.
display_nameO que um jogador lê. Nenhum artigo — «Vela de cera de abelha», nunca «Uma vela de cera de abelha»: o artigo é dado pela frase que o rodeia, e qual artigo depende do idioma. Palavras que um jogador lê.
categoryMANUFACTURED, porque alguém faz isso. Os cinco são matéria-prima, artefato, consumíveis, munição e equipamento, e aquele que você escolhe decide quais edifícios de produção e caravanas serão afetados.
decay_tierPRESERVED — 90 dias, como a vela do jogo. A cera é preservada; não é preservado para sempre. PERISHABLE dura 7 dias e ETERNAL nunca apodrece.
base_price9. A vela simples do jogo custa 3 e um pote de mel custa 8. A cera de abelha vem das mesmas colmeias que o mel e queima sem cheiro de gordura derretida, por isso fica logo acima do mel e é cerca de três vezes melhor que a vela de sebo. Não é uma importação: a pimenta-do-reino tem 14 anos e atravessou o mar.
weight0,4, um pouco abaixo de 0,5 da vela simples. Peso é o que uma caravana pode carregar, então uma mercadoria que não pesa nada e vende caro é um bug que você está escrevendo de propósito.
production_classQue profissão ela exerce? chandler é aquele que o pacote de referência usa.
daily_consumption_classQuem consome. household significa que as cidades o consomem constantemente e é isso que mantém o comerciante abastecido.
tagsPalavras livres. Outros registros e seus arquivos subsequentes podem pesquisá-los.

Concluído – agora encontre-o no jogo. Reinicie, abra Mod e a linha abaixo da sua diz 1 entry added. É tudo o que uma mercadoria faz por si só: tem um preço, é comercializável e não fica no balcão de ninguém, porque ninguém a tem ainda. Não é um fracasso e é o que confunde todo mundo uma vez. Continue com Um comerciante que estoca.

Se não for mostrado: Nada apareceu tem os seis motivos em ordem. De longe, o mais comum é content_types - uma família ausente nessa linha significa que a pasta nunca é aberta, seja lá o que ela contenha. Então Antes de pedir ajuda a alguém, que é um único botão.

Um objeto para carregar

Você terá aquilo que um jogador pega, guarda em sua mochila e revende, junto com a mercadoria que você acabou de escrever.

Captura de tela: Ainda não tirada.

Leia primeiro: [Um produto bom para vender](#um produto bom para vender) · Nomes e IDs

Copiar de: chandlery/content/inventory/items/items.json para sua pasta mods.

Para onde vão os arquivos:

where the files go

mods
└ chandlery
  ├ mod.json
  └ content
    ├ economy
    │ └ goods
    │   └ goods.json
    └ inventory
      └ items
        └ items.json

Uma mercadoria e um objeto são duas metades da mesma coisa. A mercadoria é o ponto de vista da economia: o que uma cidade produz, o que uma caravana transporta, quanto vale. O objeto é o ponto de vista do jogador: o que cabe na mochila, o que está empilhado, o que está exposto em uma loja. O trigo tem mercadoria e não tem objeto, porque ninguém carrega um saco de trigo. As velas têm ambos.

Adicione "items" a content_types em mod.json e escreva content/inventory/items/items.json:

a items record

[
  {
    "id": "chandlery:beeswax_candle_bundle",
    "display_name": "Bundle of Beeswax Candles",
    "category": "MATERIAL",
    "rarity": "COMMON",
    "weight": 0.4,
    "max_stack": 20,
    "base_value": 10,
    "sellable": true,
    "tags": ["light", "household"]
  }
]
CampoPor que esse valor
idSua identificação, não a das mercadorias. São registros diferentes em famílias diferentes e nada os obriga a corresponder: combiná-los é seu trabalho, e a linha comercial abaixo é onde o emparelhamento acontece.
categoryMATERIAL, que é a vela do jogo. Não CONSUMABLE: você não come nada.
rarityCOMMON. Raridade é o que as mesas de saque e as lojas leem quando rolam; acontece uma coisa comum.
weight0,4, como a mercadoria. Quando os dois não concordam, a mochila do jogador e a caravana não concordam no mesmo item.
max_stack20, como pão quente e como o pacote de referência. Vinte é a pilha comum do jogo para pequenas coisas que você carrega consigo; 1 é para algo único.
base_value10 versus 9 para as mercadorias. Um pacote tem um pequeno prêmio sobre o preço a granel – o pacote de referência é 4 versus uma mercadoria 3, e este é o mesmo formato um passo acima.
sellableÉ verdade, caso contrário, um comerciante não poderá comprá-lo de volta de você.

Concluído — agora encontre-o no jogo. Um item que ninguém entrega é carregado e acessível do nada. Em uma compilação de depuração, item chandlery:beeswax_candle_bundle coloca um em sua mochila imediatamente e é a prova mais rápida de que ele está carregado - mas esse comando não existe no jogo que as pessoas baixam, então é um atalho para você e nunca a resposta para um jogador. A verdadeira resposta é o próximo tutorial.

Se não for mostrado: Nada apareceu, então Antes de pedir ajuda a alguém.

Um comerciante que o detém

Você terá uma mulher com um nome em Old Seat com um balcão, suprimentos que são reabastecidos a cada dois dias e suas velas no balcão.

Captura de tela: Ainda não tirada.

Leia primeiro: Um item para carregar · Agora encontre-o no jogo

Copiar de: chandlery/content/narrative/npcs/npcs.json e chandlery/content/world/vendor_inventories/vendors.json.

Para onde vão os arquivos:

where the files go

mods
└ chandlery
  ├ mod.json
  └ content
    ├ economy
    │ └ goods
    ├ inventory
    │ └ items
    ├ narrative
    │ └ npcs
    │   └ npcs.json
    └ world
      └ vendor_inventories
        └ vendors.json

Este é aquele onde duas famílias têm que concordar. A pessoa carrega o id do banco, o banco carrega o id da pessoa e cada linha do banco carrega o id de um objeto. Três ids, e cada um deve ser escrito exatamente como você escreveu no outro arquivo. É o erro que custa uma noite, e a tela Mods o nomeia: uma linha apontando para um ID que ninguém fornece está listada como requer outro mod que não esteja instalado.

Adicione "npc_definitions" e "vendor_inventories" a content_types.

a npc_definitions record

[
  {
    "id": "chandlery:hesta",
    "display_name": "Hesta the Chandler",
    "title": "Candle Seller",
    "short_bio": "She renders fat behind the tannery and sells what burns longest.",
    "voice_tone": "brisk",
    "faction": "NONE",
    "role": "NONE",
    "settlement_id": "old_seat",
    "is_vendor": true,
    "vendor_inventory_id": "chandlery:candle_stall",
    "price_multiplier": 1.0,
    "personality_tags": ["brisk", "practical"],
    "offers_quest_ids": []
  }
]

a vendor_inventories record

[
  {
    "id": "chandlery:candle_stall",
    "display_name": "Chandler's Stall",
    "npc_id": "chandlery:hesta",
    "global_price_multiplier": 1.0,
    "buyback_rate": 0.35,
    "entries": [
      {
        "item_id": "chandlery:beeswax_candle_bundle",
        "kind": "misc",
        "daily_stock": 6,
        "price_multiplier": 1.0,
        "restock_days": 2,
        "min_standing": 0
      }
    ]
  }
]
CampoPor que esse valor
settlement_idUse um id de assentamento criado pelos autores. Os ids de assentamento são criados pelos autores e estáveis: Durnwall, Thorngate, Valdmere, Grentham e as doze vilas podem receber nome. A seed muda o terreno e os biomas ao redor delas, a escassez do ano e a organização política, não o id.
is_vendor + vendor_inventory_idJuntos eles transformam uma pessoa em uma loja. Um sem o outro é uma pessoa que não consegue vender ou um balcão que ninguém cuida.
price_multiplier1,0 — pergunta quanto valem as coisas. Acima de 1 é um lugar que sabe que você não tem opções; os comerciantes do jogo estão em 1,0 se não houver motivo no mapa.
buyback_rate0,35: Pague cerca de um terço do valor pelo que você vende a ela. É o número que os jogadores mais ouvem e é aquele que o dealer do pacote de referência utiliza.
daily_stock6. Quantos ele tem quando o banco reabastece. Seis é o valor do pacote de referência para uma casa barata; um é para algo que uma cidade vê duas vezes por ano.
restock_days2, então ele é reabastecido a cada dois dias — e não no dia em que você instala o mod. É por isso que um novo comerciante parece vazio à primeira vista. Em uma compilação de depuração, day avança um dia.
min_standing0: Qualquer pessoa pode comprar. Acima de zero estão as ações que ela mantém para as pessoas de quem gosta.
kindEm que tipo de balcão está - misc para produtos domésticos. Os outros são weapon, armor, shield, consumable e ammo.

Concluído – agora encontre-o no jogo. Reinicie, viaje para Old Seat, encontre Hesta, abra a tela de negociação. Se o banco estiver vazio, ainda não foi reabastecido: isso é restock_days, não é um bug. A cadeia pode ser quebrada de três maneiras e todas as três estão na tela do Mod: as mercadorias que ninguém possui, o contador que aponta para um id de item que não existe, a pessoa que aponta para um id de contador que não existe.

Ela também pode falar. Uma dialogue_graph cujo ID speaker é seu ID faz piadas quando um jogador clica nelas, e seu pacote não precisa redefinir nada que o jogo já tenha para obtê-las — veja Suas Conversas. Um arquivo locales oferece tudo isso em sete idiomas.

Se nada aparecer: primeiro compare os três IDs, depois Nada apareceu e depois Antes de pedir ajuda a alguém.

O serviço de um edifício

Você terá uma porta em um assentamento com sua etiqueta e cor, que se abre para um interior que o jogo já possui.

Captura de tela: Ainda não tirada.

Leia primeiro: Um comerciante que mantém · [O que um mod nunca pode fazer](#o que um mod-pode-nunca-fazer)

Copiar de: chandlery/content/world/buildings/buildings.json.

Para onde vão os arquivos:

where the files go

mods
└ chandlery
  └ content
    └ world
      └ buildings
        └ buildings.json

Você está recombinando, não construindo. Um registro buildings adiciona um novo serviço com um rótulo, cor de porta e função de rotina, e pode reutilizar uma extensão que o jogo já possui nomeando-a. Não é possível trazer uma extensão. Uma extensão é uma cena, uma cena é um código e um pacote com o nome de um caminho res:// ou .tscn é rejeitado antes mesmo de esse registro ser lido. Não é um buraco esperando para ser preenchido: é a linha que torna seguro instalar o mod de um estranho.

a buildings record

[
  {
    "id": "chandlery:chandlery",
    "label": "Chandlery",
    "role": "merchant",
    "color": { "r": 0.44, "g": 0.38, "b": 0.24 },
    "interior_service": "shop"
  }
]
CampoPor que esse valor
labelAs palavras na porta. Se você omitir, o jogo colocará seu id em maiúscula e será lido como um id.
roleO que as pessoas fazem dentro de casa o dia todo — merchant coloca a rotina do lojista atrás da porta. O papel é o vocabulário do jogo, não o seu: um estranho ataca e age como se não fosse nada em particular.
colorCera de abelha marrom, 0.44 / 0.38 / 0.24. Cada canal varia de 0 a 1, e uma string hexadecimal HTML também funciona. Escolha algo que corresponda ao tamanho de uma porta desenhada - Art That Fits.
interior_serviceshop — o interior que o jogo já projeta para uma loja. O truque está todo aqui: você consegue um quarto mobiliado de verdade sem trazer um.

Concluído – agora encontre-o no jogo. Reinicie e insira um assentamento que tenha seu serviço. Um registro sem settlement é carregado e colocado em lugar nenhum, o que é idêntico a um registro com falha: a tela do Mod dirá 1 entry added e você não encontrará nada. Leia a linha antes de procurar a porta.

Se não aparecer: Nada apareceu · Antes de pedir ajuda a alguém.

Um lugar no mapa

Você terá um ponto no mapa mundial onde um jogador poderá encontrar, com uma descrição dele e seu efeito no clima do grupo.

Captura de tela: Ainda não tirada.

Leia primeiro: O serviço de construção · Agora encontre-o no jogo

Copiar de: chandlery/content/world/pois/pois.json.

Para onde vão os arquivos:

where the files go

mods
└ chandlery
  └ content
    └ world
      └ pois
        └ pois.json

As coordenadas são absolutas e o mundo é gerado ao redor de lugares criados pelos autores. O mapa mede 61 440 × 34 560 pixels do mundo e Old Seat fica exatamente no centro, (30720, 17280), em toda partida. As cidades e vilas criadas pelos autores mantêm seus nomes e posições. A seed muda o terreno e os biomas ao redor delas, a escassez do ano, a organização política e quais estradas valem a pena. Um ponto continua sendo real e estável; o que fica ao lado muda a cada partida. Duas formas honestas de usar isso: ancore um POI perto de um assentamento criado pelos autores, para que o jogador passe por ele; ou escolha o vazio, pois uma cova de renderização que ninguém visita há anos deve ficar em lugar nenhum em particular.

a pois record

[
  {
    "id": "chandlery:tallow_pit",
    "kind": "RUINS",
    "display_name": "The Tallow Pit",
    "description": "A rendering pit behind the tannery. The smell reaches the road.",
    "world_position": { "x": 5400.0, "y": 3000.0 },
    "discovery_radius": 2.0,
    "one_time_loot": false,
    "morale_modifier": -1,
    "awareness_modifier": 0.0
  }
]
CampoPor que esse valor
kindRUINS — o que desenha o mapa e o que o jogo pensa que é.
world_position(5400, 3000), extremo noroeste do centro: Vazio deliberado, segundo dos dois usos honestos acima. Mova-o para alguns milhares de pixels de (30720, 17280) e ele se tornará um lugar que os jogadores realmente encontrarão.
discovery_radius2.0. Quão perto a festa deve passar. Grande o suficiente para ser encontrado ao longo de uma estrada, pequeno o suficiente para não ser anunciado de uma ponta a outra de uma província.
morale_modifier−1. É um poço de gordura derretida. O número é propositalmente pequeno: um lugar é um lugar, não um evento, e -1 é um estado de espírito, não um castigo.
awareness_modifier0,0 — não ajuda a ver. Deixe um número em zero em vez de remover o campo, quando zero é uma decisão.
one_time_lootFalso: não há nada para levar, portanto nada para levar apenas uma vez.

Concluído – agora encontre-o no jogo. Vá em frente. Não há comando de teletransporte, seja em uma compilação de depuração ou fora dela, então escolha as coordenadas até onde você deseja caminhar enquanto tenta.

Se não aparecer: Você provavelmente está fora de discovery_radius ou o local é algum lugar onde a semente da partida colocou um oceano. [Nada apareceu](#nada apareceu).

Mudando o que já está lá

Você terá alterado um registro que o jogo trouxe consigo – e você o terá declarado, de modo que a alteração ficará visível para o jogador e para todos os outros mods.

Captura de tela: Ainda não tirada.

Leia primeiro: Mude o que o jogo já tem · Quando dois mods querem a mesma coisa

Cópia de: chandlery/content/economy/goods/goods.json, que adiciona um registro e corrige um do jogo no mesmo arquivo.

Para onde vão os arquivos: Nenhum lugar novo. Uma mudança em algo que o jogo já possui fica na mesma pasta de família em que seus registros estão - o arquivo diz qual registro pretende e o que está fazendo com ele.

where the files go

mods
└ chandlery
  ├ mod.json          the change is declared here
  └ content
    └ economy
      └ goods
        └ goods.json  your record and the patch, in one file

Duas regras antes do arquivo. Uma alteração no registro de outra pessoa deve ser nomeada em overrides dentro de mod.json — um registro que caia em um ID que você não declarou é rejeitado, então nada pode reescrever secretamente algo com o qual o jogador não concordou. E patch, que altera um campo e deixa o resto em paz, requer "manifest_version": 2.

mod.json

{
  "id": "chandlery",
  "name": "The Chandlery",
  "version": "0.1.0",
  "game_version": "0.0.0-dev",
  "manifest_version": 2,
  "load_order": 100,
  "content_types": ["goods", "items", "npc_definitions", "vendor_inventories", "buildings", "pois"],
  "overrides": ["candle"],
  "canon_safe": true
}

a goods record

[
  {
    "op": "patch",
    "id": "candle",
    "changes": [
      { "op": "set", "field": "base_price", "value": 4 },
      { "op": "append_unique", "field": "tags", "value": "chandlery_touched" }
    ]
  }
]
EscolhaPor que
patch, não replacereplace não herda nada: você teria que reescrever o peso da vela, seu grau de decaimento, o objeto conectado e a classe de produção, e no dia em que o jogo desse um novo campo às velas, sua cópia seria a única vela do mundo sem ela.
3 → 4Uma moeda, e o motivo é o próprio mod: a sua cidade é que derrete a cera direito, então a vela comum aqui vale um pouco mais. Passar de 3 para 30 não seria uma mudança na vela, seria uma mudança na prioridade de carga de cada caravana.
append_unique para tagsA única coisa que dois mods podem fazer sem conflito. Se ambos enfileirarem o mesmo rótulo, não será um conflito e não o duplicará.
Nomeie um campo, nunca uma posiçãotags.0 foi rejeitado. A terceira etiqueta de hoje é a segunda etiqueta depois de você carregar o pacote de outra pessoa.

Concluído – agora encontre-o no jogo. A tela Mod nomeia o registro que você adquiriu. A tela do outro autor também faz isso, se houver: quando dois pacotes escrevem o mesmo id, a linha do perdedor agora diz replaced: candle — 'chandlery' escreve por último, em vez de mostrar silenciosamente uma entrada a menos do que ele escreveu. Quem tiver o maior load_order escreve por último e vence.

Ganhar não é o mesmo que ter permissão. Dois pacotes que recebem um registro sem nomear o outro em supersedes são relatados como undeclared_collision e a composição não está correta: o validador offline diz a mesma coisa e rejeita:

typed into the debug console

ERROR: conflict on goods:candle: ['early', 'late'] each supply the whole record
and none declares the others under `supersedes`

O vencedor ainda é calculado, porque uma rejeição não precisa ser também um cara ou coroa, mas dois autores que a desejaram têm que dizê-lo. Quando dois mods querem a mesma coisa é essa conversa.

Se não aparecer: a causa usual é overrides — o id deve estar nessa lista, escrito exatamente, caso contrário o registro é rejeitado em vez de aplicado. Quando dois mods querem a mesma coisa · Nada apareceu.

Um mod em dez minutos

1. Crie uma pasta na sua pasta mods, com o nome em letras minúsculas e sublinhados: northern_reach. Tudo acontece lá dentro.

2. Escreva mod.json no topo:

mod.json

{
  "id": "northern_reach",
  "name": "The Northern Reach",
  "version": "0.1.0",
  "game_version": "0.0.0-dev",
  "dependencies": [],
  "load_order": 100,
  "content_types": ["items"],
  "overrides": [],
  "canon_safe": true
}

id deve corresponder ao nome da pasta. content_types lista as famílias que você traz — uma família que falta nessa linha nunca é lida, não importa o que esteja na pasta.

3. Crie as pastas content/inventory/items e coloque blades.json dentro:

a items record

[
  {
    "id": "northern_reach:frost_blade",
    "display_name_key": "northern_reach.item.frost_blade.name",
    "display_name": "Frost Blade",
    "category": "weapon",
    "base_value": 240,
    "weight": 3
  }
]

Os colchetes são uma lista: adicione quantas espadas quiser, separadas por vírgulas. Cada arquivo .json em uma pasta de família é lido, então divida-os como desejar.

240 não é um número escolhido para impressionar. Neste jogo, as armas de uma mão variam de 50 a 300, então uma lâmina de gelo de 240 é uma espada cara e não uma espada lendária, e um jogador pode comprá-la na mesma hora que puder comprar as boas que o ferreiro já vende. Onde estão os números do jogo é a tabela a ser observada antes de escolher qualquer número; um preço sem nada próximo é uma hipótese, e numa economia que comercializa entre cidades uma hipótese não permanece onde você a coloca.

4. Inicie o jogo e abra Mods no menu principal. Seu pacote recebe exatamente um status e Did it load? tem todos os seis.

5. Leia a linha abaixo para saber o que foi lido, aplicado e rejeitado, com o motivo de cada rejeição. Mostrar detalhes tem IDs.

6. Sua espada está no jogo. Tudo o que vem depois é mais do mesmo.

Agora encontre-o no jogo

O relatório diz applied. Significa que o disco está carregado e isso não é a mesma coisa que poder andar na frente dele. É aqui que todo guia para e todo autor começa a adivinhar.

O que você adicionouOnde apareceA captura
goodsEm um comerciante, apenas uma linha de vendor_inventories solicita isso. Uma mercadoria que ninguém possui é carregada, precificada, comercializável seja qual for o nome e não está em nenhum balcão em lugar nenhum.Adicionar mercadorias é metade do trabalho. A outra metade é a linha.
vendor_inventoriesO comerciante nomeado em npc_id. Cada linha carrega seu próprio daily_stock e seu próprio restock_days, portanto, uma linha com restock_days: 2 é reabastecida a cada dois dias e não no dia em que você a adicionou.Use day no console para pular um dia em vez de esperar por ele.
itemsEm todos os lugares, algo lhe dá um: uma linha de comerciante, uma mesa de saque, uma recompensa de missão. Existe um objeto que não concede nada e só pode ser alcançado com item <id> no console.item northern_reach:frost_blade coloca-o na sua mochila imediatamente e é a maneira mais rápida de ver se está carregado.
npc_definitionsO assentamento indicado em settlement_id, no local indicado por location_morning / location_afternoon / location_evening.Leia o parágrafo abaixo sobre settlement_id antes de escrever um.
buildingsA liquidação indicada em settlement, sorteada com o role e o color que você deu. interior_service é o que um jogador encontra ao entrar.Um edifício sem settlement é carregado e colocado em lugar nenhum.
poisNo mapa mundial em world_position, detectável por discovery_radius.Leia o parágrafo sobre coordenadas abaixo. É com isso que todos se preocupam.

settlement_id nomeia um lugar criado pelos autores. Os ids de assentamento são criados pelos autores e estáveis: Durnwall, Thorngate, Valdmere, Grentham e as doze vilas podem receber nome. A seed muda o terreno e os biomas ao redor delas, a escassez do ano e a organização política, não o id. Se quiser que alguém seja certamente encontrado, use qualquer id de assentamento criado pelos autores e mantenha o nome nos dados de idioma do seu pacote.

As coordenadas são absolutas e o mundo é gerado ao redor de lugares criados pelos autores. O mapa mede 61 440 × 34 560 pixels do mundo e Old Seat fica exatamente no centro, (30720, 17280), em toda partida. As cidades e vilas criadas pelos autores mantêm seus nomes e posições. A seed muda o terreno e os biomas ao redor delas, a escassez do ano, a organização política e quais estradas valem a pena. Assim, uma world_position de (6000, 2200) é um ponto real e estável no extremo noroeste do mapa, enquanto o que fica perto muda a cada partida: pode ser uma estrada, uma floresta ou lugar nenhum. Duas formas honestas de usar isso:

  • Ainda no centro. Um ponto de interesse a alguns milhares de pixels de distância (30720, 17280) fica próximo ao assento antigo em todos os jogos, portanto é um local que o jogador encontrará.
  • Você quer dizer vazio. Uma ruína pela qual ninguém passou por cem anos deve estar em qualquer lugar. As coordenadas absolutas são exatamente corretas para isso, e a semente decidirá quais vizinhos terá.

Os comandos de console que mais economizam tempo. day [n] e hour [n] avançam o tempo, que é como você vê um suprimento sem experimentá-lo. item <id> [count] e gold <amount> colocam as coisas em suas mãos. flag, quest_start e faction_rep movem o estado que uma condição pode estar aguardando. Não existe comando de teletransporte: para chegar a um local, viaje até lá.

mod.json, campo por campo

CampoO que fa
idNo exemplo acima. O nome do seu pacote. Deve corresponder exatamente à pasta e é a palavra antes dos dois pontos em cada ID que você escreve.
nameNo exemplo acima. O que um jogador vê. Letras maiúsculas e espaços são adequados aqui.
versionNo exemplo acima. Você escolhe. Aumente sempre que você mudar alguma coisa.
game_versionNo exemplo acima. A compilação para a qual você fez isso.
content_typesNo exemplo acima. As famílias que você traz. Uma família que falta nesta lista nunca é lida, não importa o que esteja na pasta.
dependenciesNo exemplo acima. Os pacotes que você precisa. Um nome ou um objeto com optional: true.
load_orderNo exemplo acima. Quem vai primeiro quando dois pacotes tocam a mesma coisa. O mais baixo carrega primeiro.
overridesNo exemplo acima. Os IDs básicos do jogo que você pretende alterar. Um id, ou um file.json:id quando você se refere à cópia que forma um arquivo preciso.
canon_safeNo exemplo acima. Se o seu mod se encaixa na história do jogo. É você quem diz aos jogadores, não quem decide o jogo.
rootsUma pasta de família, quando você quiser em algum lugar diferente do padrão em Famílias, uma por uma. Fique dentro do seu pacote.
manifest_versionQue tipo de manifesto você está escrevendo. As operações Alterar o que o jogo já possui requerem 2. Esta compilação lê até 2.
typeQue tipo de pacote é esse. O quarto valor é aquele que envia comportamento em vez de dados, e a única coisa nesta compilação que diz sim à execução do comportamento diz não, portanto, um pacote que o declara é rejeitado. Está na lista porque a forma está decidida, não porque a porta está aberta; O que um mod nunca pode fazer é uma leitura honesta. Um de content, overhaul, total_conversion, feature_extension.
capabilitiesO que um pacote pediria ao hóspede, se o nível superior fosse aberto. Um campo desconhecido aqui falha ao ser fechado, em vez de ser ignorado.
trust_tierNão confiável, que é o que é e permanece um mod baixado por um jogador. É um convidado quem indica o outro; nada que um pacote escreva aqui o promove. Um de untrusted, trusted.
supersedesOs pacotes que isso pretende substituir. Um campo reivindicado desta forma deixa de ser relatado como uma colisão. Também aqui um campo desconhecido falha no fechamento.
fallback_policyEm que um pacote recorre quando algo que ele substitui está faltando. Um de vanilla, none.
campaignA campanha que uma conversão possui.
campaign_packageDeclare que este pacote é uma campanha, com id, nome e versão próprios. Um pacote que o contém só é lido enquanto sua campanha está em andamento, e o jogador o escolhe na tela de Mods antes de um novo jogo. Uma conversão total.

Uma dependência pode ser um objeto em vez de um nome: {"id": "some_mod", "version": "", "optional": true}.

Um valor que nomeia outro pacote é uma referência cross-mod e a referência deve ser uma dependência declarada. Se essa dependência for opcional, atribua ao campo um fallback, caso contrário o registro será ignorado quando a dependência estiver ausente:

a goods record

[
  {
    "op": "add",
    "id": "northern_reach:alloy",
    "display_name": "Alloy",
    "linked_item_id": "absent_helper:ore",
    "fallback": { "linked_item_id": "iron_ore" }
  }
]

Para onde vai cada arquivo

where the files go

northern_reach/
  mod.json                  the label
  content/assets/images/
    images.json             your art
  content/inventory/items/
    blades.json             your first record
  content/narrative/quest_plans/
    the_long_winter.json    your quest

Nomes e IDs

Um ID consiste em letras minúsculas, dígitos e sublinhados, e nada mais. frost_blade, não Frost Blade, não frost-blade e não frost.blade. Ele nem carrega seu próprio separador, porque um separador dentro de um id é a pasta que vaza para o nome: mova o arquivo e o id não estará mais de acordo com o disco. Os :s acima são a única exceção e ambas as metades seguem a regra.

A parte antes dos dois pontos é o ID do seu pacote. É assim que dois mods podem adicionar uma Frost Blade sem colidir.

Palavras que um jogador lê

O texto escrito em um registro é texto em um único idioma. Em vez disso, aponte para uma chave:

a locale CSV

northern_reach.item.frost_blade.name
northern_reach.item.frost_blade.description

As chaves são minúsculas, unidas por pontos, com o namespace como ids. Traz palavras para a família locales — um .csv sob content/locale com uma coluna key e uma coluna de idioma. As famílias, uma por uma tem o formato exato.

Escreva também o display_name simples próximo à chave. Um registro que contém apenas uma frase deve ser reescrito à mão no dia em que você o traduz, e até então haverá quatrocentas delas.

As duas maneiras de errar falham de maneiras muito diferentes, e apenas uma delas lhe diz isso. Uma chave que não responde a nada aparece como a própria chave — northern_reach.item.frost_blade.name, na tela, deliberadamente feia para alguém consertar e contada como um buraco. Um registro que contém apenas texto e nenhuma chave nunca aparece: funciona, no seu idioma, para todos os jogadores em todos os idiomas. Nada é rejeitado e nada falta, então nada informa, e um jogador que lê em português lê silenciosamente o seu italiano. Você encontra o primeiro erro. O segundo encontra seus leitores.

Traduza um mod e seja traduzido

O jogo é lançado em sete idiomas, então um pacote com inglês incluído nos registros é lido como inglês para seis sétimos daqueles que o instalam. É isso que custa evitá-lo, que é quase nada se você fizer no primeiro dia e reescrever se fizer no quatrocentos.

As línguas que existem

Sete, e esta tabela é lida na construção em vez de escrita à mão aqui, então um idioma que chega ou sai a move no mesmo dia:

Escreva istoLínguaCabeçalho da coluna
enInglêseno idioma de origem
ititalianoit
frFrancêsfr
deAlemãode
esEspanholes
pt-BRPortuguês (Brasil)pt_BR
zh-Hans简体中文zh_Hans

Dois dos códigos têm uma segunda grafia em circulação - pt-BR é aquele que uma loja digital usa e esta página, pt_BR é aquela com a qual o mecanismo está em conformidade - e em um cabeçalho de coluna ambos são aceitos. Escreva aquele que você copiou.

Carregue palavras em mais de um idioma

Um CSV em content/locale, com key primeiro e uma coluna por idioma:

a locale CSV

key,en,it,de
northern_reach:GOOD_FROST_SALT,Frost Salt,Sale di Brina,Frostsalz
northern_reach:ITEM_FROST_BLADE_NAME,Frost Blade,Lama di Brina,Frostklinge
RegraPor que
Cada chave cabe no seu namespacenorthern_reach:GOOD_FROST_SALT, com os mesmos dois pontos que os ids usam. Uma chave de lá é rejeitada, a menos que overrides a declare - caso contrário, dois pacotes que escrevem GOOD_GRAIN seriam resolvidos pela ordem de carregamento, silenciosamente.
Uma coluna nomeando um idioma que o jogo não possui é rejeitadaNão ignorado. Uma coluna que o carregador largasse silenciosamente não traria nada e você descobriria isso por meio de um jogador.
Uma célula em branco não é uma respostaEle é ignorado em vez de armazenado, portanto, um idioma que você ainda não aprendeu passa para a próxima etapa, em vez de ficar em branco na tela.
Nunca os doisUm registro contendo um campo _key e uma string literal para a mesma coisa é rejeitado. A chave é a promessa; a string é o que a chave substituiu.

Quando uma chave não responde no idioma do jogador, o jogo desce uma escada fixa: o idioma do jogador, depois o idioma em que seu pacote afirma ter sido escrito, depois o catálogo do jogo e depois a própria chave. A última etapa é feia de propósito: uma chave não resolvida precisa parecer errada para que alguém a conserte. Uma conversão total ignora o catálogo de jogos, porque Old Seat surgir em um mundo ambientado em outro continente não é um pequeno descuido de tradução, é o jogo base que brilha.

Escreva um texto que possa ser traduzido

  • Não há sentenças construídas em pedaços. A ordem das palavras não é a mesma em todos os idiomas, portanto, um nome montado em tempo de execução a partir de uma coluna de adjetivos e uma coluna de substantivos produz Oro Cervo em italiano. Uma entrada escrita para cada idioma, completa.
  • O nome de uma pessoa nunca é traduzido ou flexionado. Aldric é Aldric em todos os idiomas. O que também significa que uma chave não deve colocar um nome em posição oblíqua — "of {name}", "{name}'s" — porque muitos idiomas recusam nomes próprios e o jogo não.
  • Não há limite de caracteres e isso não é o mesmo que não ter limite. Nenhum campo conta caracteres; o que acaba sendo espaço na tela. O alemão é cerca de um terço mais longo que o inglês e é a língua mais usada; os chineses são muito mais baixos e quase nunca o fazem. Se você tentar apenas uma tradução, tente o alemão e atribua ao rótulo o texto mais curto que ainda esteja correto.

Alguém que traduz seu pacote

Adiciona uma coluna e envia o arquivo de volta para você. O fluxo de trabalho está todo aqui, e é por isso que o formato é CSV em vez de algo mais amigável para um programador: um tradutor pode abri-lo em uma planilha, e suas ferramentas já o lêem.

Duas coisas fazem a diferença entre um pacote que é traduzido e outro que não. Mantenha as chaves estáveis — uma chave renomeada é uma tradução perdida e o tradutor descobre quando um jogador descobre. E diga para que serve uma linha: uma chave chamada NR_MSG_01 recebe um palpite, enquanto northern_reach:VENDOR_HERB_GREETING recebe uma saudação do vendedor de ervas.

Se for você quem está traduzindo o pacote de outra pessoa, as mesmas regras o vinculam: as colunas são os idiomas que o jogo carrega, as chaves são as chaves dele e não as suas, e um nome continua sendo um nome.

Mudando o que o jogo já tem

Você querOperaçãoO que você precisa
Adicione algo novoaddSeu próprio id com seu próprio namespace. Nada mais.
Reescreva um dos registros do jogoreplaceO ID do registro listado em overrides. Um registro completo: não herda nada.
Mude um campo e deixe o resto em pazpatchoverrides, mais "manifest_version": 2 em mod.json.
Aposentar um recorderemoveoverrides, e uma família que o aceita. Veja [Tirando algo](#tirando algo).

part of mod.json

"overrides": ["iron_sword"]

overrides é uma promessa. Um registro que cai em um ID que você não declarou é rejeitado, então você nunca pode mudar silenciosamente algo sobre o qual um jogador nada sabia.

a goods record

[
  {
    "op": "patch",
    "id": "iron_ore",
    "changes": [
      { "op": "set", "field": "base_price", "value": 14 }
    ]
  }
]
OperaçãoO que faRequerRecusar
addForneça um registro novo e completo em seu namespace.id com namespaceum ID que já existe, seja do jogo base ou de outro mod
replaceFornecer um registro completo para um id que já existe, tendo-o declarado.substituir declarado, registro completoum ID ausente do registro e um ID que o manifesto não lista em overrides
patchAltere os campos nomeados de um registro existente e deixe o resto como está.substituição declarada, alteraçõesum id ausente no registro, um campo que a família não permite e qualquer forma de modificação fora de patch_operations
removeRetire um registro existente e deixe uma lápide em seu lugar.substituição declarada, família removívelum ID ausente do registro e qualquer família não marcada como removível abaixo

Um patch nomeia suas alterações uma de cada vez:

  • set — Grava value em field, o que quer que estivesse lá antes. Está escrito com field e value.
  • unset — Remove field do registro, para que o leitor veja o valor padrão da família. Está escrito com field.
  • append_unique — Adiciona value à lista em field se ainda não estiver lá. Está escrito com field e value.
  • remove_value — Remove cada ocorrência de value da lista em field. Está escrito com field e value.
  • Nomeie um campo por caminho, nunca por local. tags.0 é rejeitado. O terceiro rótulo de hoje é o segundo rótulo depois de você carregar o mod de outra pessoa.
  • Um caminho tem até quatro nomes em letras minúsculas unidos por pontos. Qualquer coisa que contenha um operador é rejeitada.
  • append_unique é aquele que dois mods podem compartilhar. Se ambos enfileirarem o mesmo rótulo, não é um conflito e não o duplica.

Só às vezes

Um registro pode dizer quando vale a pena. Adicione um when próximo ao op, em um pacote com "manifest_version": 2:

a presentation_bindings record

{
  "op": "add",
  "id": "my_mod:snowy_cloak",
  "subject": "wool_cloak",
  "kind": "item",
  "slot": "icon",
  "cue": "my_mod:cloak_snowy",
  "when": { "season": { "is": "winter" } }
}

Não há operador e nada para calcular. Tudo o que uma condição pode dizer está nessas duas tabelas.

Pergunte sobreDecididoEvidênciaValores
packagesao carregarall_of, none_ofIDs de mod enviados ao lado do seu
campaignao carregaris, any_of, not_any_ofa campanha a partir da qual a partida começou
localeao carregaris, any_of, not_any_ofo idioma em que você está jogando
seasonenquanto jogais, any_of, not_any_ofspring, summer, autumn, winter
weatherenquanto jogais, any_of, not_any_ofum id do clima que o jogo rolou
day_phaseenquanto jogais, any_of, not_any_ofdawn, day, dusk, night
dayenquanto jogaat_least, at_mostquantos dias durou a partida
JulgamentoLevaVerdadeiro quando
isum nomea resposta é exatamente essa
any_ofuma listaa resposta é uma daquelas
not_any_ofuma listaa resposta é nenhuma dessas
at_leastum númeroa resposta é essa ou superior
at_mostum númeroa resposta é essa ou menor
all_ofuma listaeles estão todos lá
none_ofuma listanão há ninguém

Máximo de quatro sujeitos em um when, dois ensaios por sujeito. Duas tentativas sobre o mesmo assunto são um intervalo: { "day": { "at_least": 10, "at_most": 30 } }.

Qual família leva o quê. Cada família leva os três decididos no carregamento. Apenas presentation_bindings e effects pegam os quatro que se movem durante o jogo, porque apenas esses dois são reconstruídos quando o mundo muda. A indicação de season em outro lugar é rejeitada, e a mensagem diz quais disciplinas aquela família realmente cursa.

A razão são os resgates. Um registro que decide um item, uma pessoa ou uma missão deve ser o mesmo registro na próxima vez que for carregado, e uma condição de movimentação é exatamente o que o impede de fazer isso.

Uma skin sazonal vai para o link, não para a imagem. Traga a imagem apenas uma vez, depois dois registros presentation_bindings para ela: um com when, outro sem. images, audio e fonts rejeitam um when sem discussão.

Retido não é rejeitado. Uma condição que não é atendida mantém seu registro, e o relatório de carga diz isso pelo nome:

what the game prints back

WITHHELD my_mod:snowy_cloak from my_mod: season is winter, and it is spring

Um pacote com cinquenta recordes de temporada é mantido três quartos a qualquer momento. É o pacote que funciona.

Se alguma associação de apresentação condicional for negada, o relatório ainda mostra a família conforme declarada e imprime bound=0 junto com cada linha WITHHELD; não relata incorretamente o pacote como não tendo superfície de apresentação. Se nenhuma ligação incondicional fornecer o mesmo slot, ele também imprimirá NO_APPLICABLE kind/subject/slot com a condição sem resposta, o que significa "nada se aplica neste estado mundial", e não "o registro era inválido". Teste a condição no host ou na pista de tempo de execução com o estado mundial correspondente antes de assumir que a associação foi rejeitada.

Duas versões da mesma coisa. Traz dois registros add com o mesmo id e condições diferentes. Aquele cuja condição se mantém é quem cobra. Se ambos forem válidos, o segundo será rejeitado como duplicado – que é como as condições sobrepostas são relatadas em vez de serem resolvidas pela ordem de arquivo.

Remover algo

remove significa descontinuado, não fora de existência. O registro continua se resolvendo e fica marcado: nada de novo deixa de ser oferecido, guardado em estoque, fabricado ou gerado por ele, e tudo o que um jogador já possui e quem o nomeia continua lendo exatamente o que sempre leu.

FamíliaremoveO que acontece
goodsSimRetirado. Ainda resolve o id, fora do que o jogo oferece.
vendor_inventoriesSimCancelado. A linha é removida.
todo o restoNãoRejeitado, com razão.

a goods record

{ "op": "remove", "id": "iron_ore" }

vendor_inventories é a única família que tira o registro, e apenas porque as regras de salvamento já dizem que ninguém aponta para essa linha.

Um remove não pode transportar um when. Uma retirada que um resgate poderia nomear deve ser decidida; caso contrário, uma identificação será resolvida em uma noite e não na seguinte.

Uma remoção é permanente para uma composição. Um patch, replace ou segundo remove subsequente direcionado ao ID retirado é rejeitado, mesmo que um recall de mercadorias mantenha o registro antigo solucionável por meio de sua remoção permanente. Isso evita que o relatório salvo indique "retirado" enquanto um pacote subsequente faz com que o registro se comporte como fornecido novamente. Adicione um novo ID de namespace quando precisar de um novo registro; Não confie na remoção seguida de uma ressurreição silenciosa.

Quando dois mods querem a mesma coisa

Ambos carregam. Cada mudança é composta antes de qualquer coisa ser construída, então o jogo vê ambos.

Quais confrontosO que acontece
Campos diferentes do mesmo registroAmbos se aplicam. Nada está perdido.
O mesmo campo simplesVence o load_order depois, e confronto não declarado é um erro: undeclared_collision, e a composição não está correta.
Dois pacotes que fornecem o registro completoO mesmo. O vencedor é decidido em load_order e o plano ainda recusa até que alguém o declare.
A mesma lista, com append_unique / remove_valueSem conflitos. Ambos dizem o que a lista deveria conter, não o que deveria ser.
Um pacote retira um registro, outro o altera ou substituiA retirada permanece. A operação posterior é recusada, qualquer que seja a ordem de carregamento.
Dois pacotes que vestem o mesmo assuntoA ordem de carregamento vence posteriormente, o perdedor é nomeado no relatório.
Um pacote que envolve o conteúdo de outro pacoteRefused.

Ganhar e obter permissão são duas questões diferentes, e essa é a parte surpreendente. O jogo sempre calcula qual pacote ele escreve por último – deixar isso ao acaso faria com que até mesmo o lançamento de uma moeda fosse uma rejeição – e ainda sinaliza o par como uma colisão que ninguém declarou. O validador offline rejeita o mesmo par sem discussão, então você descobre antes do jogador.

supersedes em seu manifesto é a sua maneira de dizer que você fez isso de propósito. Nomeie o ID do outro pacote e o conflito se tornará declared_replacement: registrado, com motivo e não mais um erro.

Dê ao seu pacote um load_order próprio. Dois pacotes que compartilham um número não são rejeitados, e então o vencedor sai da ordem alfabética do id do mod: uma ordem que nenhum autor escolheu e que nenhum jogador pode ler na tela.

Imagens, som, escrita, cor

Trazer um arquivo e usá-lo são duas etapas separadas e você precisa de ambas. Um arquivo para o qual nada aponta é lido, verificado, medido e nunca exibido.

TipoArquivoInstaladoO que isso significa
image.png, .webpSimO arquivo é lido e a textura é construída.
audio.ogg, .wavNãoOs descritores são validados, o cabeçalho é lido e a duração delimitada, e nada soa: nenhuma família de conteúdo carrega áudio e a funcionalidade de áudio não solicita nenhum catálogo de um pacote de som. Traga o som quando a família existir; hoje ele seria comedido e silencioso.
font.ttf, .otfNãoOs descritores são validados e a cobertura do idioma verificada, e nenhum tema resolve um caractere de pacote. A interface constrói suas fontes a partir do tema que traz consigo, portanto, uma fonte fornecida por um pacote seria verificada e não definida como nada.

Traga o arquivo

Cada família de recursos é um descritor de arquivo mais os arquivos que ela nomeia. O descritor deve ser nomeado como sua família: images.json, audio.json, fonts.json.

where the files go

content/assets/images/
  images.json
  river_guard.png
FamíliaPastaAceitarCampos obrigatórios
imagescontent/assets/images.png, .webpid, file, format
audiocontent/assets/audio.ogg, .wav (descompactado)id, file, codec, role
fontscontent/assets/fonts.ttf, .otfid, file, format, sizes, covers, fallback_font
themescontent/assets/themesfichas de corid, tokens
effectscontent/assets/effectsmodelos hospedeirosid, template

a images record

[
  {
    "id": "northern_reach:river_guard",
    "file": "river_guard.png",
    "format": "png"
  }
]

Três regras que valem:

  • O cabeçalho é verificado antes de qualquer coisa decodificá-lo. format é o que o arquivo é, não o que a extensão afirma.
  • Um nome file que contém .. ou ~, ou que começa com /, \, res:// ou user://, é rejeitado no nome.
  • Um id que não resolve recebe um espaço reservado e um aviso, nunca silenciado.

Aposte nisso

Em um registro que você carrega, com um campo que leva o ID da sua imagem:

FamíliaCampoO que é
itemsicon_idO ícone em um item que você carrega.
npc_definitionsportrait_idO retrato de um NPC com nome.
perksiconO ícone de um privilégio.

Em qualquer coisa, incluindo conteúdo do jogo base, com um registro presentation_bindings nomeando o assunto, seu tipo e slot:

a presentation_bindings record

[
  {
    "id": "northern_reach:iron_sword_icon",
    "subject": "iron_sword",
    "kind": "item",
    "slot": "icon",
    "cue": "northern_reach:river_guard",
    "alternative_key": "northern_reach_iron_sword_icon_alt"
  }
]
SlotVocê carregaOnde aparecealternative_keyRetirou
portraitimageO quadro do diálogo, para o id do locutor.obrigatórioSim
spriteimageUma ficha de tropa, um terreno de mapa mundial ou uma construção em um assentamento.Sim
iconimageCélulas de inventário, para qualquer item — seu ou do jogo.obrigatórioSim
bannerimageAs cores da casa na página de seu diário.Sim
voiceaudioSoa quando a linha do locutor aparece.obrigatórioainda não
use_soundaudioSoa quando um item é usado e o uso entra em vigor.ainda não
ambienceaudioEle circula enquanto o jogador está naquele terreno.ainda não
themethemeQual das suas paletas usa a interface.Sim
fontfontQual dos seus personagens usa a interface.ainda não
effecteffectTempo e luz no terreno ao qual está ligado.Sim

alternative_key é obrigatório quando um slot contém informações: é a chave do idioma que diz a mesma coisa para um jogador que não pode receber a imagem.

Som

role é um limite, não um rótulo: cada um carrega sua própria duração máxima, seu próprio limite de quantos jogam juntos e o cursor que o jogador procura.

PapelParaCursor
musicMúsicasMúsica
ambienceSalas, horas, lugaresAmbiente
sfxEfeitos curtosEfeitos
voicePiadas faladasEfeitos

Um WAV compactado é rejeitado: decodificá-lo requer um analisador, e o analisador é exatamente o que você está evitando.

Escritos

covers nomeia os idiomas para os quais sua fonte carrega glifos e a compilação se recusa a instalá-la para quaisquer outros. Um caractere sem idioma não falha: desenhe quadradinhos, e a tela parece uma tradução incompleta, com o texto certo e falha na fonte.

fallback_font é obrigatório: nomeie outro ID de fonte de sua preferência ou uma família de sistema (Segoe UI, Noto Sans). sizes é o que o cache de glifo é calculado.

Apenas um caractere, nunca uma coleção — um .ttc contém vários e qual deles chega depende de um índice que o descritor não pode carregar. Fontes gratuitas com ampla cobertura: Google Fonts, Font Squirrel. Verifique se a licença permite redistribuir o arquivo - seu pacote o contém.

Cor

Tokens, nunca uma cena, roteiro ou caminho de recurso. Os nomes são os do jogo: bg_deep, bg_mid, bg_button, bg_hover, border, border_hi, text, text_dim, accent, gold. Um nome que esta compilação não conhece é mencionado no log em vez de parecer ter sido aplicado.

a themes record

[
  {
    "id": "northern_reach:dusk",
    "tokens": {
      "bg_deep": { "kind": "colour", "value": "#12131a" },
      "text": { "kind": "colour", "value": "#e8e2d0" },
      "border": { "kind": "colour", "value": "#7f6ab0" }
    },
    "contrast_pairs": [
      { "text": "#e8e2d0", "background": "#12131a" }
    ]
  }
]

contrast_pairs são verificados em uma proporção de 4,5 e abaixo disso o tema é rejeitado. O medidor WebAIM informa a proporção de um par antes de usá-lo.

Desligue o pacote e a interface recupera suas cores e escritas.

Arte que faz bem

A construção verifica se uma imagem é uma imagem. Não tem nada a dizer sobre se parece certo, e em um mundo desenhado em cinza, uma espada brilhante, alegre e de alta resolução não deixa de estar errada ao passar por todos os escrutínios. Isto é o que se sabe hoje.

O registroPixel art, cinza e pouco heróico. Opaco, desgastado, manchado pelo tempo. Uma paleta adequada para uma tarde chuvosa numa cidade que teve um ano mau.
Cavilhas16 pixels, para qualquer coisa desenhada dentro de um mapa. Seus mapas.
Formatos e limites.png ou .webp, até 8192 por lado, até 8 MB, controlado por cabeçalho antes que qualquer coisa os decodifique.
Cor da interfaceOs dez tokens de themes e uma proporção contrast_pairs de 4,5 abaixo da qual o tema é rejeitado.

O guia de estilo completo ainda não foi publicado. O que ele trará: a paleta em si, as dimensões em que cada tipo de coisa é desenhada e exemplos lado a lado do que entra no mundo e do que sai dele. Vale a pena esperar em vez de adivinhar, porque a falha que ele evita não é um arquivo rejeitado: é um pacote que se instala perfeitamente e faz o jogo parecer dois jogos.

Enquanto não existir, o método confiável é aquele que não necessita de nenhum documento: coloque sua imagem ao lado da imagem do jogo e vejam-nas juntas.

Seus mapas

Desenhe em Tiled, exporte para .tmj e indexe para content/world/maps/maps.json.

a maps record

[
  {
    "id": "northern_reach:river_bend",
    "file": "river_bend.tmj",
    "name_key": "NORTHERN_REACH_RIVER_BEND",
    "world_origin": [4096, 2560],
    "region_id": "northern_reach:lowlands"
  }
]
RegraO que isso significa
O kitBlocos de 16 pixels, ortogonais, canto inferior direito, finalizados.
Níveis são funções, não nomesground, collision e walkable são obrigatórios. Um nível denominado collisions é rejeitado em vez de ignorado.
A geometria se declaraA área de colisão e caminhada são objetos que você desenha, nunca deduzidos da aparência das peças.
Cada nome de objeto tem seu próprio namespacenorthern_reach:towpath, não towpath.
world_originOnde está o canto superior esquerdo, em pixels mundiais. Afirma-se porque um arquivo de mapa não tem ideia de onde está no mundo.
Um mapa diz onde, nunca o quêUm objeto poi na camada bindings nomeia um ponto de interesse que você trouxe como registro; o arranjo o move para onde você o desenhou.
Tudo ou nadaUma disposição rejeitada não coloca absolutamente nada.
Sem rotasUma propriedade chamada path, scene, script, resource ou template é rejeitada para o nome, seja ele qual for.

Um link que nomeia o conteúdo de outro pacote — ou do jogo base — faz com que todo o layout seja rejeitado. modding_map_report nomeia a provisão e a regra que a rejeitou.

Suas missões

Uma missão é um conjunto de registros que só fazem sentido juntos, em content/narrative/quest_plans.

TipoO que é
arcA história. Lista as missões que contém.
questA tarefa: quem dá, como se chama, quanto paga.
objectiveUma coisa que o jogador deve fazer.
endingComo o arco termina.

a quest_plans record

[
  {
    "kind": "arc",
    "id": "northern_reach:the_long_winter",
    "stages": ["northern_reach:bring_the_grain"]
  },
  {
    "kind": "quest",
    "id": "northern_reach:bring_the_grain",
    "name_key": "northern_reach.quest.bring_the_grain.name",
    "giver": "northern_reach:the_reeve",
    "in_arc": "northern_reach:the_long_winter",
    "objectives": ["northern_reach:gather_grain"],
    "rewards": [
      { "grant": "receive_coin", "coin": 250 }
    ]
  },
  {
    "kind": "objective",
    "id": "northern_reach:gather_grain",
    "quest": "northern_reach:bring_the_grain",
    "goal": "collect_item",
    "target": "northern_reach:winter_grain",
    "count": 40
  },
  {
    "kind": "ending",
    "id": "northern_reach:the_barns_are_full",
    "arc": "northern_reach:the_long_winter",
    "requires": ["northern_reach:bring_the_grain"]
  }
]
ObjetivoAssisti hoje
collect_itemsim - você está carregando alguma coisa o suficiente
defeat_unitsim - você já matou o suficiente de alguma coisa
earn_coinsim - você tem dinheiro suficiente
reach_placesim - você visitou um assentamento
survive_dayssim - dias suficientes se passaram
speak_to, deliver_item, defend_place, escort_unit, learn_lorenão — rejeitado nominalmente em vez de aceito e nunca concluído
RecompensaEntregue hoje
give_item, receive_coinSim
change_relationsim, quando o assunto é o jogador
os outros cincorecusou em voz alta
  • Um plano é tudo ou nada. Um registro errado e nenhum é instalado: a alternativa é um arco que para no meio do caminho com o jogador segurando a espada e não o título.
  • Uma recompensa é um grant, nunca um kind. kind indica qual dos quatro registros é esse. Uma recompensa escrita com kind é lida muito bem e é rejeitada.

Verifique o seu com modding_quest_plan_report.

Suas conversas

Uma conversa consiste em três tipos de registros em content/narrative/dialogue: o dialogue_graph que a nomeia e diz em qual barra ela abre, as barras dialogue_node que são as linhas e as opções dialogue_option que estão acima dela.

Sua fala é a sua fala, e nada a reescreve. O que um modelo local pode fazer é responder a uma pergunta que o jogador escreve ao personagem, permanecendo dentro do que sua fala diz — e quando não consegue ficar dentro, ele diz que não sabe. É o jogador quem decide se aquela superfície existe; com o modelo desligado, o personagem diz sua frase e para. A tradução da sua piada vem dos arquivos de idioma, como tudo o mais que você escreve.

O gráfico nomeia speaker e o gatilho está todo lá. Cada personagem do jogo pergunta a esta família quais conversas estão acima deles quando clicado, para que você possa dar ao ferreiro algo a dizer sem redefinir o ferreiro.

a dialogue record

[
  {
    "kind": "dialogue_graph",
    "id": "northern_reach:gate_toll",
    "entry": "northern_reach:gate_open",
    "speaker": "gate_warden",
    "name_key": "TALK_PACK_GATE"
  },
  {
    "kind": "dialogue_node",
    "id": "northern_reach:gate_open",
    "graph": "northern_reach:gate_toll",
    "voice": "line",
    "speaker": "gate_warden",
    "line_key": "TALK_PACK_GATE_OPEN"
  }
]

Você escreve a conversa, nunca as palavras: cada piada é uma chave de idioma, então o mesmo pacote pode ser lido em todos os idiomas que o jogador possui. Um pacote contendo prosa é rejeitado no arquivo em vez da tela.

Uma piada e uma escolha podem conter cada uma das condições, e uma escolha pode conter comandos. Uma condição decide se a coisa será mostrada ao jogador; um comando é o que acontece quando ele o executa.

VerificarLevaEle perguntaRespondido hoje
companion_presentcompanionEsse companheiro está lá para ouvir.Sim
faction_stancefaction, stanceUma facção está onde a opção espera.sim, para hostile — qualquer outro valor é rejeitado antes da primeira medida
has_coincoinO jogador pode pagar.Sim
has_itemitem, countO jogador está carregando isso com ele.Sim
has_knowledgeloreO jogador foi informado disso.Sim
has_traittraitO player foi construído assim.Sim
lacks_knowledgeloreO jogador ainda não foi informado disso.Sim
quest_statequest, stateUma missão é onde a opção espera.Sim
relation_at_leastsubject, target, regardUm lado pensa pelo menos isso do outro.Sim
seasonseasonEstamos nessa parte do ano.Sim
time_of_dayphaseEstamos nessa parte do dia.Sim
ComandoLevaAtrásFeito hoje
change_relationsubject, target, deltaAltere uma reputação dentro das regras de relacionamento publicadas pelo host.Sim
give_itemitem, countEntregue algo.Sim
grant_knowledgeloreDiz algo ao jogador.Sim
open_shopvendorColoca os suprimentos de um comerciante na tela.Sim
pay_coincoinO jogador paga.Sim
receive_coincoinO jogador é pago.Sim
recruit_companioncompanionAdicione alguém ao grupo quando as regras de recrutamento publicadas pelo host permitirem.Sim
set_quest_statequest, stateLeve uma missão a um estado que seu histórico permita.sim, para active e failed — qualquer outro valor é rejeitado antes da primeira medida
start_combatencounterFecha a conversa.Sim
take_itemitem, countIsso tira alguma coisa.Sim
travel_todestinationMova a empresa.Sim
  • Uma conversa nomeando algo que esta compilação não pode fazer nunca é aberta. Não é a escolha que a utiliza: a conversa inteira, antes da primeira linha. Uma discussão que para na terceira opção já levou as moedas do jogador.
  • Nada se move mais do que existe. Pergunte primeiro com has_coin ou has_item; um pacote que se esquece disso não pode deixar o jogador com menos quarenta moedas, porque ninguém aceitou uma dívida e nenhuma tela a explica.
  • Toda piada precisa de uma saída. Uma piada que um jogador pode entender e da qual não pode fugir é rejeitada quando o gráfico é carregado.

Verifique o seu com modding_dialogue_report.

Suas cenas

Uma cena é o único tipo de conteúdo que tira o controle do jogador, então também é o único com uma regra de finalização. As cenas vivem em content/narrative/scenes e cada uma nomeia um where, o local onde é reproduzida. Entre naquele lugar e a cena começa.

a scenes record

[
  {
    "id": "northern_reach:the_morning_after",
    "where": "northern_reach:waystation",
    "beats": [
      { "beat": "fade_in", "seconds": 1.5 },
      { "beat": "lock_player" },
      { "beat": "say", "actor": "gate_warden", "line_key": "SCENE_PACK_GREETING" },
      { "beat": "wait", "seconds": 1.0 },
      { "beat": "unlock_player" }
    ]
  }
]
PiadaLevaTemposJogado hoje
ask_nameprompt_keya cena espera por elaSim
enda cena continuaSim
fade_insecondsa cena espera por elaSim
fade_outsecondsa cena espera por elaSim
lock_playera cena continuaSim
narrateline_key, secondsa cena espera por elaSim
play_cuecuea cena continuaSim
remove_actoractora cena continuaSim
sayactor, line_keya cena espera por elaSim
show_exita cena continuaSim
start_dialoguegrapha cena espera por elaSim
unlock_playera cena continuaSim
waitsecondsa cena espera por elaSim
walk_toactor, anchora cena espera por elaSim
  • Uma cena que remove controles deve devolvê-los. Uma sequência que termina sem unlock_player é rejeitada, pois a alternativa é trazer uma sala da qual o jogador só poderá sair fechando o jogo.
  • As linhas seguem em ordem e uma linha de bloqueio é esperada. Isso é o que torna uma cena uma cena, em vez de uma lista de coisas acontecendo ao mesmo tempo.

Verifique o seu com modding_scene_report.

Suas capturas de tela

O layout de uma tela informa quais seções vão em qual painel da tela o jogo já possui e em que ordem. Ele apresenta as peças que esta construção desenha; ele não pode adicionar uma, porque uma seção que ninguém escreveu não tem nada para desenhar.

As provisões residem em content/ui/screens. As famílias, uma por uma tem campos e um registro para copiar.

Verifique o seu com modding_screen_report.

Nada apareceu

Leia primeiro o status na tela Mod. Quase todos os estados nomeiam o problema abertamente, na linha, e o mesmo acontece com o erro mais comum de todos: aquele que já esteve no topo desta lista.

A família faltando em content_types. Você escreve goods.json, esquece "goods" na lista de manifesto e a pasta nunca é aberta: nada é rejeitado, porque nada foi lido. O pacote é carregado vazio. Agora a tela informa por qual arquivo ele passou e o que adicionar:

what the game prints back

content/economy/goods/goods.json was not read — add "goods" to content_types in mod.json

O validador offline imprime a mesma frase, portanto os dois não podem discordar. Somente se a linha indicar carregado e não nomear nenhum arquivo não lido, desça nesta lista. Está na ordem de quantas vezes cada um é o culpado.

#SintomaO que o validador diz
1O caminho da pasta está erradoWARN: declared goods root missing: …/content/economy/goods. Um aviso, não um erro: O pacote passa de qualquer maneira, e é por isso que --strict antes de postar é o conselho que é. Famílias, uma por uma tem a pasta exata de cada família.
2O id não tem dois pontosERROR: add needs an id under your own namespace. frost_blade é rejeitado; northern_reach:frost_blade é aceito.
3O JSON está quebradoERROR: invalid json goods.json: Expecting ',' delimiter: line 6 column 5. Uma vírgula ausente torna o arquivo inteiro ilegível e você recebe a linha.
4O arquivo está no pacote erradoA mesma mensagem do n. 2. Um id com o namespace de outra pessoa não é seu para escrever, e a verificação não consegue distingui-lo de um erro de digitação: ele só sabe que o prefixo não é o id do seu pacote.
5Um campo obrigatório está faltandoO relatório nomeia isso — para os campos que uma família realmente exige, que são menos do que você imagina. Apareceu e está errado é o caso em que nada é relatado.

Os relatórios nunca deixam você em dúvida. Um registro rejeitado é nomeado, o que há de errado com ele e geralmente com um código — consulte Cada código de diagnóstico.

Apareceu e está errado

O caso mais difícil, porque nada é relatado. Duas coisas passam por todo o escrutínio e ainda dão a você um registro que você não escreveu.

Um campo omitido não é um erro: é um valor padrão. O esquema de cada família informa quais campos sem os quais um registro não pode ser instalado e, para quase todas as famílias, essa lista é curta. goods requer exatamente um: id. Omita base_price e será 1. Omita weight e será 1.0. Omita category e a mercadoria será uma matéria-prima. Nada te alerta, porque não há nada de errado: você pediu um bem e conseguiu.

Mesmo um valor que não esteja entre as opções é um valor padrão. O leitor coloca todas as letras maiúsculas antes de pesquisar, então manufactured e MANUFACTURED são o mesmo valor e capitalização nunca é o problema: não comece a reescrever arquivos para isso. O problema é MANUFACTURED_GOODS: não é membro, então se torna RAW_MATERIAL. SLOW para um decay_tier torna-se ETERNAL. O disco é instalado, a tela diz aplicada e sua vela tem o preço e a perecibilidade de outra coisa.

Nada no jogo diz isso, porque não há nada a dizer: o campo é declarado como uma string, e uma string com erro ortográfico ainda é uma string. O validador é o único lugar onde você pode levá-lo, e agora é preciso:

typed into the debug console

$ python tools/quality/validate_mod_data.py --root mods/northern_reach
WARN: northern_reach:goods:goods.json#1: category is "MANUFACTURED_GOODS",
  which is not one of RAW_MATERIAL, MANUFACTURED, CONSUMABLE, AMMUNITION,
  EQUIPMENT. It loads as RAW_MATERIAL.
  ERROR=0 WARN=1

Um aviso e não um erro, porque o registro realmente carrega e rejeitá-lo agora quebraria os pacotes que já funcionam. --strict transforma isso em um erro e é a razão pela qual você executa --strict antes de postar.

Um campo que você omitiu permanece silencioso e não pode ser tomado: omitir category e escrever RAW_MATERIAL são a mesma solicitação. Portanto, as tabelas de campos em As famílias, uma por uma marcam Obrigatório e fornecem a coluna de valores como a forma que o carregador verifica. Quando um registro carrega e se comporta como outra coisa, primeiro compare seus campos com aquela tabela: o que você está procurando é um campo que você não escreveu ou uma palavra que o carregador não reconheceu.

Referência

Cada família

Uma pasta e um relatório por família. A coluna de status é medida na construção, então nunca é uma promessa que o jogo não cumpra. O que é é apenas a linha de abertura, para que a tabela permaneça algo que você possa percorrer com os olhos; a descrição completa de cada família, com seus campos e um registro para copiar, é o seu verbete em As famílias, uma por uma.

FamíliaEstadoPasta em seu pacoteComando de relatórioO que é
adaptivePronto para usarcontent/player/adaptivemodding_adaptive_reportPerfis que analisam o andamento de uma partida e sugerem uma abordagem diferente.
audioValidado, nada o consome aindacontent/assets/audiomodding_audio_reportSons que um pacote carrega, nomeados por id: música, ambiente, efeitos e voz, cada um apontando para um arquivo dentro de sua própria pasta e declarando a função que o delimita.
buildingsPronto para usarcontent/world/buildingsmodding_building_reportDefinições de edifícios e serviços do assentamento: rótulo, cor, função e interior reaproveitado.
caravansPronto para usarcontent/logistics/caravansmodding_caravan_reportRotas comerciais que uma caravana percorre: de onde sai, para onde vai, o que traz, quão bem é escoltada e com que rapidez se desloca.
combat_balancePronto para usarcontent/combat/balancemodding_combat_balance_reportValores de equilíbrio de combate limitados que ajustam os parâmetros existentes do solucionador sem adicionar regras, operações ou mecânicas.
dialoguePronto para usarcontent/narrative/dialoguemodding_dialogue_reportConversas como registros: o gráfico, suas piadas e as escolhas que nele constam.
effectsPronto para usarcontent/assets/effectsmodding_effect_reportTempo, poeira, faíscas e luzes, compostas a partir dos modelos que o anfitrião disponibiliza.
enemy_archetypesPronto para usarcontent/threat/enemy_archetypesmodding_enemy_archetype_reportTipos de inimigos que o nível estratégico conhece: classificação, quais variantes eles implantam, onde acampam, qual é o tamanho da guarnição e com que frequência eles atacam.
enemy_variantsPronto para usarcontent/combat/enemy_variantsmodding_enemy_variant_reportBlocos de estatísticas para um tipo de corpo inimigo em campo: classe, classificação, os cinco atributos e os IDs da arma, improvisada e escudo que ela carrega.
fontsValidado, nada o consome aindacontent/assets/fontsmodding_font_reportTipos de letra que um pacote carrega, nomeados por id: o arquivo, o tamanho em que são desenhados e os idiomas cujos glifos eles carregam.
goodsPronto para usarcontent/economy/goodsmodding_goods_reportBens comercializáveis ​​e suas propriedades econômicas.
group_archetypesPronto para usarcontent/strategic/group_archetypesmodding_group_archetype_reportParâmetros estratégicos ajustáveis ​​para um grupo que vive no mapa mundial: raio de alerta, preferência de alvo, número de membros, limites de abastecimento e retirada.
imagesPronto para usarcontent/assets/imagesmodding_image_reportImagens que um pacote traz, nomeadas por id: ícones, retratos e folhas de sprites, cada uma apontando para um arquivo dentro de sua própria pasta.
input_bindingsPronto para usarcontent/inputmodding_input_reportAções próprias de um pacote, com a chave que desejarem.
itemsPronto para usarcontent/inventory/itemsmodding_items_reportItens de inventário, incluindo armas e armaduras.
localesPronto para usarcontent/localemodding_locale_reportAs palavras que um jogador lê, em CSV com uma coluna por idioma: as chaves do próprio pacote e as do jogo onde o pacote declara a substituição.
lorePronto para usarcontent/narrative/loremodding_lore_reportEntradas do Codex: lugares, pessoas, eventos, costumes e coisas sobre as quais um mundo conta histórias.
mapsPronto para usarcontent/world/mapsmodding_map_reportArranjos que um pacote desenha no Tiled, nomeados por id: o arquivo, onde ele está no mundo e a chave do idioma pelo qual é conhecido.
mercenary_templatesPronto para usarcontent/character/mercenariesmodding_mercenary_reportModelos mercenários contratáveis: nome, classe, origem, saúde e moral iniciais, custo de contratação e dia em que aparecem pela primeira vez.
mr_linesPronto para usarcontent/medieval_realism/structuredmodding_mr_lines_reportLinhas estruturadas de realismo medieval, roteadas por arquivo e id de linha em vez de um campo de id no JSON.
noble_housesPronto para usarcontent/politics/noble_housesmodding_noble_house_reportDados iniciais de uma casa nobre: ​​o senhor, o herdeiro, cujos assentamentos respondem à casa, e quem conta como rival ou aliado.
npc_definitionsPronto para usarcontent/narrative/npcsmodding_npc_reportDefinições de NPCs Nomeados.
perksPronto para usarcontent/character/perksmodding_perk_reportPrivilégios declarativos: gatilhos e efeitos, sem nenhum manipulador escrito em código.
poisPronto para usarcontent/world/poismodding_poi_reportPontos de interesse colocados por coordenadas no mapa mundial manuscrito.
presentation_bindingsPronto para usarcontent/presentation/bindings-Qual recurso de pacote preenche qual espaço em qual assunto: o ícone em um objeto, o sprite em uma unidade ou bloco, o banner em uma facção, tanto para o conteúdo do pacote quanto para o do jogo base.
progressPronto para usarcontent/player/progress-Registros de progressão do jogador: objetivos, perfis de dificuldade seguros e perfis de partida dentro das regras do anfitrião.
quest_metadataPronto para usarcontent/narrative/quest_metadatamodding_quest_metadata_reportRegistros de metadados da missão, indexados por quest_id em vez de id.
quest_plansPronto para usarcontent/narrative/quest_plansmodding_quest_plan_reportPlanos de Missão como Registros: Os arcos, missões, objetivos e finais que um pacote escreve e a partir dos quais o jogo constrói suas próprias missões.
questsVerificado, ainda não instaladocontent/narrative/quests-Recursos de missão manuscritos, carregados por rota em vez de interpretados como registros.
recipesPronto para usarcontent/economy/recipes-Receitas artesanais: o que se consome, o que sai, onde é feito, quanto custa e qual a probabilidade de estragar.
relationshipsPronto para usarcontent/companion/relationships-Padrões de parceiros, políticas de relacionamento limitado, condições de recrutamento e títulos declarativos.
scenesPronto para usarcontent/narrative/scenesmodding_scene_reportCenas encenadas: a sala, quem está nela e as falas que se desdobram em ordem.
screensPronto para usarcontent/ui/screensmodding_screen_reportLayouts de tela: quais seções cabem em qual painel da tela o jogo já possui e em que ordem.
settingsPronto para usarcontent/settingsmodding_settings_reportOpções que um jogador pode alterar, declaradas em vez de sorteadas.
themesPronto para usarcontent/assets/themesmodding_theme_reportPaletas de interface como tokens: cores, tamanhos e espaçamentos nomeados, com pares cujo contraste o jogador deve ser capaz de ler.
vendor_inventoriesPronto para usarcontent/world/vendor_inventoriesmodding_vendor_inventory_reportTabelas de abastecimento do comerciante.
world_generationPronto para usarcontent/world/generation-Perfis de geração feitos apenas de dados: escolhas ponderadas de bioma e localização, de propriedade do hospedeiro.
  • Pronto para usar — formulário publicado, o jogo instala seus registros, há um exemplo, e seus ids sobrevivem a um salvamento e recarregamento.
  • Validado, nada o consome ainda — o carregador lê e verifica a família, mas nenhuma superfície de pacote voltada ao jogador a consome. Pacotes de áudio e fontes estão neste nível: um relatório limpo não faz um sinal silencioso nem uma fonte sem uso aparecer no jogo.
  • Verificado, ainda não instalado — o jogo reconhece a família e verifica seu arquivo, e nada o coloca em um jogo em andamento. Um pacote direcionado a ele passa em todas as verificações e não carrega nada. Está na página de propósito: a alternativa é que alguém passe uma noite lá sem nunca descobrir que não fez nada de errado.

Decidido na íntegra, sem família para carregá-los, então nenhum cartaz pode perguntar a ela:

SeriaPara onde iriaO que é
feature_extensionainda não há pastaUm pacote que é um recurso e não um conteúdo. O que um mod nunca pode fazer é a leitura honesta disso.

Isto não é desperdício. O que um mod nunca pode fazer é essa lista.

As famílias, uma por uma

Cada família que a construção conhece, o que aceita e um registro que você pode copiar.

  • Os campos obrigatórios são aqueles sem os quais um registro não pode ser instalado.
  • A coluna de valores é a forma que o carregador verifica, não uma dica.
  • Onde uma família diz isso, um campo que a tabela não nomeia é rejeitado junto com o registro em que está. Um erro de digitação no nome de um campo é um registro que não carrega, e o relatório da família diz isso pelo nome.

Cada entrada também diz o que acontece com um save no dia em que um jogador desinstala você:

ResponderO que o resgate faz
preserve_inert_referenceO id permanece, não resolve nada e é relatado. Aquele que o jogador tinha ainda tem nome.
substitute_placeholderUm substituto estável pertencente ao mecanismo responde, então o mundo carrega de qualquer maneira e o ID original é mantido por perto.
drop_optional_presentationA referência é descartada porque nada depende dela. Somente uma família de apresentação pode declarar isso.

Não há nada escrito à mão aqui. Os campos vêm do esquema publicado de cada família. Cada exemplo é um dos pacotes que a matriz de teste da estrutura gira no carregador, colocado de volta no namespace northern_reach e verificado novamente em relação ao seu padrão ao entrar nesta página: um exemplo que o jogo rejeitaria causa falha na compilação.

O mundo e os lugares que ele contém

5 famílias: buildings, caravans, maps, pois, world_generation.

buildings

Definições de edifícios e serviços do assentamento: rótulo, cor, função e interior reaproveitado.

  • Status Pronto para usar
  • Viajou em O serviço de um edifício
  • Pasta content/world/buildings
  • Registros roteados para o campo id
  • Relatório modding_building_report
  • Se um jogador desinstalar você substitute_placeholder. Um assentamento com um buraco onde houve um saque é impossível de jogar; um edifício visivelmente desaparecido é lido e recuperado.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
roleSimcorda
color-qualquer um
description_key-corda
interior-texto, id
interior_service-texto, id
label-corda
label_key-corda
map_binding-texto, id
services-lista
settlement-texto, id
tier-inteiro de 0 a 5

Em um arquivo chamado buildings.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a buildings record, under content/world/buildings

[
  {
    "id": "northern_reach:guildhall",
    "label": "Guild Hall",
    "role": "reeve",
    "color": {
      "r": 0.4,
      "g": 0.34,
      "b": 0.26
    },
    "interior_service": "moot_hall"
  }
]

caravans

Rotas comerciais que uma caravana percorre: de onde sai, para onde vai, o que traz, quão bem é escoltada e com que rapidez se desloca.

  • Status Pronto para usar
  • Pasta content/logistics/caravans
  • Registros roteados para o campo id
  • Relatório modding_caravan_report
  • Se um jogador desinstalar você preserve_inert_reference. Uma rota cujo pacote desapareceu mantém seu nome e não transporta nada. Substituir um destino enviaria as mercadorias do jogador para um lugar que ele nunca aceitou.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
origin_settlement_idSimcorda
destination_settlement_idSimcorda
cargo_type-corda
cargo_value-inteiro, 0 ou mais
daily_progress-número de 0,01 a 1,0
display_name-corda
group_archetype_id-corda
guard_strength-none, light, medium, heavy
initial_spawn_offset_days-inteiro de 0 a 30

Em um arquivo chamado caravans.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a caravans record, under content/logistics/caravans

[
  {
    "id": "northern_reach:salt_road_run",
    "display_name": "Salt Road Run",
    "origin_settlement_id": "valdmere",
    "destination_settlement_id": "old_seat",
    "cargo_type": "salt",
    "cargo_value": 240,
    "guard_strength": "light",
    "daily_progress": 0.08,
    "initial_spawn_offset_days": 3
  }
]

maps

Arranjos que um pacote desenha no Tiled, nomeados por id: o arquivo, onde ele está no mundo e a chave do idioma pelo qual é conhecido. O índice é o registro; o arranjo próximo a ele é lido como dados e nunca como um recurso, normalizado em forma canônica, verificado em relação ao kit publicado e montado antes de qualquer coisa ser colocada. Um layout rejeitado não coloca absolutamente nada, pois metade do mapa é uma região em que o jogador entra sem saber qual metade chegou.

  • Status Pronto para usar
  • Pasta content/world/maps
  • Registros roteados para o campo id
  • Relatório modding_map_report
  • Se um jogador desinstalar você drop_optional_presentation. Nenhum resgate nomeia uma disposição. Um salvamento nomeia o ponto de interesse para o qual um layout foi movido, e esse registro mantém sua coordenada, portanto, um mapa retirado custa o layout e nunca o conteúdo. Abandonar isso é o que faz o mundo voltar ao que dizem seus registros, em vez de manter uma posição que ninguém mais fornece.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
fileSimtexto, fixed shape
name_keySimcorda
world_originSimlista de inteiros de -1000000 a 1000000
region_id-corda
sha256-texto, fixed shape

Em um arquivo chamado maps.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a maps record, under content/world/maps

[
  {
    "id": "northern_reach:river_bend",
    "file": "river_bend.tmj",
    "name_key": "MAP_RIVER_BEND",
    "world_origin": [
      4096,
      2560
    ],
    "region_id": "northern_reach:lowlands"
  }
]

pois

Pontos de interesse colocados por coordenadas no mapa mundial manuscrito.

  • Status Pronto para usar
  • Rota para Um lugar no mapa
  • Pasta content/world/pois
  • Registros roteados para o campo id
  • Relatório modding_poi_report
  • Se um jogador desinstalar você preserve_inert_reference. Um lugar descoberto permanece descoberto. Missões e histórico de viagens apontam para o id.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
display_nameSimcorda
awareness_modifier-número de -1 a 1
description-corda
discovery_radius-número de 1 a 10
kind-inteiro ou string
linked_quest_id-corda
morale_modifier-inteiro de -10 a 10
narrative_significance_key-corda
one_time_loot-booleano
world_position-qualquer um

Em um arquivo chamado pois.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a pois record, under content/world/pois

[
  {
    "id": "northern_reach:drowned_mile",
    "kind": "RUINS",
    "display_name": "The Drowned Mile",
    "description": "A stretch of road the river took back. The milestones still stand, chest deep.",
    "world_position": {
      "x": 0.0,
      "y": 0.0
    },
    "discovery_radius": 3.0,
    "one_time_loot": true,
    "morale_modifier": -1,
    "awareness_modifier": 0.05,
    "narrative_significance_key": "POI_DROWNED_MILE_LORE"
  }
]

world_generation

Perfis de geração feitos apenas de dados: escolhas ponderadas de bioma e localização, de propriedade do hospedeiro.

  • Status Pronto para usar
  • Pasta content/world/generation
  • Registros roteados para o campo id
  • Relatório nada dele; modding_preflight_report cuida disso
  • Se um jogador desinstalar você preserve_inert_reference. Um save registra o id do perfil escolhido. Se o pacote estiver faltando, manter e relatar esse ID é mais seguro do que reconstruir silenciosamente o jogo com o mapa base do jogo.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
kindSimqualquer um
idSimtexto, id
streamSimtexto, id
tablesSimobjeto
description_key-corda
name_key-corda

Em um arquivo chamado profiles.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a world_generation record, under content/world/generation

[
  {
    "kind": "generation_profile",
    "id": "northern_reach:ashen_reach",
    "stream": "northern_reach:world_stream",
    "tables": {
      "biomes": [
        {
          "id": "plains",
          "weight": 60
        },
        {
          "id": "forest",
          "weight": 30
        },
        {
          "id": "hills",
          "weight": 10
        }
      ],
      "settlements": [
        {
          "id": "northern_reach:hamlet",
          "weight": 100
        }
      ],
      "buildings": [
        {
          "id": "northern_reach:longhouse",
          "weight": 100
        }
      ],
      "pois": [
        {
          "id": "northern_reach:standing_stone",
          "weight": 100
        }
      ]
    }
  }
]

Pessoas, famílias e o que podem fazer

8 famílias: enemy_archetypes, enemy_variants, group_archetypes, mercenary_templates, noble_houses, npc_definitions, perks, relationships.

enemy_archetypes

Tipos de inimigos que o nível estratégico conhece: classificação, quais variantes eles implantam, onde acampam, qual é o tamanho da guarnição e com que frequência eles atacam.

  • Status Pronto para usar
  • Pasta content/threat/enemy_archetypes
  • Registros roteados para o campo id
  • Relatório modding_enemy_archetype_report
  • Se um jogador desinstalar você preserve_inert_reference. Um acampamento ainda aponta para o que o estabeleceu. A substituição mudaria silenciosamente o que cerca um assentamento; nomeando a ausência que lemos.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
aggression-número de 0 a 1
behavior_profile_mix-lista de cordas
camp_count-inteiro de 0 a 12
camp_glyph-corda
corruption_chance-número de 0 a 1
description-corda
display_name-corda
encounter_id-corda
garrison_max-inteiro de 1 a 60
garrison_min-inteiro de 1 a 60
preferred_camp_biomes-lista de cordas
raid_cooldown_days-inteiro de 0 a 30
sortie_size_max-inteiro de 1 a 30
sortie_size_min-inteiro de 1 a 30
target_preferences-lista de cordas
tier-inteiro de 1 a 5
variant_ids-lista de cordas
variant_weights-lista

Em um arquivo chamado enemy_archetypes.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a enemy_archetypes record, under content/threat/enemy_archetypes

[
  {
    "id": "northern_reach:salt_reavers",
    "display_name": "Salt Reavers",
    "description": "Coastal raiders who winter inland and burn what they cannot carry.",
    "tier": 2,
    "corruption_chance": 0.1,
    "preferred_camp_biomes": [
      "marsh",
      "coast"
    ],
    "camp_count": 3,
    "garrison_min": 8,
    "garrison_max": 16,
    "aggression": 0.4,
    "raid_cooldown_days": 5,
    "sortie_size_min": 4,
    "sortie_size_max": 9,
    "target_preferences": [
      "caravan",
      "settlement"
    ],
    "camp_glyph": "tent"
  }
]

enemy_variants

Blocos de estatísticas para um tipo de corpo inimigo em campo: classe, classificação, os cinco atributos e os IDs da arma, improvisada e escudo que ela carrega.

  • Status Pronto para usar
  • Pasta content/combat/enemy_variants
  • Registros roteados para o campo id
  • Relatório modding_enemy_variant_report
  • Se um jogador desinstalar você substitute_placeholder. Um corpo que já esteja em campo sem um bloco de estatísticas não pode ser combatido. Um substituto estável do motor mantém a batalha solucionável e o ID original é preservado ao lado.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
archetype_idSimcorda
agility-número de 0 a 12
ai_behavior-corda
aim-número de 0 a 12
constitution-número de 0 a 12
display_name-corda
main_weapon_id-corda
off_weapon_id-corda
shield_id-corda
special_ability_description-corda
special_ability_name-corda
strength-número de 0 a 12
tier-inteiro de 1 a 4
variant_class-soldier, archer, berserker, ranger, finisher
will-número de 0 a 12

Em um arquivo chamado enemy_variants.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a enemy_variants record, under content/combat/enemy_variants

[
  {
    "id": "northern_reach:salt_reaver_archer",
    "archetype_id": "northern_reach:salt_reavers",
    "display_name": "Salt Reaver Archer",
    "variant_class": "archer",
    "tier": 2,
    "strength": 3.0,
    "agility": 5.0,
    "constitution": 3.5,
    "aim": 6.0,
    "will": 2.5,
    "main_weapon_id": "short_bow",
    "ai_behavior": "keeps distance and gives ground rather than trade blows"
  }
]

group_archetypes

Parâmetros estratégicos ajustáveis ​​para um grupo que vive no mapa mundial: raio de alerta, preferência de alvo, número de membros, limites de abastecimento e retirada.

  • Status Pronto para usar
  • Pasta content/strategic/group_archetypes
  • Registros roteados para o campo id
  • Relatório modding_group_archetype_report
  • Se um jogador desinstalar você substitute_placeholder. A inteligência estratégica deve identificar um limite em algum lugar. Ele responde a um valor padrão do motor, que é o mesmo que esta família já utiliza.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
aggression-corda
alarm_radius_px-número de 0 a 2000
behavior_profile_mix-lista de cordas
captain_archetype_id-corda
display_name-corda
faction_id-corda
kind-none, caravan, patrol, army, lair, camp,…
max_members-inteiro de 1 a 60
member_archetype_mix-lista de cordas
min_members-inteiro de 1 a 60
night_aggression_multiplier-número de 0,25 a 4
provisions_max-inteiro de 0 a 99
retreat_hp_pct-número de 0 a 1
target_preference-corda

Em um arquivo chamado group_archetypes.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a group_archetypes record, under content/strategic/group_archetypes

[
  {
    "id": "northern_reach:pilgrim_column",
    "display_name": "Pilgrim Column",
    "kind": "nomad",
    "faction_id": "",
    "target_preference": "wandering",
    "aggression": "avoid_player",
    "alarm_radius_px": 300.0,
    "night_aggression_multiplier": 0.5,
    "min_members": 6,
    "max_members": 14,
    "behavior_profile_mix": [
      "coward",
      "balanced"
    ],
    "provisions_max": 6,
    "retreat_hp_pct": 0.6
  }
]

mercenary_templates

Modelos mercenários contratáveis: nome, classe, origem, saúde e moral iniciais, custo de contratação e dia em que aparecem pela primeira vez.

  • Status Pronto para usar
  • Pasta content/character/mercenaries
  • Registros roteados para o campo id
  • Relatório modding_mercenary_report
  • Se um jogador desinstalar você preserve_inert_reference. Mercenários já contratados vivem no resgate como uma unidade; apenas a lista da taverna perde seu modelo. O id permanece nomeado, então a origem do orgânico ainda pode ser lida.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
display_nameSimcorda
available_from_day-inteiro de 0 a 999
background-corda
class_id-corda
hire_cost-inteiro de 0 a 9999
hp_max-inteiro de 1 a 999
morale_start-inteiro de 1 a 100

Em um arquivo chamado mercenaries.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a mercenary_templates record, under content/character/mercenaries

[
  {
    "id": "northern_reach:ditchwater_sapper",
    "display_name": "Ditchwater Sapper",
    "class_id": "skirmisher",
    "background": "Dug siege trenches for whoever was paying, and stopped asking which side it was.",
    "hp_max": 24,
    "morale_start": 70,
    "hire_cost": 180,
    "available_from_day": 6
  }
]

noble_houses

Dados iniciais de uma casa nobre: ​​o senhor, o herdeiro, cujos assentamentos respondem à casa, e quem conta como rival ou aliado.

  • Status Pronto para usar
  • Pasta content/politics/noble_houses
  • Registros roteados para o campo id
  • Relatório modding_noble_house_report
  • Se um jogador desinstalar você preserve_inert_reference. A consideração de um jogador por uma casa é registrada em sua identidade. Substituir um seria reescrever sem dizer nada aos que eram leais.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
alignment-pro_crown, pragmatic, isolationist, hostile, neutral, opportunist,…
ally_house_ids-qualquer um
apex_ambition-qualquer um
apex_claim_legitimacy-qualquer um
captain_initial_opinion-inteiro de 0 a 100
captain_initial_stance-hostile, suspicious, neutral, willing, allied
castle_id-corda
corruption_risk-low, moderate, high, critical, unknown
current_lord_id-corda
designer_hooks-corda
display_name-corda
display_name_key-corda
family_npc_ids-qualquer um
heir_id-corda
house_power_base-qualquer um
is_defunct-booleano
is_minor-booleano
lord_state-healthy, ailing, corrupted, missing, dead, none
lore_summary-corda
predecessor_house_id-corda
rival_house_ids-qualquer um
secret_flags-qualquer um
settlement_ids-qualquer um
steward_npc_id-corda
strength-dominant, stable, reduced, weakened, vacant, extinct

Em um arquivo chamado noble_houses.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a noble_houses record, under content/politics/noble_houses

[
  {
    "id": "northern_reach:house_tidewatch",
    "display_name_key": "VALID_NOBLE_HOUSE_MOD_HOUSE_TIDEWATCH",
    "display_name": "House Tidewatch",
    "strength": "reduced",
    "alignment": "isolationist",
    "corruption_risk": "moderate",
    "is_minor": true,
    "lord_state": "ailing",
    "captain_initial_stance": "suspicious",
    "captain_initial_opinion": 35,
    "apex_ambition": 20,
    "apex_claim_legitimacy": 15,
    "house_power_base": 25,
    "lore_summary": "Kept the coast road open for two hundred years and was paid in salt for it."
  }
]

npc_definitions

Definições de NPCs Nomeados.

  • Status Pronto para usar
  • Entrado Um comerciante que o detém
  • Pasta content/narrative/npcs
  • Registros roteados para o campo id
  • Relatório modding_npc_report
  • Se um jogador desinstalar você preserve_inert_reference. Uma pessoa com um nome que o mundo lembra não é a mesma que nunca existiu, e os relatos apontam para o id.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
display_nameSimcorda
faction-string ou inteiro
flag_keys-lista de cordas
is_vendor-booleano
kill_reputation_delta-inteiro de -100 a 100
location_afternoon-texto, id
location_evening-texto, id
location_morning-texto, id
lore_only-booleano
need_quest_ids-lista de cordas
offers_quest_ids-lista de cordas
personal_need-corda
personality_tags-lista de cordas
portrait_id-texto, id
price_multiplier-número de 0,1 a 10
role-string ou inteiro
settlement_id-texto, id
short_bio-corda
starts_hidden-booleano
title-corda
vendor_inventory_id-texto, id
voice_tone-corda

Em um arquivo chamado npcs.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a npc_definitions record, under content/narrative/npcs

[
  {
    "id": "northern_reach:wandering_herbalist",
    "display_name": "Wandering Herbalist",
    "title": "Travelling Healer",
    "role": "NONE",
    "settlement_id": "old_seat",
    "is_vendor": true,
    "vendor_inventory_id": "northern_reach:herb_stall",
    "personality_tags": [
      "gentle",
      "secretive"
    ]
  }
]

perks

Privilégios declarativos: gatilhos e efeitos, sem nenhum manipulador escrito em código.

  • Status Pronto para usar
  • Pasta content/character/perks
  • Registros roteados para o campo id
  • Relatório modding_perk_report
  • Se um jogador desinstalar você preserve_inert_reference. Um personagem mantém o que ganhou. A remoção de um recurso reescreve silenciosamente um edifício no qual o jogador passou o jogo.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
skillSimtexto, fixed shape
name_keySimcorda
kindSimroad, junction, lateral, capstone
colSiminteiro de 0 a 4
rowSiminteiro de 1 a 7
levelSiminteiro de 1 a 300
description_key-corda
icon-texto, id
parents-lista de cordas
side-L, R

Em um arquivo chamado perks.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a perks record, under content/character/perks

[
  {
    "id": "northern_reach:stoneskin",
    "skill": "armour",
    "name_key": "PERK_STONESKIN",
    "description_key": "PERK_STONESKIN_DESC",
    "kind": "lateral",
    "side": "L",
    "col": 0,
    "row": 7,
    "level": 100,
    "parents": [],
    "icon": "northern_reach:stoneskin_icon"
  }
]

relationships

Padrões de parceiros, políticas de relacionamento limitado, condições de recrutamento e títulos declarativos.

  • Status Pronto para usar
  • Pasta content/companion/relationships
  • Registros roteados para o campo id
  • Relatório nada dele; modding_preflight_report cuida disso
  • Se um jogador desinstalar você preserve_inert_reference. A semente do relacionamento de um parceiro permanece ligada à sua identidade, portanto, remover um pacote não pode apagar silenciosamente a confiança, o rancor ou o histórico de abandono.

Campos. Esta família contém mais de um tipo de registro e cada tipo é verificado em sua própria lista. Um campo que esta tabela não nomeia é rejeitado junto com o registro.

Um registro com kind: bond:

CampoNecessárioValores
idSimtexto, id
kindSimbond
relationSimcorda
subjectSimcorda
targetSimcorda
initial_regardSiminteiro de -100 a 100
policySimcorda
description_key-corda
name_key-corda
note_key-corda

Um registro com kind: companion_template:

CampoNecessárioValores
idSimtexto, id
kindSimcompanion_template
unitSimcorda
recruitSimcorda
loyaltySimcorda
description_key-corda
leave_below-inteiro de -100 a 100
name_key-corda
starting_regard-inteiro de -100 a 100

Um registro com kind: recruit_terms:

CampoNecessárioValores
idSimtexto, id
kindSimrecruit_terms
meansSimcorda
cost-inteiro de 0 a 1.000.000
description_key-corda
name_key-corda
requires_bond-corda

Um registro com kind: relationship_policy:

CampoNecessárioValores
idSimtexto, id
kindSimrelationship_policy
relation_kindsSimlista de cordas
boundsSimobjeto
bandsSimlista de objetos
decay_per_day-inteiro de 0 a 20
description_key-corda
max_change_per_event-inteiro de 1 a 50
name_key-corda

Em um arquivo chamado relationships.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a relationships record, under content/companion/relationships

[
  {
    "id": "northern_reach:marsh_policy",
    "kind": "relationship_policy",
    "relation_kinds": [
      "comrade",
      "feud",
      "sworn"
    ],
    "bounds": {
      "floor": -100,
      "ceiling": 100
    },
    "bands": [
      {
        "name": "hostile",
        "from": -100,
        "to": -61
      },
      {
        "name": "cold",
        "from": -60,
        "to": -31
      },
      {
        "name": "wary",
        "from": -30,
        "to": -11
      },
      {
        "name": "neutral",
        "from": -10,
        "to": 10
      },
      {
        "name": "warm",
        "from": 11,
        "to": 40
      },
      {
        "name": "trusted",
        "from": 41,
        "to": 70
      },
      {
        "name": "devoted",
        "from": 71,
        "to": 100
      }
    ],
    "max_change_per_event": 12,
    "decay_per_day": 1
  },
  {
    "id": "northern_reach:hire_terms",
    "kind": "recruit_terms",
    "means": "hire",
    "cost": 240
  },
  {
    "id": "northern_reach:marsh_companion",
    "kind": "companion_template",
    "unit": "northern_reach:marsh_unit",
    "recruit": "northern_reach:hire_terms",
    "loyalty": "northern_reach:marsh_policy",
    "starting_regard": 8,
    "leave_below": -60
  }
]

Coisas, comércio e os números por trás de um confronto

5 famílias: combat_balance, goods, items, recipes, vendor_inventories.

combat_balance

Valores de equilíbrio de combate limitados que ajustam os parâmetros existentes do solucionador sem adicionar regras, operações ou mecânicas.

  • Status Pronto para usar
  • Pasta content/combat/balance
  • Registros roteados para o campo id
  • Relatório modding_combat_balance_report
  • Se um jogador desinstalar você substitute_placeholder. O saldo é um dado de definição mantido pelo anfitrião, não pelo inventário do jogador. Quando seu pacote está ausente o balanceamento canônico e estável responde, e o carregamento subsequente não traz consigo uma segunda forma de salvar os ajustes.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
valuesSimobjeto

Em um arquivo chamado balance.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a combat_balance record, under content/combat/balance

[
  {
    "id": "northern_reach:coastal_balance",
    "values": {
      "zone_penalty_head": 22,
      "crit_damage_mult": 1.75,
      "friendly_fire_redirect_chance": 0.2
    }
  }
]

goods

Bens comercializáveis ​​e suas propriedades econômicas.

  • Status Pronto para usar
  • Viajei em [Um produto para vender](#um produto para vender)
  • Pasta content/economy/goods
  • Registros roteados para o campo id
  • Relatório modding_goods_report
  • Se um jogador desinstalar você preserve_inert_reference. Uma acompanhante que nomeia uma mercadoria que ninguém fornece é honesta. Substituí-la mudaria silenciosamente o que o jogador tem.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
base_price-inteiro de 0 a 1.000.000
category-string ou inteiro
daily_consumption_class-corda
decay_tier-string ou inteiro
display_name-corda
display_name_key-corda
linked_item_id-corda
production_class-corda
tags-lista de cordas
weight-número de 0 a 10000

Em um arquivo chamado goods.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a goods record, under content/economy/goods

[
  {
    "id": "northern_reach:spiced_wine",
    "display_name": "Spiced Wine",
    "category": "consumable",
    "decay_tier": "preserved",
    "base_price": 12,
    "weight": 0.5,
    "tags": [
      "luxury",
      "drink"
    ]
  }
]

items

Itens de inventário, incluindo armas e armaduras.

  • Status Pronto para usar
  • Pathed in Um item para carregar
  • Pasta content/inventory/items
  • Registros roteados para o campo id
  • Relatório modding_items_report
  • Se um jogador desinstalar você preserve_inert_reference. O repositório continua nomeando o que estava nele, e essa é a única razão pela qual a reinstalação o devolve a eles.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
base_value-inteiro, 0 ou mais
category-string ou inteiro
condition-número de 0 a 1
description_key-corda
display_name-corda
display_name_key-corda
icon_id-texto, id
max_stack-inteiro, 1 ou mais
quality_tier-inteiro, 0 ou mais
rarity-string ou inteiro
sellable-booleano
tags-lista de cordas
weight-número, 0 ou mais

Em um arquivo chamado items.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a items record, under content/inventory/items

[
  {
    "id": "northern_reach:spiced_wine_bottle",
    "display_name": "Bottle of Spiced Wine",
    "category": "CONSUMABLE",
    "rarity": "UNCOMMON",
    "weight": 0.5,
    "max_stack": 10,
    "base_value": 14,
    "sellable": true,
    "tags": [
      "drink",
      "luxury"
    ]
  }
]

recipes

Receitas artesanais: o que se consome, o que sai, onde é feito, quanto custa e qual a probabilidade de estragar.

  • Status Pronto para usar
  • Pasta content/economy/recipes
  • Registros roteados para o campo id
  • Relatório nada dele; modding_preflight_report cuida disso
  • Se um jogador desinstalar você preserve_inert_reference. Nada em um salvamento nomeia uma receita: um salvamento nomeia o objeto que um processo produziu, e a família desse objeto é responsável por ele. O que uma receita aposentada deixa para trás é uma estação que não oferece mais algo, que é relatado em vez de corrigido, pois inventar uma receita substituta colocaria na mão do jogador um item que nenhum pacote fornece.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
inputsSimobjeto
craft_tax_rate-número de 0,0 a 1,0
description_key-corda
display_name_key-corda
enhancer_policy-none, consumed, preserved, damaged, transformed
failure_policy-none, lose_fuel, lose_catalyst, lose_all, damaged_output
gold_cost-inteiro de 0 a 9999
legality-legal, licensed, suspicious, forbidden, black_market
optional_enhancer-corda
output_count-inteiro de 1 a 99
output_good_id-corda
output_item_id-corda
quality_policy-fixed, material_inputs, crafter_skill, enhancer, materials_and_crafter
recipe_kind-normal, equipment, special, enhancement
requires_perk_id-corda
requires_service-corda
station_fee-inteiro de 0 a 9999
success_chance-número de 0,0 a 1,0
time_cost_minutes-inteiro de 1 a 60
tools_required-lista de cordas

Em um arquivo chamado recipes.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a recipes record, under content/economy/recipes

[
  {
    "id": "northern_reach:salt_cured_ration",
    "display_name_key": "VALID_RECIPE_MOD_SALT_CURED_RATION",
    "recipe_kind": "normal",
    "inputs": {
      "salt": 1,
      "dried_meat": 2
    },
    "output_item_id": "northern_reach:salt_cured_ration",
    "output_count": 3,
    "requires_service": "kitchen",
    "gold_cost": 4,
    "time_cost_minutes": 20,
    "success_chance": 0.95,
    "failure_policy": "lose_fuel",
    "quality_policy": "material_inputs",
    "legality": "legal"
  }
]

vendor_inventories

Tabelas de abastecimento do comerciante.

  • Status Pronto para usar
  • Entrado Um comerciante que o detém
  • Pasta content/world/vendor_inventories
  • Registros roteados para o campo id
  • Relatório modding_vendor_inventory_report
  • Se um jogador desinstalar você drop_optional_presentation. Os estoques são regenerados. Um comerciante com uma prateleira vazia é um estado legível e a linha não aponta para mais nada.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
display_nameSimcorda
entriesSimlista de objetos
buyback_rate-número de 0 a 1
description-corda
global_price_multiplier-número, 0 ou mais
npc_id-corda

Em um arquivo chamado vendors.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a vendor_inventories record, under content/world/vendor_inventories

[
  {
    "id": "northern_reach:herb_stall",
    "display_name": "Herbalist's Stall",
    "npc_id": "northern_reach:wandering_herbalist",
    "global_price_multiplier": 1.0,
    "buyback_rate": 0.4,
    "entries": [
      {
        "item_id": "northern_reach:spiced_wine_bottle",
        "kind": "consumable",
        "daily_stock": 3,
        "price_multiplier": 1.1,
        "restock_days": 2,
        "min_standing": 0
      }
    ]
  }
]

História, missões e as palavras que um jogador lê

9 famílias: dialogue, locales, lore, mr_lines, progress, quest_metadata, quest_plans, quests, scenes.

dialogue

Conversas como registros: o gráfico, suas piadas e as escolhas que nele constam. Três tipos compartilham a família e kind diz qual deles. Um pacote escreve a conversa, nunca as palavras — cada pressionamento de tecla é uma chave de linguagem — e cada condição e cada consequência é uma verificação ou comando que esta compilação já executa.

  • Status Pronto para usar
  • Pasta content/narrative/dialogue
  • Registros roteados para o campo id
  • Relatório modding_dialogue_report
  • Se um jogador desinstalar você preserve_inert_reference. Um save registra o que uma conversa fez – uma missão que mudou, um objeto que mudou de mãos, uma verdade aprendida – nunca a conversa em si, que termina no momento em que você escreve algo. Quando o pacote vai embora, as consequências permanecem porque eles nunca fizeram parte da conversa e a conversa simplesmente não é mais oferecida. Substituí-lo colocaria na boca de um personagem palavras que seu autor nunca escreveu.

Campos. Esta família contém mais de um tipo de registro e cada tipo é verificado em sua própria lista. Um campo que esta tabela não nomeia é rejeitado junto com o registro.

Um registro com kind: dialogue_graph:

CampoNecessárioValores
kindSimdialogue_graph
idSimcorda
entrySimcorda
description_key-texto, fixed shape
name_key-texto, fixed shape
speaker-corda

Um registro com kind: dialogue_node:

CampoNecessárioValores
kindSimdialogue_node
idSimcorda
graphSimqualquer um
voiceSimline
speakerSimcorda
line_keySimqualquer um
conditions-qualquer um
description_key-qualquer um
name_key-qualquer um
reveals-qualquer um

Um registro com kind: dialogue_node:

CampoNecessárioValores
kindSimdialogue_node
idSimcorda
graphSimqualquer um
voiceSimnarration
line_keySimqualquer um
conditions-qualquer um
description_key-qualquer um
name_key-qualquer um
reveals-qualquer um

Um registro com kind: dialogue_node:

CampoNecessárioValores
kindSimdialogue_node
idSimcorda
graphSimqualquer um
voiceSimend
conditions-qualquer um
description_key-qualquer um
line_key-qualquer um
name_key-qualquer um
reveals-qualquer um

Um registro com kind: dialogue_option:

CampoNecessárioValores
kindSimdialogue_option
idSimcorda
nodeSimcorda
label_keySimtexto, fixed shape
gotoSimcorda
commands-lista de qualquer coisa
conditions-lista de qualquer coisa
description_key-texto, fixed shape
name_key-texto, fixed shape

Em um arquivo chamado gate_toll.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a dialogue record, under content/narrative/dialogue

[
  {
    "kind": "dialogue_graph",
    "id": "northern_reach:gate_toll",
    "entry": "northern_reach:gate_open",
    "speaker": "gate_warden",
    "name_key": "TALK_PACK_GATE_TOLL_NAME",
    "description_key": "TALK_PACK_GATE_TOLL_DESC"
  },
  {
    "kind": "dialogue_node",
    "id": "northern_reach:gate_open",
    "graph": "northern_reach:gate_toll",
    "voice": "line",
    "speaker": "gate_warden",
    "line_key": "TALK_PACK_GATE_OPEN"
  },
  {
    "kind": "dialogue_option",
    "id": "northern_reach:opt_pay_the_toll",
    "node": "northern_reach:gate_open",
    "label_key": "TALK_PACK_OPT_PAY",
    "goto": "northern_reach:gate_paid",
    "commands": [
      {
        "step": "pay_coin",
        "coin": 25
      },
      {
        "step": "change_relation",
        "subject": "player",
        "target": "gate_warden",
        "delta": 4
      }
    ]
  }
]

O aparelho contém 12 registros; 3 são mostrados.

locales

As palavras que um jogador lê, em CSV com uma coluna por idioma: as chaves do próprio pacote e as do jogo onde o pacote declara a substituição.

  • Status Pronto para usar
  • Pasta content/locale
  • Relatório modding_locale_report
  • Se um jogador desinstalar você preserve_inert_reference. Um save dá nome ao disco, nunca as palavras que o dizem, então um pacote retirado entre duas sessões custa uma tradução e nada. A chave é preservada e aparece, o que parece uma tradução ausente, em vez de conteúdo ausente.

Colunas. Uma coluna que esta tabela não nomeia é rejeitada com o registro.

ColunaNecessárioValores
keySimtexto, id
en-corda

Em um arquivo chamado words.csv. O nome do arquivo é metade do endereço e o ID da linha é a outra metade, então dois arquivos podem conter o mesmo ID de linha sem colidir:

a locales file

key,en,it
word_pack:GOOD_FROST_SALT,Frost Salt,Sale di Brina

lore

Entradas do Codex: lugares, pessoas, eventos, costumes e coisas sobre as quais um mundo conta histórias. Uma entrada carregada não é uma entrada conhecida.

  • Status Pronto para usar
  • Pasta content/narrative/lore
  • Registros roteados para o campo id
  • Relatório modding_lore_report
  • Se um jogador desinstalar você preserve_inert_reference. Uma entrada do Codex que um jogador leu é algo que ele viu. Retirá-lo apaga parte do que ele sabe sobre o mundo em que passou algum tempo, e missões e outras entradas apontam para o id.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
categorySimplace, person, event, custom, thing
title_keySimcorda
body_keySimcorda
chronology_index-inteiro
citation_key-corda
content_warnings-lista de cordas
era-corda
relates_to-lista de cordas
requires-lista de cordas
reveals-lista de cordas

Em um arquivo chamado lore.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a lore record, under content/narrative/lore

[
  {
    "id": "northern_reach:the_drowned_causeway",
    "category": "place",
    "title_key": "STORY_PACK_DROWNED_CAUSEWAY_TITLE",
    "body_key": "STORY_PACK_DROWNED_CAUSEWAY_BODY",
    "era": "before_the_mark",
    "citation_key": "STORY_PACK_CAUSEWAY_CITATION"
  },
  {
    "id": "northern_reach:the_tide_watch",
    "category": "custom",
    "title_key": "STORY_PACK_TIDE_WATCH_TITLE",
    "body_key": "STORY_PACK_TIDE_WATCH_BODY",
    "relates_to": [
      "northern_reach:the_drowned_causeway"
    ]
  }
]

mr_lines

Linhas estruturadas de realismo medieval, roteadas por arquivo e id de linha em vez de um campo de id no JSON.

  • Status Pronto para usar
  • Pasta content/medieval_realism/structured
  • Relatório modding_mr_lines_report
  • Se um jogador desinstalar você drop_optional_presentation. Uma piada de cores à qual nada se refere. Removê-lo não custa nada e mantê-lo mostraria uma string vazia.

Colunas. Uma coluna sem nome nesta tabela é permitida e deve ser um valor simples em vez de uma lista ou objeto.

ColunaNecessárioValores
line_idSimtexto, id
mechanical_hint-corda
public_label-corda
public_line-corda
public_summary_line-corda
speaker-corda
tone-corda
voice-corda

Cada registro precisa de pelo menos um dentre public_line, public_label, public_summary_line.

Estes nomes são rejeitados sem questionamento, sejam eles quais forem: unsafe_example, unsafe_reason, audit_note, expected_block_reason, script, scene, resource_path. Algumas são as colunas de verificação com as quais aqueles que jogam escrevem e outras são os nomes em forma de código que [O que um mod nunca pode fazer](#o que um mod-pode-nunca-fazer) rejeita em todos os lugares. Um registro com um é rejeitado em vez de ser apagado silenciosamente.

Em um arquivo chamado MR_L03_TAVERN_INN_LINES.csv. O nome do arquivo é metade do endereço e o ID da linha é a outra metade, então dois arquivos podem conter o mesmo ID de linha sem colidir:

a mr_lines file

line_id,tavern_state,speaker_role,tone,public_line,mechanical_hint
northern_reach:tavern_extra_01,evening_rush,innkeeper,welcoming,"Warm bread and a clean cup if you've the coin for it, friend.",food_only

progress

Registros de progressão do jogador: objetivos, perfis de dificuldade seguros e perfis de partida dentro das regras do anfitrião.

  • Status Pronto para usar
  • Pasta content/player/progress
  • Registros roteados para o campo id
  • Relatório nada dele; modding_preflight_report cuida disso
  • Se um jogador desinstalar você preserve_inert_reference. As conquistas conquistadas e os perfis de jogo escolhidos permanecem nomeados quando o pacote está ausente; tirá-los silenciosamente reescreveria a história do jogador ou o contrato do jogo.

Campos. Esta família contém mais de um tipo de registro e cada tipo é verificado em sua própria lista. Um campo que esta tabela não nomeia é rejeitado junto com o registro.

Um registro com kind: achievement:

CampoNecessárioValores
idSimtexto, id
kindSimachievement
name_keySimcorda
description_keySimcorda
conditionSimlista de objetos
campaign-corda
hidden-booleano
icon-banner, blade, coin, crown, hand, road,…

Um registro com kind: difficulty_profile:

CampoNecessárioValores
idSimtexto, id
kindSimdifficulty_profile
name_keySimcorda
modifiersSimobjeto
campaign-corda
description_key-corda
permadeath-booleano

Um registro com kind: run_profile:

CampoNecessárioValores
idSimtexto, id
kindSimrun_profile
name_keySimcorda
difficultySimcorda
campaign-corda
description_key-corda
seed_stream-corda
starting_origin-corda

Em um arquivo chamado progress.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a progress record, under content/player/progress

[
  {
    "id": "northern_reach:hard_tide",
    "kind": "difficulty_profile",
    "name_key": "DIFF_HARD_TIDE",
    "description_key": "DIFF_HARD_TIDE_DESC",
    "modifiers": {
      "enemy_strength_percent": 140,
      "coin_gain_percent": 80
    },
    "permadeath": true
  },
  {
    "id": "northern_reach:tide_run",
    "kind": "run_profile",
    "name_key": "RUN_TIDE",
    "description_key": "RUN_TIDE_DESC",
    "difficulty": "northern_reach:hard_tide",
    "seed_stream": "tide"
  },
  {
    "id": "northern_reach:held_tide",
    "kind": "achievement",
    "name_key": "ACH_HELD_TIDE",
    "description_key": "ACH_HELD_TIDE_DESC",
    "condition": [
      {
        "when": "days_survived",
        "count": 30
      }
    ],
    "icon": "tower"
  }
]

quest_metadata

Registros de metadados da missão, indexados por quest_id em vez de id.

  • Status Pronto para usar
  • Pasta content/narrative/quest_metadata
  • Registros roteados para o campo quest_id
  • Relatório modding_quest_metadata_report
  • Se um jogador desinstalar você preserve_inert_reference. Ele descreve missões que já poderiam ser reduzidas a uma lápide; retirá-lo os deixaria sem descrição, em vez de ausentes.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
quest_idSimtexto, id
arc_id-texto, id
choice_valence-corda
consequence_hooks-lista de cordas
difficulty_band-corda
faction_context-corda
failure_consequence-corda
moral_pressure-corda
notification_policy-corda
novelty_tags-lista de cordas
player_model_tags-lista de cordas
quest_role-corda
replay_suppression_key-corda
reward_intent-corda
story_turn_role-corda
urgency_band-corda
world_reason-corda

Em um arquivo chamado quests.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a quest_metadata record, under content/narrative/quest_metadata

[
  {
    "quest_id": "northern_reach:tavern_errand",
    "world_reason": "settlement_shortage",
    "quest_role": "recovery",
    "difficulty_band": "standard",
    "urgency_band": "soon"
  }
]

quest_plans

Planos de Missão como Registros: Os arcos, missões, objetivos e finais que um pacote escreve e a partir dos quais o jogo constrói suas próprias missões. A forma de registro de uma missão, ao lado de recursos manuscritos, em vez de em seu lugar.

  • Status Pronto para usar
  • Pasta content/narrative/quest_plans
  • Registros roteados para o campo id
  • Relatório modding_quest_plan_report
  • Se um jogador desinstalar você preserve_inert_reference. Um plano constrói as mesmas missões que o jogo executa, então um aposentado deixa o mesmo buraco que a caligrafia deixaria. O progresso é a única coisa que um jogador não pode reconstruir: uma missão não resolvida é relatada e nunca concluída ou cancelada silenciosamente.

Campos. Esta família contém mais de um tipo de registro e cada tipo é verificado em sua própria lista. Um campo que esta tabela não nomeia é rejeitado junto com o registro.

Um registro com kind: arc:

CampoNecessárioValores
kindSimqualquer um
idSimtexto, id
stagesSimlista
description_key-texto, fixed shape
name_key-texto, fixed shape

Um registro com kind: ending:

CampoNecessárioValores
kindSimqualquer um
idSimtexto, id
arcSimcorda
requiresSimlista
description_key-texto, fixed shape
epilogue_key-texto, fixed shape
name_key-texto, fixed shape

Um registro com kind: objective:

CampoNecessárioValores
kindSimqualquer um
idSimtexto, id
questSimcorda
goalSimcollect_item, defeat_unit, defend_place, deliver_item, earn_coin, escort_unit,…
count-inteiro de 1 a 999
description_key-texto, fixed shape
name_key-texto, fixed shape
optional_step-booleano
target-corda

Um registro com kind: quest:

CampoNecessárioValores
kindSimqualquer um
idSimtexto, id
name_keySimtexto, fixed shape
giverSimcorda
objectivesSimlista
deadline_days-inteiro de 1 a 3650
description_key-texto, fixed shape
forfeits-lista de qualquer coisa
in_arc-corda
rewards-lista de qualquer coisa

Em um arquivo chamado the_long_winter.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a quest_plans record, under content/narrative/quest_plans

[
  {
    "kind": "arc",
    "id": "northern_reach:the_long_winter",
    "name_key": "northern_reach.arc.the_long_winter.name",
    "stages": [
      "northern_reach:bring_the_grain"
    ]
  },
  {
    "kind": "quest",
    "id": "northern_reach:bring_the_grain",
    "name_key": "northern_reach.quest.bring_the_grain.name",
    "description_key": "northern_reach.quest.bring_the_grain.description",
    "giver": "northern_reach:the_reeve",
    "in_arc": "northern_reach:the_long_winter",
    "objectives": [
      "northern_reach:gather_grain",
      "northern_reach:pay_the_toll"
    ],
    "deadline_days": 30,
    "rewards": [
      {
        "grant": "receive_coin",
        "coin": 250
      },
      {
        "grant": "give_item",
        "item": "northern_reach:reeves_seal",
        "count": 1
      }
    ]
  },
  {
    "kind": "objective",
    "id": "northern_reach:gather_grain",
    "quest": "northern_reach:bring_the_grain",
    "goal": "collect_item",
    "target": "northern_reach:winter_grain",
    "count": 40,
    "name_key": "northern_reach.objective.gather_grain.name"
  }
]

O fixture contém 5 registros; 3 são mostrados.

quests

Recursos de missão manuscritos, carregados por rota em vez de interpretados como registros. Um pacote que deseja sua própria missão escreve quest_plans.

  • Status Verificado, ainda não instalado
  • Pasta content/narrative/quests
  • Relatório nada dele; modding_preflight_report cuida disso
  • Se um jogador desinstalar você preserve_inert_reference. O progresso é a única coisa que um jogador não pode reconstruir. Uma missão não resolvida é relatada e nunca concluída ou cancelada silenciosamente.

Esta família é carregada por caminho em vez de lida como um registro, e um pacote não pode carregar o arquivo que deseja; veja O que um mod nunca pode fazer. Em vez disso, escreva quest_plans.

scenes

Cenas encenadas: a sala, quem está nela e as falas que se desdobram em ordem. É o único conteúdo que tira o controle do player, e é por isso que uma sequência que nunca chega a end é rejeitada em vez de reproduzida. Piadas e adereços são nomes retirados de listas publicadas; nenhuma cena Godot, nenhum ativo e nenhum script são carregados aqui.

  • Status Pronto para usar
  • Pasta content/narrative/scenes
  • Registros roteados para o campo id
  • Relatório modding_scene_report
  • Se um jogador desinstalar você preserve_inert_reference. Um save registra o que uma cena fez – um nome escolhido, uma missão movida, uma porta aberta – nunca o fato de que ela foi assistida. É jogado e termina numa única sessão, portanto um pacote que sai custa a cena e nunca a consequência de o ter visto. Substituí-lo representaria algo que o autor nunca escreveu sob o nome de algo que escreveu.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
beatsSimlista de qualquer coisa
cast-lista de qualquer coisa
name_key-qualquer um
stage-objeto
where-corda

Em um arquivo chamado scenes.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a scenes record, under content/narrative/scenes

[
  {
    "id": "northern_reach:tollhouse_wake",
    "name_key": "STAGE_PACK_TOLLHOUSE_WAKE",
    "stage": {
      "room": [
        880,
        600
      ],
      "light": "candle",
      "props": [
        {
          "prop": "bed",
          "at": "bedside"
        },
        {
          "prop": "storage",
          "at": "east",
          "label_key": "STAGE_PACK_BELONGINGS"
        },
        {
          "prop": "light_marker",
          "at": "north",
          "light": "candle"
        },
        {
          "prop": "walkway",
          "at": "bedside",
          "to": "door"
        }
      ]
    },
    "cast": [
      {
        "actor": "northern_reach:tollkeeper",
        "name_key": "STAGE_PACK_TOLLKEEPER",
        "sprite": "default",
        "at": "bedside"
      }
    ],
    "beats": [
      {
        "beat": "lock_player"
      },
      {
        "beat": "fade_in",
        "seconds": 2.0
      },
      {
        "beat": "say",
        "actor": "northern_reach:tollkeeper",
        "line_key": "STAGE_PACK_WAKE_1"
      },
      {
        "beat": "wait",
        "seconds": 0.8
      },
      {
        "beat": "say",
        "actor": "northern_reach:tollkeeper",
        "line_key": "STAGE_PACK_WAKE_2"
      },
      {
        "beat": "play_cue",
        "cue": "northern_reach:door_latch"
      },
      {
        "beat": "walk_to",
        "actor": "northern_reach:tollkeeper",
        "anchor": "door"
      },
      {
        "beat": "remove_actor",
        "actor": "northern_reach:tollkeeper"
      },
      {
        "beat": "show_exit"
      },
      {
        "beat": "unlock_player"
      },
      {
        "beat": "end"
      }
    ]
  }
]

Como você vê e ouve tudo

7 famílias: audio, effects, fonts, images, presentation_bindings, screens, themes.

audio

Sons que um pacote carrega, nomeados por id: música, ambiente, efeitos e voz, cada um apontando para um arquivo dentro de sua própria pasta e declarando a função que o delimita.

  • Status Validado, nada o consome ainda
  • Pasta content/assets/audio
  • Registros roteados para o campo id
  • Relatório modding_audio_report
  • Se um jogador desinstalar você preserve_inert_reference. Um save nomeia o assunto e nunca o som acima dele, então um pacote retirado entre duas sessões custa uma atmosfera e não uma coisa. A referência é preservada e relatada: silêncio sem nada a dizer porque é precisamente o estado que esta família existe para evitar.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
fileSimtexto, fixed shape
codecSimogg, wav
roleSimmusic, ambience, sfx, voice
duration_seconds-número, 0 ou mais
sha256-texto, fixed shape
subtitle_key-corda

No arquivo audio.json, que é o único arquivo através do qual esta pasta é lida:

a audio record, under content/assets/audio

[
  {
    "id": "northern_reach:hearth_hum",
    "file": "hearth_hum.wav",
    "codec": "wav",
    "role": "ambience",
    "duration_seconds": 0.25,
    "sha256": "23fc92432963f74bd638f38ea9d7ddb475853f022810bdc8b344269bf43d5830"
  }
]

effects

Tempo, poeira, faíscas e luzes, compostas a partir dos modelos que o anfitrião disponibiliza. Um pacote nomeia um modelo e define parâmetros dentro de intervalos declarados; não há campo, em lugar nenhum, que carregue um shader, uma cena ou um script - e é isso que permite que um pacote de um estranho peça fogo sem poder pedir um programa.

  • Status Pronto para usar
  • Pasta content/assets/effects
  • Registros roteados para o campo id
  • Relatório modding_effect_report
  • Se um jogador desinstalar você preserve_inert_reference. Nada em um salvamento nomeia um efeito. O ar retorna ao que o jogo base desenha quando o pacote sai, o que custa um aspecto e nada que o jogador possua.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
templateSimdust_drift, lightning_flash, rain_sheet, smoke_column, snow_drift, spark_burst,…
parameters-objeto
priority-inteiro de 0 a 100

Em um arquivo chamado effects.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a effects record, under content/assets/effects

[
  {
    "id": "northern_reach:moor_drift",
    "template": "dust_drift",
    "parameters": {
      "amount": 64,
      "lifetime": 6,
      "scale": 2,
      "wind": 4,
      "colour": "#c8bfa8"
    },
    "priority": 40
  }
]

fonts

Tipos de letra que um pacote carrega, nomeados por id: o arquivo, o tamanho em que são desenhados e os idiomas cujos glifos eles carregam. A capa afirma estar exposta, porque um caractere sem os glifos de um idioma não falha: ele desenha pequenos quadrados e a tela parece uma tradução que alguém deixou pela metade.

  • Status Validado, nada o consome ainda
  • Pasta content/assets/fonts
  • Registros roteados para o campo id
  • Relatório modding_font_report
  • Se um jogador desinstalar você preserve_inert_reference. Nada em um save nomeia um personagem. A interface reverte para a fonte do kit de ferramentas quando o pacote sai, que é a única que qualquer autor teve que escolher.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
fileSimtexto, fixed shape
formatSimttf, otf
sizesSimlista de inteiros de 8 a 96
coversSimlista
fallback_fontSimcorda
glyphs-lista
oversampling-inteiro de 1 a 4
sha256-texto, fixed shape

No arquivo fonts.json, que é o único arquivo através do qual esta pasta é lida:

a fonts record, under content/assets/fonts

[
  {
    "id": "northern_reach:plain",
    "file": "plain.ttf",
    "format": "ttf",
    "sizes": [
      12,
      16,
      24
    ],
    "oversampling": 1,
    "covers": [
      "en"
    ],
    "fallback_font": "Segoe UI",
    "sha256": "613b1d24f9f8b0365a94f01214155af8e87ca72aa6633befd5e0ee05b3dc4122"
  }
]

images

Imagens que um pacote traz, nomeadas por id: ícones, retratos e folhas de sprites, cada uma apontando para um arquivo dentro de sua própria pasta.

  • Status Pronto para usar
  • Pasta content/assets/images
  • Registros roteados para o campo id
  • Relatório modding_image_report
  • Se um jogador desinstalar você preserve_inert_reference. Um save nomeia objetos e pessoas, nunca a imagem de um deles, então uma imagem que deixa de resolver custa um desenho e não uma coisa. A referência é preservada e relatada: substituí-la por arte de outro pacote mostraria ao jogador algo que nenhum autor escolheu, e remover o id silenciosamente faria com que o ícone ausente parecesse uma falha de design.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
fileSimtexto, fixed shape
formatSimpng, webp
frame_columns-inteiro de 1 a 256
frame_rows-inteiro de 1 a 256
sha256-texto, fixed shape

No arquivo images.json, que é o único arquivo através do qual esta pasta é lida:

a images record, under content/assets/images

[
  {
    "id": "northern_reach:salt_pouch",
    "file": "salt_pouch.png",
    "format": "png"
  }
]

presentation_bindings

Qual recurso de pacote preenche qual espaço em qual assunto: o ícone em um objeto, o sprite em uma unidade ou bloco, o banner em uma facção, tanto para o conteúdo do pacote quanto para o do jogo base.

  • Status Pronto para usar
  • Pasta content/presentation/bindings
  • Registros roteados para o campo id
  • Relatório nada dele; modding_preflight_report cuida disso
  • Se um jogador desinstalar você preserve_inert_reference. Um save nomeia o sujeito — o objeto, a pessoa, a peça — e nunca a imagem que o reveste, então um link que deixa de resolver custa um desenho e não uma coisa. A referência é preservada e relatada: o sujeito retorna à arte que a construção já possuía, que é a única resposta que nenhum autor teve que escolher.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
subjectSimtexto, id
kindSimbuilding, faction, interface, item, region, tile,…
slotSimambience, banner, effect, font, icon, portrait,…
cueSimtexto, id
alternative_key-corda

Em um arquivo chamado bindings.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a presentation_bindings record, under content/presentation/bindings

[
  {
    "op": "add",
    "id": "northern_reach:cloak_icon",
    "subject": "wool_cloak",
    "kind": "item",
    "slot": "icon",
    "cue": "northern_reach:cloak_plain",
    "alternative_key": "item_wool_cloak_icon_alt"
  },
  {
    "op": "add",
    "id": "northern_reach:cloak_icon_winter",
    "subject": "wool_cloak",
    "kind": "item",
    "slot": "icon",
    "cue": "northern_reach:cloak_snowy",
    "alternative_key": "item_wool_cloak_icon_alt",
    "when": {
      "season": {
        "is": "winter"
      }
    }
  }
]

screens

Layouts de tela: quais seções cabem em qual painel da tela o jogo já possui e em que ordem. Possui peças que esta construção desenha e não pode adicionar nenhuma: uma nova tela precisaria de widgets, fontes de dados e manipuladores de cliques, que juntos são uma linguagem de programação.

  • Status Pronto para usar
  • Pasta content/ui/screens
  • Registros roteados para o campo id
  • Relatório modding_screen_report
  • Se um jogador desinstalar você preserve_inert_reference. Nada em um resgate nomeia uma disposição. Ele decide como uma página é desenhada enquanto o pacote é carregado, e a página reverte para o layout que esta compilação leva consigo quando sai: custa uma skin e nada que o jogador possua.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
screenSimcharacter_sheet
panelsSimobjeto

Em um arquivo chamado screens.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a screens record, under content/ui/screens

[
  {
    "id": "northern_reach:character_sheet",
    "screen": "character_sheet",
    "panels": {
      "header": [
        "header"
      ],
      "left": [
        "vitals",
        "combat"
      ],
      "middle": [
        "attributes",
        "skills"
      ],
      "right": [
        "service",
        "weight",
        "background"
      ]
    }
  }
]

themes

Paletas de interface como tokens: cores, tamanhos e espaçamentos nomeados, com pares cujo contraste o jogador deve ser capaz de ler. Nunca uma cena, roteiro ou caminho de recurso.

  • Status Pronto para usar
  • Pasta content/assets/themes
  • Registros roteados para o campo id
  • Relatório modding_theme_report
  • Se um jogador desinstalar você preserve_inert_reference. Nada em um save nomeia um tema. A interface volta às cores do kit de ferramentas quando o pacote sai, que é a única paleta que qualquer autor teve que escolher.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
idSimtexto, id
tokensSimobjeto
contrast_pairs-lista de objetos

Em um arquivo chamado themes.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a themes record, under content/assets/themes

[
  {
    "id": "northern_reach:dusk",
    "tokens": {
      "bg_deep": {
        "kind": "colour",
        "value": "#12131a"
      },
      "bg_panel": {
        "kind": "colour",
        "value": "#1b1c26"
      },
      "bg_panel_hi": {
        "kind": "colour",
        "value": "#262838"
      },
      "text": {
        "kind": "colour",
        "value": "#e8e2d0"
      },
      "text_bright": {
        "kind": "colour",
        "value": "#f4efe2"
      },
      "text_mute": {
        "kind": "colour",
        "value": "#6f6a80"
      },
      "border": {
        "kind": "colour",
        "value": "#7f6ab0"
      },
      "border_dark": {
        "kind": "colour",
        "value": "#14151c"
      },
      "border_soft": {
        "kind": "colour",
        "value": "#4a4560"
      },
      "danger": {
        "kind": "colour",
        "value": "#d4564b"
      },
      "success": {
        "kind": "colour",
        "value": "#7fc46a"
      },
      "warning": {
        "kind": "colour",
        "value": "#e0b13c"
      },
      "accent_player": {
        "kind": "colour",
        "value": "#6f97e8"
      },
      "accent_enemy": {
        "kind": "colour",
        "value": "#c94a4a"
      }
    },
    "contrast_pairs": [
      {
        "text": "#e8e2d0",
        "background": "#12131a"
      },
      {
        "text": "#f4efe2",
        "background": "#1b1c26"
      },
      {
        "text": "#e8e2d0",
        "background": "#262838"
      }
    ]
  }
]

O que o jogador controla e o que ele observa

3 famílias: adaptive, input_bindings, settings.

adaptive

Perfis que analisam o andamento de uma partida e sugerem uma abordagem diferente. O resultado é um conselho e nunca uma mudança: um perfil que pudesse atuar seria a única coisa que um pacote traz capaz de alterar um jogo sem que o jogador ou convidado o tenha solicitado, e num diff pareceria exatamente como uma tabela de ajustes. As entradas são uma lista publicada de agregados de jogos, cada um deles uma contagem ou média que o jogo já possui sobre si mesmo.

  • Status Pronto para usar
  • Pasta content/player/adaptive
  • Registros roteados para o campo id
  • Relatório modding_adaptive_report
  • Se um jogador desinstalar você drop_optional_presentation. Não há salvamento de nomes de perfil. O que um perfil tocou é um multiplicador recalculado pelos mutadores ativos toda vez que eles mudam, assim um pacote retirado deixa de ser consultado e o jogo volta exatamente para o que o jogador havia escolhido. Nada é preservado, portanto não há nada para preservar.

Campos. Esta família contém mais de um tipo de registro e cada tipo é verificado em sua própria lista. Um campo que esta tabela não nomeia é rejeitado junto com o registro.

Um registro com kind: adaptive_profile:

CampoNecessárioValores
kindSimqualquer um
idSimtexto, id
name_keySimtexto, fixed shape
policySimenemy_composition, event_cadence, hint_frequency, pace_economy, pace_encounters, weather_variety
readsSimlista
fallback_policySimenemy_composition, event_cadence, hint_frequency, pace_economy, pace_encounters, weather_variety
confidence_floor_percent-inteiro de 1 a 100
description_key-texto, fixed shape
sample_days-inteiro de 1 a 365

Um registro com kind: threshold_set:

CampoNecessárioValores
kindSimqualquer um
idSimtexto, id
profileSimtexto, id
thresholdsSimlista de objetos
description_key-texto, fixed shape
name_key-texto, fixed shape

Em um arquivo chamado adaptive.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a adaptive record, under content/player/adaptive

[
  {
    "kind": "adaptive_profile",
    "id": "northern_reach:hard_roads",
    "name_key": "ADAPTIVE_HARD_ROADS",
    "description_key": "ADAPTIVE_HARD_ROADS_BODY",
    "policy": "pace_encounters",
    "reads": [
      "battles_won_ratio",
      "days_survived",
      "party_size"
    ],
    "fallback_policy": "event_cadence",
    "confidence_floor_percent": 60,
    "sample_days": 14
  },
  {
    "kind": "threshold_set",
    "id": "northern_reach:hard_roads_lines",
    "profile": "northern_reach:hard_roads",
    "name_key": "ADAPTIVE_HARD_ROADS_LINES",
    "thresholds": [
      {
        "signal": "battles_won_ratio",
        "above": 80,
        "advise": "raise"
      },
      {
        "signal": "battles_won_ratio",
        "below": 35,
        "advise": "lower"
      },
      {
        "signal": "party_size",
        "below": 3,
        "advise": "lower"
      },
      {
        "signal": "days_survived",
        "above": 60,
        "advise": "hold"
      }
    ]
  }
]

input_bindings

Ações próprias de um pacote, com a chave que desejarem. O jogador decide: uma sugestão que termina em uma combinação que ele já havia atribuído perde, e a ação vem sem botão, porque um botão que faz outra coisa silenciosamente é pior do que um botão que não faz nada.

  • Status Pronto para usar
  • Pasta content/input
  • Registros roteados para o campo action_id
  • Relatório modding_input_report
  • Se um jogador desinstalar você preserve_inert_reference. A reatribuição de um jogador permanece armazenada no ID da ação, portanto, a reinstalação do pacote encontra o botão onde você o colocou. A ação em si é removida do mapa de comando quando o pacote sai, então a tela de atribuição nunca lista algo que não responde a nada.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
action_idSimtexto, id
label_keySimcorda
contextSimexploration, combat, menu, global
suggested_keyboardSimcorda
suggested_controller-corda

Em um arquivo chamado bindings.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a input_bindings record, under content/input

[
  {
    "action_id": "northern_reach:call_scout",
    "label_key": "KEY_PACK_CALL_SCOUT",
    "context": "exploration",
    "suggested_keyboard": "f9"
  }
]

settings

Opções que um jogador pode alterar, declaradas em vez de sorteadas. Um pacote diz qual é a opção, quais valores ela pode ter e onde reside o valor; o controle é construído pelo convidado. Nada que cruze essa fronteira é um Controle ou um script, e essa é a única razão pela qual um menu de configurações pode mostrar as opções de um estranho sem executar seu código.

  • Status Pronto para usar
  • Pasta content/settings
  • Registros roteados para o campo key
  • Relatório modding_settings_report
  • Se um jogador desinstalar você preserve_inert_reference. Um valor armazenado permanece sob sua chave, então a reinstalação do pacote encontra a escolha do jogador onde ele o deixou. O que o pacote deixa é uma linha em um perfil que ninguém lê: não custa nada e preserva uma escolha feita pelo jogador.

Campos. Um campo que esta tabela não nomeia é rejeitado com o registro.

CampoNecessárioValores
keySimtexto, id
typeSimbool, int, float, string, enum
defaultSimqualquer um
scopeSiminstallation, campaign, presentation
label_keySimcorda
help_key-corda
max_length-inteiro de 1 a 4096
maximum-número
migrates_from-texto, id
minimum-número
options-lista de cordas
requires_restart-booleano
secret-booleano

Em um arquivo chamado settings.json, ou qualquer nome .json que você quiser dentro dessa pasta:

a settings record, under content/settings

[
  {
    "key": "northern_reach:patrol_density",
    "type": "int",
    "default": 3,
    "minimum": 1,
    "maximum": 9,
    "scope": "campaign",
    "label_key": "OPTION_PACK_PATROL_DENSITY",
    "help_key": "OPTION_PACK_PATROL_DENSITY_HELP"
  },
  {
    "key": "northern_reach:show_road_names",
    "type": "bool",
    "default": true,
    "scope": "presentation",
    "label_key": "OPTION_PACK_SHOW_ROAD_NAMES"
  }
]

Atalhos do console

Estes são um atalho, não uma etapa. Tudo abaixo tem um lugar na tela Mods, que é por onde segue o caminho normal e para onde qualquer pessoa que baixou seu pacote irá procurar. O console é mais rápido quando você está iterando e já está aberto, e só existe em uma versão de depuração: uma cópia publicada do jogo não tem console, então nada que um autor de pacote precisa pode ficar aqui sozinho.

ComandoA mesma coisa na tela do Mod
modding_open_foldero caminho na parte superior e o botão próximo a ele
modding_manifest_reporta coluna de status e a linha abaixo de cada linha
modding_<family>_reportas contagens em cada pacote e Mostrar detalhes
modding_preflight_reportVerifique a compatibilidade
modding_roots_report, modding_safety_reportCopiar o relatório
modding_reloadSem botões na tela. Reiniciar o jogo faz a mesma coisa e é a única forma que possui uma compilação publicada; isso evita que você tenha que reiniciar durante a iteração. É a única linha aqui que é mais conveniente do que um atalho para algo que a tela já faz.

Comece em modding_manifest_report — o jogo vê seu pacote e em que estado? - então modding_preflight_report para um veredicto único sobre tudo instalado. Em seguida, o relatório de cada família.

modding_reload lê seus arquivos novamente sem reiniciar. Edite, use Alt-Tab, digite o comando e veja. Ele reconstrói o que nada está segurando — bindings, efeitos e imagens — e nomeia cada família deixada de lado, porque uma partida está sobre os registros que um save pode nomear:

what the game prints back

HELD BY THE RUN items: edited files are read on the next load

modding_reload all lê tudo novamente e é para uma tela inicial sem nenhum jogo em andamento. modding_condition_report imprime o que o jogo agora pode responder por um when e o que não pode.

ComandoO que isso te diz
modding_roots_reportRaízes e pegadas de mods de dados
modding_manifest_reportEstados de modificação (ativo/inválido/ignorado/conflitante)
modding_fingerprint_reportPegadas determinísticas de salvamentos (save_wired=no)
modding_safety_reportPostura segura (mods de comportamento desativados, arquivos bloqueados)
modding_preflight_reportVeredicto VERDE/VERMELHO em todos os mods ativos
modding_packaging_reportDetecção PCK/ZIP de nível 2 (desativada por padrão)
modding_campaign_reportModding_campaign_report [id] - campanhas instaladas somente leitura; com um id, você vai lá
modding_condition_reportO que o mundo publica para condições recordes
modding_reloadModding_reload [all] - releia os pacotes; all somente se não houver jogo em andamento
modding_binding_reportLinks de envio: vinculados/rejeitados/substituídos
modding_open_folderCria (se necessário) e abre a pasta mods do usuário

Ferramentas off-line

Estas ferramentas são para autores e automação de lançamentos. Elas ficam no checkout público do Bonemark; jogadores que instalam um mod lançado não precisam de Python nem Godot. Se você escreve um mod, clone a versão correspondente de github.com/tallowgames/Bonemark, mantenha seu pacote de trabalho fora da pasta mods do jogador e execute os comandos abaixo a partir desse checkout. O jogo continua sendo a autoridade final do runtime.

Python 3.10 ou mais recente; Godot apenas para pista de tempo de execução. Mantenha seu pacote fora da pasta mods do player e tente uma cópia.

a command line

python tools/modding/new_mod.py --list
python tools/modding/new_mod.py --id my_mod --family goods --family items

Ele escreve um pacote que passa na validação antes mesmo de você escrever qualquer coisa: um mod.json pré-compilado, um registro de trabalho para cada família solicitada e um README com os próximos dois comandos. Os registros vêm de equipamentos que a construção já verifica para essas famílias, portanto, um starter que para de funcionar causa a mesma verificação que faz com que o equipamento falhe, em vez de apodrecer dentro de um modelo. Ele se recusa a gravar em uma pasta chamada mods.

a command line

python tools/quality/validate_mod_data.py --root "<mod-root>"
python tools/quality/validate_mod_data.py --strict --root "<mod-root>"

Verifique mod.json, pastas familiares, ids, esquemas, referências, limites e cargas bloqueadas. --strict transforma avisos em falhas.

Compare a superfície de modding com a versão

Quando o jogo mudar, compare o instantâneo da superfície arquivado antes de atualizar um pacote. Ele contém um resumo, além de campos e operações para cada família pública, portanto o resultado indica qual família foi alterada e por quê:

a command line

python tools/quality/modding_surface_contract.py --json
python tools/quality/modding_surface_contract.py --before "<previous-build>/game/games/bonemark/modding/data/mod_surface_contract.json" --json

A diferença é unchanged, additive ou breaking. Os motivos da falha são explícitos: field_removed, required_added, type_changed, default_changed, constraint_changed, operation_removed e root_changed, format_changed, id_field_changed, catalogue_changed, family_removed e contract_major_changed_without_new_id. Nome de modificação compatível field_added, required_removed, operation_added ou family_added. O comando sem --before também verifica a linha de base armazenada. Se a superfície atual foi movida, a auditoria falhará até que um mantenedor examine os resumos exatos antes/depois em tools/quality/modding_surface_contract_changes.json; uma alteração significativa também deve registrar cada motivo, a decisão, a nota de migração e o revisor. A promoção de um instantâneo intencionalmente revisado é explícita:

a command line

python tools/quality/modding_surface_contract.py --write-baseline

Esta é uma verificação do mantenedor/lançamento; os autores do mod só precisam da comparação --before, e os jogadores que instalam um pacote lançado não precisam executá-lo.

a command line

python tools/modding/mod_test_host.py --root "<mod-root>" --repo-root "<framework-root>" --json

Lê o manifesto, dependências, compatibilidade e ordem de carregamento sem iniciar o Godot e sem executar nenhum pacote.

Nunca abre um arquivo de conteúdo. Esta é a divisão do trabalho: o host responde estes pacotes serão carregados juntos, o validador responde este registro está correto - mas isso significa que um pacote que o validador rejeita ainda pode ser composto de forma limpa aqui. Medidos em quatorze pacotes deliberadamente quebrados, os dois discordam em cada rejeição: o host prepara todos os quatorze refused vazios, incluindo um carregando scripts/payload.sh que apenas o validador encontra. Discar não é o mesmo que instalar com segurança. Faça as duas coisas antes de publicar. Repita --root quando o conjunto de teste for dividido em pastas; o host então compõe o conjunto completo em um plano determinístico.

a command line

python tools/modding/mod_test_matrix.py --repo-root "<framework-root>" --root "<mod-root>" --godot "<godot-exe>" --require-runtime --report "mod_test_matrix.json"

Ele executa o validador, o host de teste, o equipamento de cada família pronto para uso e a pista de tempo de execução Godot. Remova --require-runtime se você não tiver Godot; o relatório dirá então que o teste de tempo de execução foi ignorado e não aprovado.

Para um conjunto composto, repita a opção:

a command line

python tools/modding/mod_test_matrix.py --repo-root "<framework-root>" --root "<mod-a>" --root "<mod-b>" --godot "<godot-exe>" --require-runtime

O relatório mantém um resultado por raiz e adiciona composed_set para o conjunto completo. Este bloco é onde são demonstrados conflitos de pacotes, IDs duplicados e erros de dependência. Um pacote limpo por si só não é prova de que o conjunto será carregado junto. O relatório também inclui surface_contract, a versão atual do contrato familiar, e o resumo de auditoria, portanto, uma matriz não pode ser verde enquanto o instantâneo de compatibilidade do repositório estiver desatualizado. Com --require-runtime, leia runtime.reachability.loaded_families e runtime.reachability.reachable_families. A primeira diz que os registros compostos foram carregados; o segundo só é preenchido quando um caminho real direcionado aos jogadores da sonda Godot os consumiu. runtime.reachability.observations mantém o pacote, família, ID do registro, caminho e status para cada linha, enquanto unreachable lista as linhas carregadas que ainda não possuem nenhum caminho. Uma família pode ser validada e encenada, mas ainda assim estar ausente de reachable_families: "carregado" não é o mesmo que "um jogador pode alcançá-lo".

Cada comando acima é verificado nas próprias ferramentas à medida que esta página é construída: o script deve existir e cada opção deve ser aceitável.

Cada código de diagnóstico

Não leia esta lista em ordem. Está aqui para que um código que você encontra em um relatório seja uma pergunta com uma resposta – uma pequena palavra em letras minúsculas como asset_missing. Cole um na caixa de pesquisa no topo desta página.

Alguns códigos pertencem a mecanismos que um pacote ainda não consegue alcançar. Estou aqui da mesma forma: um código que você não pode acionar custa uma linha que você nunca lerá, e um código que está faltando custa uma noite.

CódigoO que causou issoO que fazer
adaptive_brings_a_modelUm pacote tentando carregar algo ou chegar a algum lugar.Remova o caminho ou endereço e escolha uma política publicada por nome. Quaisquer arquivos que você trouxe não serão carregados aqui.
adaptive_fell_backUm perfil que não atingiu seu piso e utilizou a política que havia declarado.Nada para consertar, a menos que eu nunca pare. O perfil não tinha sinais suficientes entre aqueles que ele lia, então ele usou a política que declarou como alternativa.
adaptive_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
adaptive_over_budgetUm pacote acima do teto declarado.O relatório imprime o que foi medido próximo ao que foi permitido. Divida o registro ou remova entradas além da linha: o teto é o que uma tela ou leitor pode conter, não uma sugestão.
adaptive_text_not_keyUma frase onde uma chave de catálogo é necessária.Mova a frase para o seu catálogo de idiomas e coloque sua chave no campo. Um campo que termina em _key contém uma chave; uma frase ali deixa seu pacote em um idioma para sempre.
adaptive_unknown_stepUma política, sinal ou direção que esta construção não possui.O nome não está na lista publicada dessa tabela. Escolha um que esteja aí: a lista é curta porque cada entrada é algo que esta compilação já faz.
adaptive_unresolved_referenceUm registro nomeado que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
assembly_dangling_referenceUma escada, porta ou entrada nomeia algo que este mapa não contém.Adicione o objeto nomeado a este mapa ou corrija o ID. Uma escada cujo patamar não está no mapa é um andar onde o jogador pode entrar e não pode sair, e um edifício cuja entrada não é uma passagem é uma porta desenhada na parede. As duas extremidades devem estar no mesmo arquivo.
assembly_leakedA desmontagem liberou menos nós do que a montagem.Nada para consertar em seu pacote e nada em um pacote pode causar isso. A desmontagem liberou menos nós do que a montagem, então algo está preso em alguma parte do mapa anterior - escreva-o junto com o mapa que o produziu. É visto como uma memória que cresce cada vez que você entra no mesmo lugar.
assembly_missing_aspectUma parte obrigatória do layout não produziu nada, então você não cabe no mapa.Adicione a parte que falta em sua camada e exporte novamente. A mensagem diz o seguinte: retângulos percorríveis vão para a camada percorrível, colisores na colisão e a camada de blocos de terreno deve cobrir o mapa. Um mapa sem nada que possa ser percorrido é um lugar onde o jogador pode entrar e não se mover, por isso é rejeitado em vez de publicado.
assembly_over_budgetA forma montada está além de um telhado declarado.Retire parte do que a mensagem contava ou divida o mapa. O telhado é medido pelo que foi montado e não pelo tamanho do arquivo, então comprimir as camadas não muda nada: o número na mensagem é o que a máquina deveria ter segurado.
assembly_refusedNada foi construído, porque construir meio mapa é pior do que não construir nenhum.Corrija quaisquer outras mensagens desta execução e exporte novamente. Nada foi construído de propósito: metade do mapa é uma sala em que você entra sem paredes, e não haveria como saber qual metade o fez.
assembly_unreachable_affordanceUm ancoradouro é onde nada é declarado transitável, então ninguém pode alcançar o que ele oferece.Desenhe um retângulo percorrível que toque a âncora nomeada pela mensagem, no mesmo plano. Uma âncora é a própria coisa e o ator fica ao lado dela, então um balcão dentro de uma área transitável é um balcão pelo qual o jogador passa, e um balcão sem nada ao redor é um serviço que ninguém pode alcançar. Verifique primeiro a propriedade do andar: um beliche no andar de cima não é atendido pelo quarto de baixo.
asset_invalidExiste um descritor e esta compilação o rejeita. O veredicto diz qual regra.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
asset_kind_mismatchO chamador solicitou um tipo e o descritor indica outro. Resolvê-lo de qualquer maneira daria uma textura a algo que espera um som.Vincule um recurso do tipo que o slot utiliza. Ninguém desenha um retrato para uma região, então a conexão nunca seria traçada e nada diria o porquê.
asset_missingO pacote está instalado e não declara nenhum descritor sob esse ID.O ID do recurso não resolve nada na composição. Traga o arquivo ou aponte o link para aquele que seu pacote realmente contém.
asset_package_missingNenhum pacote instalado responde ao namespace que o ID nomeia.O pacote que forneceu este recurso não está instalado. Reinstale-o ou vincule o slot a algo que caiba em um pacote instalado.
audio_cue_refusedUm som ou playlist que esta compilação não grava.Leia a regra nomeada ao lado do código e recodifique para cumpri-la. As causas habituais são um formato que não decodificamos e uma duração além do limite declarado.
audio_placeholder_usedUm som rejeitado ou ausente foi resolvido no substituto reservado e o chamador foi notificado.Nada para consertar, se você quisesse. Faltava o som, então a substituição do seu tipo soou e a substituição foi sinalizada em vez de ficar em silêncio.
audio_refusedUm som que esta construção não reproduz. O veredicto diz qual regra.O próprio arquivo de áudio foi rejeitado antes que qualquer coisa o reproduzisse. Recodifique-o para um formato declarado dentro do tamanho declarado e mantenha a taxa de amostragem entre as da lista publicada.
audio_stream_overranUm fluxo que ultrapassou a duração declarada pelo seu descritor, parou no limite.O fluxo é mais longo do que o slot permite. Encurte-o ou mova-o para um slot cujo orçamento o cubra: um fluxo que ultrapassa é um fluxo que o mixer precisa cortar no meio da palavra.
binding_invalidUma conexão que esta construção não faz.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
binding_missing_alternativeInformação que um jogador não pode receber, sem que nada mais a carregue.Um retrato e um ícone precisam de uma chave de descrição, e uma linha falada precisa de uma chave de legenda. Adicione a alternativa: É a única regra de acessibilidade que um jogador ouve diretamente.
binding_over_budgetEnviar um pacote além do que um dos totais permite.O relatório imprime o que foi medido próximo ao que foi permitido. Divida o registro ou remova entradas além da linha: o teto é o que uma tela ou leitor pode conter, não uma sugestão.
binding_placeholder_usedUm som que ninguém fornece, resolvido no substituto do seu tipo.Nada para consertar, se você quisesse. O link resolveu o substituto para o tipo de recurso de seu slot, e o relatório informa qual slot, para que você possa distinguir uma decisão de um descuido.
boot_attempt_recordedUma tentativa foi escrita antes do início da composição.Nada para consertar. A inicialização foi escrita antes de ser tentada, e é isso que permite que a próxima inicialização saiba que algo deu errado.
boot_last_known_good_offeredEm vez disso, é oferecido um perfil que foi iniciado no passado.A composição que falhou não foi a que funcionou, então foi oferecida a última que funcionou. Obtenha-o e reinstale os pacotes, um de cada vez, para encontrar aquele que quebrou tudo.
boot_marker_unwritableA tentativa não foi registrada. O jogo é iniciado com a recuperação desabilitada para esta sessão e diz isso.O marcador de inicialização não pôde ser gravado, então da próxima vez você não conseguirá distinguir uma falha de uma saída limpa. Verifique se a pasta de dados do jogo é gravável; Não se trata do seu pacote.
boot_package_rejectedUm pacote foi rejeitado durante a recuperação. O id é registrado, nunca o caminho.Este pacote impediu o lançamento do jogo e ficou de fora. O relatório nomeia a recusa; conserte-o e reinstale-o ou deixe-o de fora.
boot_retry_offeredAbaixo do limite; o mesmo perfil é tentado novamente.Aceite a nova tentativa. Se a segunda inicialização também falhar, o problema é a composição e não o tempo, e a próxima oferta será o modo de segurança.
boot_safe_mode_offeredO limite está esgotado; o jogo oferece para começar sem nenhum pacote.Aceite o modo de segurança e remova os pacotes, um de cada vez, até iniciar. Seu salvamento não é tocado: o modo de segurança lê e nunca grava nele.
budget_aggregate_exceededO conjunto instalado excedeu o limite compartilhado. O pacote nomeado é aquele que passou por ele, na ordem de carregamento.Tire algo da composição. São todos os pacotes juntos que estão acima do limite, não só os seus, e o relatório imprime o total próximo ao limite.
budget_degradedUma dimensão foi reduzida em vez de rejeitada, e é nomeado aquilo em que está incorporada.Nada para consertar, a menos que você queira dizer o contrário. A composição manteve-se dentro do seu orçamento, abrindo mão da qualidade e não do conteúdo: não falta nada, algo é menor.
budget_package_exceededUm pacote excedeu seu limite de tamanho.Leia o tamanho mencionado no relatório e corte o que ele mede. Imprima quanto seu pacote usou ao lado de quanto um pacote pode usar.
budget_soft_warningAlém do limite suave, carregado de qualquer maneira, reportado a quem cria.Nada para consertar por enquanto. Você está perto o suficiente de um teto para que outro bando o ultrapasse, e é útil saber antes que o de outra pessoa o faça.
budget_unknown_dimensionHouve relato de consumo em um tamanho que esta build não declara, ou seja, alguém escrevendo contra uma superfície que não existe.O orçamento nomeia algo que esta construção não mede. Escolha um tamanho na lista publicada - um tamanho que não medimos nunca será aplicado.
budget_unknown_profileUm perfil que esta compilação não declara. O perfil mais severo é aplicado em vez do mais amplo.Escolha um perfil de orçamento na lista publicada. Os perfis são escolhidos em vez de serem descritos, portanto, aquele que não publicamos é aquele que ninguém imporia.
campaign_hardcoded_identityUm consumidor escreveu o ID base da campanha em vez de perguntar qual campanha está selecionada.Algo aconteceu e pegou o ID da campanha base, texto ou cena pelo nome, em vez de perguntar a campanha selecionada. Resolva isso através do contexto da campanha, caso contrário uma conversão receberá a resposta deste mundo em vez da sua própria.
campaign_invalidA declaração não é aquela que esta compilação selecionaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
campaign_not_foundUma campanha foi selecionada para id e nenhuma declaração responde a esse id.O ID da campanha nomeado não está instalado. Verifique como você o escreveu ou instale o pacote que o fornece: aqui não depende da campanha básica.
character_carries_handlerDados públicos nomeando um símbolo privado.Remova o campo que nomeia um método ou retorno de chamada. Publicar um símbolo interno torna-o um contrato público, e a renomeação que o quebra, os jogadores relatam como quebra do jogo.
character_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
character_origin_missingUm personagem cuja origem não é fornecida por ninguém, carregado de substitutos.Reinstale o pacote que escreveu esta fonte. O personagem se carregou com o substituto reservado e o id que ele perdeu viaja com ele, então a reinstalação o coloca exatamente como estava.
character_tree_unenterableUm loop ou nó inacessível em uma árvore de progressão.Veja se o relatório diz ciclo ou órfão e reconecte essa parte da árvore. Nem é um erro durante o jogo - a opção simplesmente nunca é oferecida e o arquivo parece correto.
character_unknown_propertyUma propriedade que não significaria nada para nenhum sistema.Use uma propriedade que esta compilação possui. Aceitar um que não tenha, colocaria um campo no save que não significa nada para nenhum sistema e não pode ser explicado a ninguém, para sempre.
combat_carries_formulaUm pacote que tenta fornecer a aritmética de um conflito.Remova o campo. O nível 1 são os dados: o que é executado pertence ao jogo e os novos recursos vêm de um fornecedor confiável.
combat_effect_expiredUm estado salvo cuja calibração desapareceu, encerrado no carregamento.O pacote que calibrou esse estado não está mais instalado, então o estado acabou sendo aplicado com números que ninguém possui. Reinstale-o para mantê-lo.
combat_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
combat_over_budgetUm pacote acima do teto declarado.O relatório imprime o que foi medido próximo ao que foi permitido. Divida o registro ou remova entradas além da linha: o teto é o que uma tela ou leitor pode conter, não uma sugestão.
combat_phase_unreachableUma fase escrita e nunca alcançada.Duas fases compartilham um limite, então uma delas nunca seria iniciada. Dê-lhes diferentes valores de saúde restantes.
combat_unknown_operationUma operação ou parâmetro que o solucionador não possui.Escolha a operação na lista publicada e forneça apenas seus parâmetros. Um empurrão que carrega valor é uma linha mal interpretada, não um empurrão mais forte.
combat_unknown_statusUm estado que esta compilação não publica.Calibre um estado que esta compilação publica em vez de inventar um. Um estado inventado fica em uma unidade atrás de um ícone em branco e não há nada que possa retirá-lo.
combat_unresolved_referenceUm registro nomeado que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
conversion_external_referenceUm endereço ou caminho que sai do pacote.Uma conversão apontada em seu próprio pacote. Traga com você aquilo a que você se refere, caso contrário o mundo irá pescar algo que você não escreveu.
conversion_fallback_allowedUma conversão que não negou o retrocesso no jogo base, nem no pôster nem na campanha.Nada para consertar. Esta família pode recorrer ao jogo básico, e a linha diz por que não é uma fuga.
conversion_family_unclassifiedExiste uma família de conteúdo e este catálogo não a classifica.Declara a família como propriedade do campo ou do motor. Uma família não classificada é aquela sobre a qual a verificação de escape do jogo base não consegue raciocinar.
conversion_missing_fileUm arquivo que o fixture declara e não possui.Um arquivo obrigatório cuja conversão declarada não está no pacote. Traga: uma conversão que falta uma parte de si mesma começa e não pode continuar.
conversion_partial_atomic_familyUma família atômica foi fornecida apenas parcialmente. Rejeitado em vez de publicado com a costura à mostra.Traga toda a família ou não traga ninguém. Metade de uma lista de missões é um mundo que se refere a missões que ninguém escreveu.
conversion_required_family_missingAusente uma família possuída pelo campo que a conversão deveria proporcionar.Traga a família. O catálogo diz quais são necessários para uma conversão, e sem eles o mundo é o jogo base com nova arte.
conversion_unclaimed_familyUma família para a qual o pacote fornece arquivos e que a campanha não reivindica.Reivindique a família em um pacote ou declare o adiamento com motivo. Se não for reclamado, nada diz se a sua ausência foi intencional.
conversion_unknown_familyA campanha declarou uma família que esta construção não conhece.Nomeie uma família do catálogo de tipos de conteúdo. As famílias se declaram lá antes que alguém possa fornecer um.
conversion_vanilla_leakUm ID que não pertence à conversão nem ao namespace reservado do mecanismo.Substitua o id, texto ou cena que o relatório nomeia. Esta conversão anula o substituto, então a alternativa é o jogador ver este mundo dentro daquele outro.
dialogue_carries_expressionUm pacote que tenta executar algo ou escrever palavras na hora.Remova o campo. O nível 1 são os dados: o que é executado pertence ao jogo e os novos recursos vêm de um fornecedor confiável.
dialogue_dead_endUma conversa da qual um jogador não consegue sair.Tenha um ponto de opção deste nó para um caminho que chega ao fim. Um ciclo está bom; um beco sem saída é uma conversa da qual o jogador não pode sair.
dialogue_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
dialogue_orphan_nodeUm nó que nada pode alcançar.Nada vai para este nó, então nenhum jogador irá lê-lo. Faça-o apostar contra uma opção ou descarte-o.
dialogue_over_budgetUm pacote acima do teto declarado.O relatório imprime o que foi medido próximo ao que foi permitido. Divida o registro ou remova entradas além da linha: o teto é o que uma tela ou leitor pode conter, não uma sugestão.
dialogue_text_not_keyUma frase onde uma chave de catálogo é necessária.Mova a frase para o seu catálogo de idiomas e coloque sua chave no campo. Um campo que termina em _key contém uma chave; uma frase ali deixa seu pacote em um idioma para sempre.
dialogue_unguarded_revealUm segredo sem nada à frente.Coloque pelo menos uma condição no nó. Uma lista de condições vazia conta como nenhuma: o segredo iria para quem abre a conversa.
dialogue_unknown_stepUm controle ou comando que esta compilação não possui.O nome não está na lista publicada dessa tabela. Escolha um que esteja aí: a lista é curta porque cada entrada é algo que esta compilação já faz.
dialogue_unresolved_referenceUm registro nomeado que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
distribution_hash_mismatchOs arquivos no disco não são o que o registro descreve.O pacote do disco não é o que foi lançado. Baixe novamente: uma incompatibilidade é uma transferência que deu errado ou um arquivo que outra pessoa alterou.
distribution_invalidO registro não é aquele que esta compilação aceitaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
distribution_offlineA procedência foi verificada em relação ao que foi registrado no momento da instalação.Verifique sua conexão e tente novamente. Os pacotes já instalados continuam funcionando; novos não podem ocorrer até que o serviço retorne.
distribution_reportedAlguém relatou isso. O jogador é notificado e decide.Leia o relatório e decida. O pacote funciona da mesma forma: o relatório existe para que a decisão seja tomada na frente dele, e não no seu lugar.
distribution_revokedO pacote está em quarentena ou retirado. Não instala.Remova o pacote. Foi retirado após publicação e não está sendo carregado; se você escreveu, o aviso de revogação diz o porquê.
distribution_update_deferredHá uma nova versão disponível e uma campanha em andamento na antiga.Reinicie para fazer a atualização. Trocar um pacote em um jogo em andamento é como um save começa a nomear coisas que ninguém fornece.
economy_expression_refusedUm campo que traria algo para avaliar.Uma entrada de preço tentava trazer algo valioso. Escolha uma curva pelo nome dentre as quatro que esta construção implementa: Um preço que pode ser executado é o limite do nível 1 alcançado pela economia.
economy_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
economy_out_of_boundsUm número fora do intervalo indicado.Retorna o número dentro do intervalo declarado. Cada campo numérico aqui tem um, e um campo sem intervalo declarado é rejeitado em vez de permitido.
economy_overriddenUm pacote substituiu um registro declarado por outro pacote ou jogo base.Nada para consertar. Esse registro foi tirado por outro pacote, e o relatório diz qual, para você decidir se essa era a intenção.
economy_unresolved_referenceUma receita ou tanque que nomeia conteúdos que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
effect_carries_sourceUm descritor que nomeia um sombreador, cena ou código.Remova o campo que nomeia um sombreador, script ou cena. Os efeitos são compostos a partir das primitivas do motor; fornecer a fonte é fornecer um programa.
effect_degradedUm efeito reduzido para caber dentro do quadro, nomeado para que a redução não seja um mistério.Nada para consertar, a menos que você queira dizer o contrário. O efeito foi a redução da qualidade para permanecer dentro do orçamento do quadro: ainda está lá e é menor.
effect_droppedUm efeito que simplesmente não existia.Veja o tamanho que o demonstrativo orçamentário indica que foi preenchido e, em seguida, corte-o. O quadro ficou sem espaço e esse efeito não foi desenhado.
effect_refusedUm efeito que esta build não marca. O veredicto diz qual regra.Leia o parâmetro nomeado no relatório e informe-o dentro do intervalo impresso ao lado dele. O efeito foi rejeitado antes que qualquer coisa o atraísse.
extension_forbidden_fieldO manifesto carrega um campo que nenhuma extensão pode carregar, como o caminho para um script, um resolvedor ou uma importação privada.Remova o campo. O caminho para um script, solucionador, importação privada ou alteração nas configurações do projeto vai além do contrato para o convidado, e uma extensão que precisa dele está solicitando um recurso em vez de declarar um recurso: declare o recurso em requires.
extension_foreign_namespaceO namespace de estado declarado não é o ID do pacote da extensão, portanto seu estado não seria atribuível depois que ele desaparecesse.Renomeie state_namespace para o ID do pacote da extensão. O status escrito em outro lugar não pode ser atribuído ou removido depois que o pacote acabar e o hóspede manterá seus nomes.
extension_missing_fieldFalta um campo que o convidado precisa para instalar, tirar uma impressão, voltar ou remover a extensão.Adicione o campo ao manifesto da extensão. Cada um deles é algo que o hóspede precisa antes de solicitar a extensão, colocá-la na área de composição, voltar ou removê-la novamente: um pôster faltando descreve um recurso que o convidado poderia instalar e nunca remover.
extension_teardown_incompleteA remoção da extensão rendeu menos do que o necessário, o que faz com que ela perca na próxima instalação, em vez de agora.Retorne tudo o que a extensão levou antes de declarar a desmontagem completa e atualize takes se o número verdadeiro tiver mudado. Retornar less não falha agora: perde na próxima instalação, e instalar a mesma extensão duas vezes em uma sessão é comum.
extension_unboundedFalta um orçamento declarado ou não há um número, então nada pode superá-lo.Escreva um número para cada orçamento nomeado no contrato. Um orçamento omitido, ou escrito em forma de frase, lê-se como está declarado e não se compara a nada, pelo que a prorrogação nunca pode ultrapassá-lo.
extension_unknown_capabilityA extensão requer ou fornece um recurso que esta compilação não publica.Compare os IDs de habilidade com os que esta compilação publica e remova ou renomeie aqueles que não correspondam. Recusar antes da instalação é intencional: uma extensão que descobrisse uma habilidade ausente enquanto girava a descobriria na frente de um jogador.
extension_would_add_autoloadO manifesto adicionaria uma variável global. Rejeitado seja o que for que o nível de confiança diga, porque um pacote que pudesse adicionar um desfaria o retrocesso no qual esta compilação foi construída.Remova o nome de carregamento automático, singleton ou carregamento automático básico do manifesto. Nenhum nível de confiança garante isso: toda a migração da qual esta compilação depende é a desativação de variáveis ​​globais, portanto, uma extensão que pudesse adicionar uma iria desfazê-la externamente. Coloque o estado no namespace da extensão e alcance o convidado por meio dos recursos que ele publica.
font_locale_fallbackUm glifo que o personagem escolhido não carrega, extraído do substituto e relatado.A fonte que você forneceu não possui glifos para esse idioma, então o substituto a desenhou. Traga uma fonte que cubra o idioma, caso contrário o texto ficará em pequenos quadrados.
font_refusedUm personagem que esta construção não usa. O veredicto diz qual regra.O arquivo de fonte foi rejeitado. Verifique se o formato é um dos que carregamos e se o arquivo não contém nenhum programa.
image_bomb_refusedUm cabeçalho que reivindica mais do que o orçamento de decodificação, rejeitado antes que qualquer decodificador o veja.A imagem é descompactada em muito mais do que o tamanho do arquivo sugere. Reexporte-o para o seu tamanho real: ele é rejeitado antes de ser decodificado, porque decodificá-lo é o dano.
image_frame_gridUma planilha cuja grade declarada não a divide exatamente.Os frames da sprite sheet não dividem suas dimensões exatamente. Ajuste a grade, caso contrário, cada quadro após o primeiro será deslocado pelo resto.
image_hash_mismatchBytes alterados após a validação do descritor.A imagem não é o que foi anunciado. Reexportar ou redeclarar: uma incompatibilidade significa que o arquivo e o manifesto não concordam com o que foi portado.
image_placeholder_usedUma imagem rejeitada ou ausente foi resolvida no substituto reservado e o chamador foi notificado.Nada para consertar, se você quisesse. A imagem estava faltando e a substituição do seu tipo foi desenhada, com a substituição sinalizada em vez de deixada em branco.
image_refusedUma imagem que esta compilação não decodifica. O veredicto diz qual regra.Exporte novamente para o tamanho, formato e orçamento indicados no relatório. A imagem foi rejeitada antes que qualquer coisa a desenhasse.
inference_cancelledUma execução excedeu seu orçamento de latência e foi interrompida. A heurística atendeu, então o chamador não precisou esperar.Reduza o modelo ou aumente max_latency_usec se o orçamento estiver realmente muito apertado. A execução excedeu seu orçamento e foi interrompida, e a heurística respondeu em vez de deixar o chamador esperando: um quadro gasto em espera é um quadro que o jogador olhou.
inference_digest_mismatchOs bytes do padrão não são os registrados, o que o torna um padrão diferente e não mais antigo.Atualize o resumo declarado para o SHA-256 do modelo que você está portando ou porta o modelo que o resumo nomeia. Bytes diferentes significam que este é um modelo diferente e não há outra maneira de saber a diferença.
inference_forbidden_fieldA declaração carrega um tempo de execução, um script, um endpoint, alguma telemetria ou uma reivindicação de autoridade.Remova o campo. O adaptador pertence ao motor, portanto um pacote fornece os pesos e nunca o código que os executa; um endpoint colocaria o modelo em um local onde ele poderia ser alterado após revisão, e a telemetria relataria o que o jogador solicitou. Traga os pesos e deixe o motor fazer isso.
inference_load_refusedA instrução está correta e esta compilação não traz nenhum adaptador de inferência para carregá-la, então a heurística determinística respondeu.Nada para consertar em seu pacote. Esta construção não carrega nenhum adaptador de inferência, portanto, nenhum modelo de qualquer formato é carregado e a heurística determinística responde. A declaração é validada de qualquer maneira, portanto, um modelo portado hoje é um modelo que um adaptador poderia carregar sem modificação.
inference_missing_fieldFalta em uma declaração de modelo algo que o adaptador precisa antes de gastar qualquer coisa em uma execução.Adicione o campo à declaração do modelo. Cada um é algo que o adaptador precisa antes de gastar qualquer coisa em uma execução: o resumo é a identidade do modelo, os padrões são o que você alimenta e o que ele aceitará de volta, e as plataformas são onde ele pode ser testado.
inference_output_rejectedA resposta do modelo não correspondeu ao padrão de saída declarado e foi descartada em vez de interpretada com tolerância.Compare o que o modelo retorna com o padrão de saída declarado. Uma resposta quase certa é descartada em vez de ser interpretada com tolerância, porque uma proposta que passa de forma errada é aquela que cada verificação subsequente é considerada válida.
inference_unboundedFalta um limite declarado ou não é um número, então nada pode excedê-lo.Escreva um número para cada limite nomeado pelo contrato. Um limite omitido, ou escrito em palavras, é lido como declarado e não é comparado a nada, então a execução que dá errado é aquela que ninguém estava medindo.
inference_unknown_formatO formato do modelo não é aquele implementado pelo adaptador do mecanismo.Reexporta o modelo em um dos formatos implementados pelo adaptador do mecanismo. Um formato que não é implementado não é um caminho mais lento: não é nada.
inference_wrong_platformO modelo não declara esta plataforma, então a heurística determinística respondeu.Nada para consertar, se for desejado. O modelo não declara esta plataforma, então a heurística determinística respondeu aqui; adicione a plataforma à declaração somente quando o modelo tiver sido realmente construído e testado lá.
input_binding_conflictA chave sugerida já foi atribuída. A atribuição existente manteve-a e a dica foi registrada em vez de aplicada.Nada para consertar em seu pacote e nada retirado. O botão já estava atribuído, então a atribuição do jogador o manteve e sua ação é oferecida sem botão na tela de atribuição. Escolha um padrão menos lotado se quiser que ele permaneça na instalação.
input_binding_orphanedUma reatribuição pertence a uma ação que nenhum pacote instalado declara. Mantido em vez de removido, então a reinstalação o encontra onde o player o deixou.Nada para consertar. A reatribuição pertence a uma ação que nenhum pacote instalado declara e é preservada em vez de removida, portanto, a reinstalação do pacote encontra o botão onde o jogador o deixou.
input_core_actionUm pacote nomeado ou que tentou substituir uma das ações do host.Renomeie a ação. As ações do jogo pertencem ao host e um pacote não pode declará-las nem substituí-las; pegar pause é um jogo do qual você não consegue sair. Declare sua ação ao lado e deixe o jogador atribuir ambas.
input_forbidden_fieldA declaração traz uma leitura direta do dispositivo, um ouvinte, um punho de fogo ou uma atribuição que o jogador não pode alterar.Remova o campo. Declarar uma ação é toda a interface: ler um dispositivo diretamente, instalar um ouvinte, pegar fogo ou forçar uma tarefa, tudo tira a decisão do jogador e fica invisível em todas as telas que ele pode verificar.
input_foreign_namespaceO ID da ação não cabe no namespace do pacote que o declara.Renomeie o ID da ação para o namespace do seu pacote. A reatribuição do jogador está anexada a nós, portanto, um id que pertence a outra pessoa é uma reatribuição que muda de mestre quando um dos dois pacotes é removido.
input_keyboard_unreachableA ação não tem atribuição de teclado, então um jogador sem controle não pode alcançá-la.Escreva uma atribuição de teclado ao lado da atribuição do controlador. Uma atribuição apenas de pad é inatingível para um jogador sem pad, em um jogo que de outra forma poderia ser jogado sem, e para ele falha silenciosamente.
input_missing_fieldUma instrução de ação está faltando algo que a tela de atribuição ou reatribuição precisa.Adicione o campo à declaração de ação. Cada um é algo que uma tela precisa: a chave do rótulo é o que a lista de atribuições mostra no lugar do seu ID interno, e o contexto é o que informa ao jogo quando a ação está ativa, em vez de acioná-la enquanto alguém digita o nome de um salvamento.
input_reserved_chordUm pacote solicitou uma combinação que pertence ao sistema ou janela.Escolha outra chave. Fechar a janela, sair do jogo e a chave da plataforma pertencem ao sistema operacional, e um pacote que contém uma pode impedir que alguém saia.
input_unknown_contextO contexto declarado não é aquele que esta compilação publica, então ninguém sabe quando a ação está ativa.Escolha um dos contextos publicados. Ninguém sabe quando uma ação está viva em um contexto não publicado, então ou ela nunca seria acionada ou sempre seria acionada, e nem foi isso que você quis dizer.
lore_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
lore_player_state_in_definitionUm campo que descreve um jogador encontrado em uma definição.Remova o campo. Um registro de conhecimento é uma definição e o que o jogador sabe é: carregar conhecimento nunca concede conhecimento, então um campo que pretende fazer isso seria um campo que ninguém lê.
lore_replacedUm pacote substituiu uma entrada existente, preservando seu id e links.Nada para consertar. Outro pacote substituiu esta entrada e manteve seu id, então tudo que apontava para ele ainda aponta para alguma coisa.
lore_unresolved_referenceUm id em relaciona_to, revela ou exige que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
lore_verbatim_textTexto transportado no lugar de uma chave de catálogo, para que aparecesse em apenas um idioma.Um campo que termina em _key contém uma frase. Mova-o para o seu catálogo de idiomas: ignore todas as outras verificações aqui e traga seu conhecimento para apenas um idioma.
map_bad_layer_dataUma camada que não cobre o mapa ao qual pertence.Exporte novamente a camada descompactada, sem blocos e sem linhas curtas. O subconjunto que aceitamos é o subconjunto que sabemos controlar.
map_carries_pathUm mapa que nomeia algo para carregar ou executar.Remova o campo que aponta para um arquivo. Um mapa nomeia suas peças do kit; um caminho é a maneira como um pacote sai de si mesmo.
map_duplicate_anchorDois objetos reivindicando o mesmo ID.Duas âncoras compartilham um nome, portanto, a qual delas algo se atribui depende da ordem de leitura. Renomeie um.
map_invalidO mapa não é aquele que esta construção montaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
map_kit_mismatchUm mapa projetado contra um kit que esta compilação não possui.O mapa foi escrito em um kit diferente daquele publicado nesta compilação. Exporte-o novamente para o kit atual: as funções e classes foram movidas.
map_layer_missingUm nível obrigatório está ausente ou mal concebido.Adicione o nível exigido pelo contrato. O arquivo de projeto do kit os lista, e um que falta é um mapa carregado com um buraco.
map_normalization_failedO mapa não produziu nenhuma forma canônica.Remova a construção que o relatório nomeia e exporte novamente. Sem um formulário canônico você não pode provar que o tempo de execução e o validador offline concordam com este mapa.
map_outside_packageUm conjunto de peças ou modelo que vem de fora do pacote.O mapa aponta para algo fora do seu próprio pacote. Traga-o, caso contrário o mapa depende do que estiver instalado.
map_over_budgetUm mapa normalizado além de um limite declarado.O relatório imprime o que foi medido próximo ao que foi permitido. Divida o registro ou remova entradas além da linha: o teto é o que uma tela ou leitor pode conter, não uma sugestão.
map_unresolved_referenceUm ID nomeado que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
map_unsupported_subsetAlgo no arquivo está fora do subconjunto do formato.O arquivo usa uma função Tiled do subconjunto que esta construção lê: camadas recolhidas, camadas de imagem, grupos, blocos ou polígonos. Reexportar sem.
pack_claims_host_surfaceUm carregamento automático, uma ação de entrada ou uma configuração de projeto.Substitua o conteúdo em vez do arquivo. Os pacotes adicionam e substituem conteúdo; as superfícies necessárias para o início do jogo não estão entre elas.
pack_collisionUma reivindicação que outro pacote já possui.Desista do arquivo em um dos dois pacotes. O relatório nomeia os dois, e deixar assim ganharia a ordem de montagem.
pack_mount_failedEle não montou o motor; o conjunto anterior permanece válido.O pacote não pôde ser montado. Verifique se o arquivo está intacto e em um formato que esta compilação possa ler.
pack_replaces_vanillaUma afirmação que o jogo base possui.Substitua o conteúdo em vez do arquivo ou solicite um recurso de substituição confiável. Substituir um arquivo básico do jogo não é algo que um pacote de dados faz.
pack_restart_requiredO todo reunido mudaria e a mudança não pode ter efeito neste processo.A alteração não pode ser aplicada a um jogo em execução. Reiniciar: Trocar conteúdo montado no meio do jogo deixa metade do jogo lendo arquivos antigos.
progress_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
progress_origin_lostUma conquista conquistada cujo pacote desapareceu, foi preservado e nomeado.Nada para consertar. O pacote que o declarava desapareceu e o que o jogador ganhou permanece; a identidade está lá para que ele saiba o que o traria de volta.
progress_over_budgetUm pacote acima do teto declarado.O relatório imprime o que foi medido próximo ao que foi permitido. Divida o registro ou remova entradas além da linha: o teto é o que uma tela ou leitor pode conter, não uma sugestão.
progress_reaches_outsideUm pacote que tenta fazer algo ou falar em nome da plataforma.Remova o campo. O fato de um marco atingir a plataforma é derivado de seu namespace e nunca é algo que um registro diga.
progress_reserved_namespaceUm pacote reivindicando um namespace que não é seu.Use o namespace do seu pacote. Os reservados são nossos, e seria de se acreditar num gol que parecia ser da plataforma.
progress_text_not_keyUma frase onde uma chave de catálogo é necessária.Mova a frase para o seu catálogo de idiomas e coloque sua chave no campo. Um campo que termina em _key contém uma chave; uma frase ali deixa seu pacote em um idioma para sempre.
progress_unknown_stepUma condição ou modificador que esta compilação não possui.O nome não está na lista publicada dessa tabela. Escolha um que esteja aí: a lista é curta porque cada entrada é algo que esta compilação já faz.
progress_unresolved_referenceUm registro nomeado que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
provider_forbidden_capabilityUm pacote solicitou um recurso que nenhum nível concede, como sistema de arquivos, rede ou processo.Remova a capacidade. Nenhum nível concede o sistema de arquivos, rede, processo ou namespace de outro pacote, e nenhuma revisão ou assinatura altera isso: o que uma compilação faz com o sistema de arquivos não é uma propriedade que alguém possa controlar lendo-o. Use propose_intent para passar uma proposta ao proprietário canônico e write_own_namespace para o estado que deve sobreviver.
provider_native_extension_refusedUma extensão nativa foi encontrada. Ele tem autoridade total sobre o processo antes de qualquer política ser implementada, portanto é rejeitado por seu próprio motivo e não como uma falha na verificação de confiança.Remova a extensão do pacote. O mecanismo carrega um GDExtension com autoridade total sobre o processo antes de qualquer parte desta política ser executada, portanto, ele é rejeitado pelo que é e não por quem o assinou, e a ratificação do nível do fornecedor não alterará essa resposta.
provider_tier_inactiveA camada de provedores de comportamento não foi ratificada nesta compilação, portanto, nada executável foi carregado.Nada para consertar em seu pacote. Esta compilação não ratificou a camada Behavior Vendors, portanto, um script, cena empacotada ou extensão nativa é rejeitado por quem o assinou. Traga a mecânica como registros declarativos se uma das famílias publicadas puder carregá-la e leia as notas de lançamento da compilação que ratifica o nível antes de escrever contra um fornecedor.
provider_unknown_capabilityUm pacote solicitou um recurso que esta compilação não publica.Remova a capacidade do manifesto ou substitua-a por uma que esta compilação publique. A lista é propositalmente curta: uma permissão que ninguém publica é uma permissão sobre a qual o anfitrião não consegue raciocinar, por isso é rejeitada em vez de ignorada.
provider_unknown_load_kindUm pacote ofereceu algo que esta compilação não classifica. Rejeitado em vez de tratado como dados, porque errar na suposição aqui é errar na direção de sua execução.Compare o que o pacote oferece com os quatro tipos que esta compilação classifica: dados declarativos, uma cena empacotada, um script ou uma extensão nativa. Qualquer outra coisa é rejeitada em vez de adivinhada, porque adivinhar aqui significa adivinhar no sentido de realizá-la.
provider_untrustedO pacote está em um estado confiável que não carrega nada, que é o estado em que cada pacote começa.Nada para consertar em seu pacote e nada que um pacote possa consertar sozinho. A confiança está atrelada aos bytes exatos e é o jogador quem a dá, então instale o pacote de uma fonte de sua escolha e deixe-o confirmar; um resumo revogado não se torna confiável novamente ao ser detectado novamente.
provider_user_trust_requiredO nível permitiria isso e nem uma única pessoa disse sim a esse conteúdo exato ainda.Leve o jogador à lista de mods e deixe-o confirmar este pacote. O nível permitiria isso e ninguém ainda disse sim a esse conteúdo exato, que é a única etapa que uma assinatura deliberadamente não substitui.
quest_already_appliedUm comando que já foi executado.Nada para consertar. O comando já havia sido executado e não foi repetido, e é o que impede que uma recarga pague recompensa duas vezes.
quest_carries_expressionUm pacote que tenta fazer algo ou manter a resposta "única" para si.Remova o campo. O nível 1 são os dados: o que é executado pertence ao jogo e os novos recursos vêm de um fornecedor confiável.
quest_ending_unreachableUm final que ninguém pode alcançar.O final requer uma missão que seu arco não contém. Adicione a missão às etapas do arco, ou solicite uma que esteja lá.
quest_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
quest_nothing_appliedUm plano que rejeitou algo, então nada foi executado.Algo no conjunto foi rejeitado, então nada foi aplicado. Coloque quaisquer rejeições no relatório: uma reverência semi-aplicada é um estado que ninguém pode descrever.
quest_over_budgetUm pacote acima do teto declarado.O relatório imprime o que foi medido próximo ao que foi permitido. Divida o registro ou remova entradas além da linha: o teto é o que uma tela ou leitor pode conter, não uma sugestão.
quest_text_not_keyUma frase onde uma chave de catálogo é necessária.Mova a frase para o seu catálogo de idiomas e coloque sua chave no campo. Um campo que termina em _key contém uma chave; uma frase ali deixa seu pacote em um idioma para sempre.
quest_unfinishableUma missão que ninguém pode completar.Dê à missão pelo menos um objetivo não opcional, caso contrário ela será concluída no momento em que for aceita.
quest_unknown_stepUma meta ou concessão que esta construção não possui.O nome não está na lista publicada dessa tabela. Escolha um que esteja aí: a lista é curta porque cada entrada é algo que esta compilação já faz.
quest_unresolved_referenceUm registro nomeado que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
relationship_band_gapUm intervalo com um valor sem nome de banda.Cubra toda a gama da sua apólice, do chão ao telhado, sem furos e sem sobreposições, utilizando apenas os nomes das gamas publicados. Um valor em um buraco é um valor que nenhuma tela pode nomear.
relationship_carries_behaviour_codeUm pacote que tenta fornecer o que é executado quando um relatório é alterado.Remova o campo. O nível 1 são os dados: o que é executado pertence ao jogo e os novos recursos vêm de um fornecedor confiável.
relationship_declares_live_stateUm pacote que tenta dizer onde está um relacionamento agora.Em vez disso, declare o valor inicial. A situação atual de um relacionamento é uma questão de tempo de execução, e é o jogador que o moveu.
relationship_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
relationship_leave_unreachableUm companheiro que nunca pode partir, ou que sai imediatamente.Mover o limite de abandono para o intervalo da política. No chão você nunca pode perder seu parceiro; acima do telhado ele vai na primeira noite.
relationship_origin_lostO pacote que declarava título desapareceu e o valor evoluído permanece.Nada para consertar. O pacote que o declarava desapareceu e o que o jogador ganhou permanece; a identidade está lá para que ele saiba o que o traria de volta.
relationship_pair_collisionUm casal arrumado declarou duas vezes, saiu sem qualquer ligação.Dois registros reivindicam o mesmo par ordenado. Excluir um: manter ambos faria com que o pacote carregado primeiro vencesse.
relationship_unknown_relationUm tipo de relacionamento ou rota de recrutamento que esta construção não possui.Escolha um relacionamento na lista publicada. Uma que esta construção não tivesse seria reduzida a nada e a história que você escreveu não aconteceria.
relationship_unresolved_referenceUm registro nomeado que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
resolution_cache_invalidatedItens descartados porque seu fornecedor não está mais ativo.Nada para consertar. A composição mudou, então o que os ids resolvem foi recalculado em vez de reutilizado.
resolution_missingNinguém fornece a identificação e não há nada em que recorrer.Reinstale o pacote que forneceu o ID ou corrija o ID. O relatório o guarda para que você possa entender qual das duas coisas aconteceu.
resolution_over_budgetUm pacote ou processo acima de um orçamento declarado.O relatório imprime o que foi medido próximo ao que foi permitido. Divida o registro ou remova entradas além da linha: o teto é o que uma tela ou leitor pode conter, não uma sugestão.
resolution_refusedUma solicitação que esta compilação não faz.Leia a regra que o relatório menciona e altere o id para algo que o local aceite.
resolution_restart_requiredUma alteração de perfil cujos bytes antigos não podem ser baixados.O que esse ID resolve é alterado de uma forma que um jogo em execução não consegue acompanhar. Reinicie para obtê-lo.
resolution_tombstonedUm ID conhecido que um pacote removeu.Reinstale o pacote para retornar a marca para exclusão ao conteúdo verdadeiro. O id é resolvido em sua lápide em vez de nada, e é exatamente por isso que a reinstalação devolve ao jogador suas coisas.
save_campaign_absentA campanha sob a qual o salvamento foi feito não está instalada.Instale a campanha que o resgate nomeia. O resgate não se abre contra outro, porque seria silenciosamente outro mundo.
save_composition_matchesNada do que o resgate havia registrado se moveu.Nada para consertar. Os pacotes com os quais este salvamento foi feito são os pacotes instalados.
save_content_absentConteúdo cujos nomes salvos não estão instalados. Relatado, não fatal.Reinstale os pacotes listados no relatório. Os ids permanecem salvos, então o que agora não tem resposta receberá novamente.
save_orphan_state_carriedEstado sem titular instalado, transitado sem execução.Reinstale o pacote para fazer com que esse estado signifique algo novamente. Foi mantido em vez de removido precisamente para que funcionasse.
save_provider_contract_movedUma capacidade na qual o resgate dependia agora responde a um contrato diferente.Veja se o relatório diz migrado, ignorado ou rejeitado. A versão do contrato de um fornecedor mudou entre o salvamento e agora, e essas são as três respostas.
save_write_beside_originalA sessão gravou um novo arquivo e deixou o original como está.Nada para consertar. O salvamento recuperado foi escrito próximo ao original em vez de na parte superior - o modo de segurança nunca substitui o arquivo que não conseguiu abrir.
selection_campaign_missingA campanha solicitada não está instalada e nada foi composto em seu lugar.Instale o pacote que fornece o ID da campanha na mensagem ou inicie outra campanha. O id é o que foi solicitado, escrito como foi solicitado, então compare-o com o id no Campaign.json do pacote. Nada foi carregado em seu lugar: iniciar o jogo base lhe daria um mundo diferente com o nome que você escreveu.
selection_madeFoi selecionada uma campanha, com o motivo pelo qual o foi.Nada para consertar. É a fala que diz que mundo é esse jogo e por que foi escolhido, e vale a pena ler quando o mundo não é o que você esperava: a razão diz se ele foi solicitado, revivido ou o único instalado.
selection_safe_modeOs pacotes foram deixados de fora, seja após uma falha na inicialização ou porque o jogador os solicitou.Leia o motivo antes de mudar alguma coisa. player_asked significa que você escolheu e não há nada de errado com isso. boot_failed significa que a campanha falhou ao iniciar várias vezes: desative os mods instalados mais recentemente, inicie uma vez e coloque-os de volta um de cada vez. No modo de segurança nenhum pacote é composto, então uma correspondência que funciona aqui indica que a falha está em um pacote.
selection_save_preservedUm salvamento recuperado foi escrito ao lado do original em vez de acima.Nada para consertar e não exclua o segundo arquivo. A recuperação escreveu seu resultado próximo ao seu salvamento, em vez de acima, então a mensagem nomeia os dois caminhos: o original é aquele sem o sufixo .recovered e ainda está exatamente como estava.
setting_invalidA declaração não é aquela que esta construção desenharia.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
setting_migratedUm valor chegou em uma chave antiga e foi portado para a atual.Nada para consertar. A configuração mudou para sua forma atual e o valor antigo ficou para trás.
setting_owner_missingUm valor armazenado pertence a um pacote que não está instalado. Preservado, não aplicado.Nomeie um proprietário declarado para a configuração. Uma coisa que esta compilação não possui é uma configuração que ninguém jamais leria.
setting_restart_requiredO valor foi alterado e não poderá entrar em vigor até a próxima inicialização.Reinicie para aplicá-lo. A configuração não pode ser alterada enquanto o jogo está em execução.
setting_secret_withheldUm segredo foi excluído de um salvamento ou relatório.Nada para consertar. Um valor marcado como secreto foi deixado de fora do relatório, e é por isso que o relatório pode ser colado em um tópico de bug.
setting_value_refusedUm valor fora do que a declaração permite. O valor padrão responde em vez disso.Insira o valor dentro do intervalo impresso ao lado ou escolha um na lista publicada. O relatório mostra ambos.
settlement_building_unresolvedUm edifício salvo cujo pacote desapareceu, nomeado em vez de substituído.Reinstale o pacote mencionado na mensagem para recuperar o prédio, ou deixe-o como está: nada foi perdido. O edifício ainda está salvo com seu ID e deliberadamente não foi substituído pelo mais próximo que esta construção possui, o que colocaria os bens de outra pessoa dentro de uma forja que você nunca construiu.
settlement_carries_pathUm registro que nomeia uma cena, roteiro ou local próprio.Remova o campo e nomeie um ID. Um interior é o id de um registro interior, nunca o caminho de uma cena, e um edifício é colocado nomeando um objeto no mapa, em vez de carregar suas próprias coordenadas. Os campos de localização são rejeitados por esta segunda razão: um registro que contém uma coordenada é um registro que pode acabar sabe-se lá onde quando seu mapa não estiver mais lá.
settlement_invalidUm registro de liquidação que esta compilação não carrega.Leia o veredicto ao lado do código e corrija o registro que ele nomeia. As causas comuns são um campo obrigatório omitido, um id sem o namespace do seu pacote na frente e um campo que pertence a um dos outros cinco tipos de registro.
settlement_loot_table_absentUm contêiner cuja tabela de saque sumiu com o pacote, então ele está vazio em vez de ser retirado de outro.Reinstale o pacote que forneceu a tabela de saque se quiser que o contêiner seja preenchido novamente. Está vazio e não retirado de outra mesa, porque puxar entregaria as coisas de outro mundo sob o nome deste.
settlement_over_budgetMais edifícios ou serviços do que um assentamento pode conter.Retire uma parte do que a mensagem contava ou divida o acordo em dois. A contagem e o limite estão na mensagem, então a diferença é quantos devem sair.
settlement_text_not_keyUm campo mostrado na tela que contém uma frase em vez de uma chave de catálogo.Substitua a frase por uma chave de catálogo e coloque a frase na sua tabela de idiomas. Um nome escrito dentro do registro não pode ser traduzido e é visto em inglês em todos os idiomas.
settlement_unreachable_serviceServiço oferecido em um ancoradouro que o mapa não declara.Adicione a âncora à camada de âncoras do mapa com o ID que o serviço nomeia ou renomeie o serviço para um que esteja lá. O registro e o mapa são legítimos por si só, e o resultado é um contador que ninguém consegue resistir.
settlement_unresolved_referenceUm registro que nomeia algo que ninguém fornece.Adicione o registro nomeado ao seu pacote ou corrija o id. A mensagem nomeia o registro para o qual apontou e o ID para o qual apontou e, em seguida, compara-o com os IDs que você declarou.
society_dimension_leakDescobriu-se que uma dimensão da identidade leva a outra.Remova o campo que nomeia a outra dimensão. Uma cultura não tem um campo de fé: a derivação deve ser impossível de escrever e não simplesmente desaconselhável, para que nada possa dar a uma facção uma fé que ninguém escreveu.
society_heraldry_pathUm sinal que nomeia um arquivo em vez de um motivo.Uma insígnia heráldica chamada a. Em vez disso, cite um motivo: um sinal é escolhido entre aqueles que esta construção projeta.
society_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
society_mutation_in_definitionUma definição que pede que você faça algo.Remova o campo. Os adaptadores de definição descrevem; eles não têm autoridade para mudar o que descrevem.
society_relationship_collisionO mesmo par ordenado declarado duas vezes.Um par ordenado foi declarado duas vezes, portanto o par não tem posição. Excluir um - manter ambos faria o mundo depender de qual pacote foi carregado por último.
society_relationship_one_sidedUma posição cujo oposto ninguém declarou; o oposto é o valor padrão.Nada para consertar, se você quisesse. Apenas uma direção deste par é declarada, e o oposto não declarado é o padrão: uma facção que não sabe que tem um inimigo é uma premissa, e esta linha está aqui para ser uma premissa escolhida.
society_unresolved_referenceUm registro nomeado que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
state_namespace_ignoredO pacote não lê mais esse estado.Declare o namespace ou remova o estado. Chegou a um acordo que ninguém reivindica e foi deixado sozinho em vez de aplicado.
state_namespace_malformedUm namespace no salvamento não é um nome que esta compilação aceitaria.Escreva um namespace que identifique inequivocamente um pacote. Tudo o que está num resgate depende dele, então uma forma que não sabemos resolver é que então ninguém pode reivindicar.
state_namespace_orphanedNenhum pacote instalado tem esse status e foi enviado adiante.Reinstale o pacote para recuperar seu estado. O namespace pertence a um que desapareceu e o estado foi preservado em vez de excluído.
state_namespace_rejectedO pacote rejeitou o estado salvo para esta sessão.O pacote tentou escrever fora do namespace que possui. Escreva dentro do seu próprio: o estado de outro pacote não cabe a você mudar.
state_namespace_reservedUm pacote reivindicou um namespace que pertence ao host.O namespace é um dos convidados. Pegue aquele do seu pacote.
state_schema_futureFoi escrito a partir de uma versão de pacote mais recente do que esta compilação.Atualize o pacote. O estado salvo foi escrito por uma versão mais recente que a instalada e não pretendemos trazer um estado de volta.
state_schema_migratedEstado mais antigo da compilação, entregue ao pacote para transporte.Nada para consertar. Um estado mais antigo foi trazido à sua forma atual pela migração do próprio pacote.
state_schema_too_oldIndique mais antigo que o piso que a embalagem afirma ser capaz de ler.Veja qual resposta o relatório diz que o pacote escolheu. O estado é mais antigo que a forma mais antiga de onde o pacote migra, então ele decide o que fazer com ele.
state_write_outside_namespaceO escritor abordou um namespace que não é dele.Escreva dentro do seu namespace. Um pacote alterando o estado de outro é como um save deixa de pertencer a alguém.
strategic_carries_policyUm pacote que tenta fornecer a própria regra.Remova o campo. O nível 1 são os dados: o que é executado pertence ao jogo e os novos recursos vêm de um fornecedor confiável.
strategic_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
strategic_over_budgetUm pacote acima do teto declarado.O relatório imprime o que foi medido próximo ao que foi permitido. Divida o registro ou remova entradas além da linha: o teto é o que uma tela ou leitor pode conter, não uma sugestão.
strategic_text_not_keyUma frase onde uma chave de catálogo é necessária.Mova a frase para o seu catálogo de idiomas e coloque sua chave no campo. Um campo que termina em _key contém uma chave; uma frase ali deixa seu pacote em um idioma para sempre.
strategic_unknown_termUma consideração, uma intenção ou uma classe que esta construção não possui.A palavra não está na lista publicada para esse campo. Escolha uma que exista: sob uma palavra que não temos, nada responderia.
strategic_unresolved_referenceUm registro nomeado que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
strategic_weightlessUm planejador que decidia sempre da mesma maneira.Dê a pelo menos uma consideração um peso diferente de zero. Os pesos todos em zero dão a mesma pontuação para cada opção e escolhem sempre a primeira em ordem alfabética.
theme_carries_executableUm tema que nomeia uma cena, um roteiro ou um caminho de recurso.Remova o campo. Um tema descreve como você vê as coisas; um script dentro de um tema é um programa executado atrás de cada tela.
theme_contrast_too_lowUm par de cores abaixo da taxa de contraste mínima.Mova o primeiro plano ou o fundo até que a proporção exceda o mínimo impresso próximo a ele. É a única regra temática que um jogador ouve diretamente.
theme_refusedUm tema que esta build não registra.Leia a propriedade que o relatório nomeia e informe dentro do que ele permite.
tombstone_blocks_campaignA família declarada sem a qual a campanha não carrega.Essa família está carregando e falta o pacote, então a campanha não começa. Reinstale-o: sair sem ele seria um mundo sem algo que é mencionado em todos os lugares.
tombstone_placeholder_substitutedUm substituto possuído pelo motor responde em seu lugar.Reinstale o pacote para recuperar o conteúdo real. O relatório diz qual substituto foi usado nesse meio tempo.
tombstone_recordedUm id cujo pacote desapareceu foi registrado em vez de removido.Nada para consertar. Um pacote desaparece e seus ids são deixados no save, que é a única razão pela qual reinstalá-lo devolve ao jogador seus itens.
tombstone_reinstall_recoveredO pacote retornou e a lápide se transformou novamente em conteúdo real.Nada para consertar. O pacote está de volta e suas lápides se transformam em conteúdo real novamente.
tombstone_unresolved_referenceAlgo no save ainda aponta para um id reduzido a uma lápide.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
unit_carries_behaviour_codeUm pacote que tenta fornecer algum comportamento.Remova o campo. O nível 1 são os dados: o que é executado pertence ao jogo e os novos recursos vêm de um fornecedor confiável.
unit_incomplete_for_categoryUma unidade que carece do que sua categoria exige.Adicione a parte que a categoria exige. A tabela de categorias os lista: um companheiro precisa de equipamento, uma tropa precisa de comportamento e um líder nunca recorre a um.
unit_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
unit_unknown_behaviourUm perfil de comportamento que esta compilação não possui.Escolha um perfil de comportamento na lista publicada. Aquele que esta build não possui é rejeitado em vez de substituído por um padrão, porque um chefe que silenciosamente se tornou um andarilho é uma luta que não acontece.
unit_unresolved_referenceUm registro nomeado que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.
unit_visual_missingUm aspecto foi resolvido em sua substituição.O aspecto que você mencionou não é fornecido, então foi utilizado o substituto desse tipo. Traga o recurso ou aponte para um que exista.
world_calendar_inconsistentUm calendário ou uma festa que não pode acontecer.Coloque o casal que o relatório menciona. As estações, meses e feriados devem concordar, e aquele que não concorda é um calendário que o mundo lê de duas maneiras.
world_carries_clock_controlUm pacote que oferece seu próprio tempo.Remova o campo. Um pacote declara quanto vale uma temporada e não pode mover o relógio: o relógio canônico tem apenas um dono.
world_carries_randomnessUm pacote que fornece sua própria aleatoriedade.Remova a semente e nomeie um fluxo. A semente da correspondência pertence ao host e o fluxo segue a partir dele, portanto, um pacote que carrega sua própria semente é um mundo que ignora a correspondência em que se encontra.
world_invalidO registro não é aquele que esta compilação carregaria.Leia o veredicto ao lado do código. Nomeie a regra que o recorde quebrou e cada uma é um campo para remover, um campo para adicionar ou uma palavra para alterar.
world_unresolved_referenceUm registro nomeado que ninguém fornece.O id nomeado é aquele que nada na composição fornece. Ou você carrega o registro para o qual ele aponta ou depende do pacote que o carrega.

Limites, salvando, compartilhando

O que um mod nunca pode fazer

Rejeitado pela construção, não desanimado.

Sem códigoScripts, extensões, executáveis, arquivos shell — em qualquer lugar do seu pacote.
Sem cenas ou arquivos de recursosUm registro apontando para um é rejeitado mesmo que o arquivo não esteja lá.
Sem escurecimento dos arquivos baseUm mod adiciona e altera registros; ele não pode substituir arquivos do jogo.
Nenhum tipo novo de coisaUm novo privilégio sim, um novo tipo de privilégio não.
Sem comandos, carregamentos automáticos ou configurações de projetoNão é de todo acessível.
Sem cancelamentos reaisremove remove um registro de circulação e o deixa resolvível. Apenas vendor_inventories tira um.

A lista exata, por que uma recusa menciona isso:

  • Um arquivo de registro pode ter 4 MB, conter 4.096 registros e aninhar 16 níveis. O maior catálogo que o jogo traz contém algumas centenas deles, portanto, um arquivo que aciona um desses limites é malformado e não ambicioso.
  • Arquivos que seu pacote não pode conter, em nenhum lugar: .bat, .cmd, .dll, .dylib, .exe, .gd, .gdc, .gde, .gdextension, .ps1, .sh, .so, .vbs. Cada um deles é um comportamento: um script, uma biblioteca nativa ou algo que o host executaria.
  • Extensões para as quais um registro não pode apontar: .bat, .cmd, .dll, .dylib, .exe, .gd, .gdc, .gde, .gdextension, .ps1, .res, .scn, .sh, .so, .tres, .tscn, .vbs. É a lista acima mais cenas e recursos, porque um registro que nomeia alguém está pedindo ao jogo para construí-lo.
  • Chaves rejeitadas independentemente do que contenham: resource_local_to_scene, resource_path, scene, scene_path, script.
  • Caminhos rejeitados onde quer que apareçam: qualquer coisa que comece com res:// ou user://. Um registro direciona o conteúdo dentro de seu próprio pacote.

O tamanho também tem limites, por pacote e em todos eles, e exceder um nem sempre é uma rejeição:

  • ok Abaixo do limite. Nada é relatado.
  • aviso Além do limite suave e carregado da mesma forma. Aqueles que criam são avisados; o jogador não está parado.
  • degradar Acima do limite de tamanho que o hóspede pode reduzir em vez de rejeitar. É nomeado aquilo em que se baseia, porque um jogo que corre de forma diferente no silêncio é pior do que aquele que diz porquê.
  • rejeitar Cruzar a linha em uma dimensão que não possui uma versão menor de si mesma. O pacote não carrega e é nomeado.
TamanhoUm pacoteTodosSe ele superar isso
records20 000120 000reject
decoded_image_bytes256 MB1 GBreject
decoded_audio_bytes128 MB512 MBreject
map_cells4 194 3048 388 608reject
map_objects65 536262 144reject
effect_instances4 09616 384degrade
provider_frame_usec2 0008 000degrade
worker_tasks832reject
queue_depth5122 048degrade
teardown_msec100400warn

Uma revisão geral obtém o dobro desses números e uma conversão total quadruplica esses números. Quatro vezes, não ilimitado: Um limite que um pacote pode declarar não é um limite.

Somente a linha de remoção se move. Uma família aceita um remove quando consegue entregar o registro que está sendo retirado para o carregador; hoje dois fazem isso. Todo o resto nesta tabela é permanente.

Nenhuma camada de script está chegando. O manifesto carrega um tipo de pacote que envia comportamento em vez de dados: a única coisa que poderia autorizar sua execução o rejeita, não há sandbox por trás dele e um pacote que o declara foi rejeitado hoje. Projeto para dados.

Leia “dados” de forma ampla. Números são dados. Balanceamento são dados. O que uma arma faz, quanto custa um ferimento, por quanto uma mercadoria é vendida, como uma facção avalia uma decisão: tudo é seu. O que não são dados é uma mecânica que o jogo nunca teve – é um código que alguém escreve e testa. Se a sua ideia precisar, é um jogo diferente e não um mod.

Salva

Seus IDs vão parar no arquivo salvo do jogador. Um id publicado é uma promessa.

RegraPor que
Nunca renomeie um IDTodo resgate que o utilizou permanece encalhado. Adicione um novo e deixe o antigo em paz.
Desinstalar você nunca exclui as coisas de um jogadorSalvar mantém os IDs que não pode resolver e os sinaliza, portanto, a reinstalação retorna o cofre.
Aumente version toda vez que você mudar alguma coisaÉ o que um jogador pode ver.

Cada forma como um conjunto de pacotes pode ser diferente daquele em que foi salvo tem um nome, e cada nome decide uma coisa: se a sessão pode gravar naquele arquivo.

VeredictoEle pode escrever seu salvamentoO que isso significa
compatibleSimA composição corresponde àquela sob a qual foi feita a poupança.
degradedSimEntendi, com algum conteúdo nomeado ausente. O jogo continua e a ausência é comunicada.
incompatibleNão, o arquivo é deixado sozinhoA sessão não pode respeitar o que diz o salvamento. O arquivo original é deixado sozinho.
O que há de diferenteVeredictoO que isso significa
identical_compositioncompatibleMesmas embalagens, mesmas versões, mesma composição.
mod_addedcompatibleUm pacote do qual o resgate nunca soube nada. Nada do que ele gravou mudou.
mod_missingdegradedUm pacote cujo nome foi salvo não está instalado. Seus IDs ainda estão no arquivo e permanecem lá.
mod_upgraded_compatibledegradedUm pacote foi alterado, mas permaneceu dentro da compatibilidade reivindicada. Relatado porque um hash alterado é uma resposta alterada, mesmo quando é uma resposta legítima.
provider_contract_incompatibleincompatibleUma capacidade com a qual o resgate contava responde através de um fornecedor cujo contrato foi transferido. Seguir em frente seria adivinhar o que isso significa.
conversion_missingincompatibleA campanha em si está ausente. Cada id no arquivo pertence a um mundo que não está instalado.
safe_mode_disableddegradedA sessão começou com os pacotes desligados propositalmente. O salvamento é legível e seu conteúdo modificado está ausente por opção.
orphan_state_preserveddegradedO estado cujo pacote desapareceu passa intacto. Preservado, nunca executado.

Leia a linha incompatible duas vezes: o salvamento original é deixado de lado. Um arquivo sobrescrito por uma sessão que não o entendeu é um jogo perdido, e um jogador que perde um devido a um mod não instala outro.

Cada pacote carregado recebe uma impressão digital: o mesmo é feito para o mesmo manifesto e conteúdo, diferente quando o arquivo de conteúdo é alterado. O resumo do conjunto composto também inclui o ID, a versão, a ordem de carregamento e o resumo do conteúdo de cada pacote, portanto, os mesmos pacotes em uma ordem diferente não podem fingir ter a mesma composição. modding_fingerprint_report imprime esses valores e salva o esquema v56 registra a lista de impressões digitais ativas para que um carregamento posterior possa alertá-lo sobre um pacote ausente ou alterado. Aumentar seu version ainda é necessário porque é o valor que um jogador pode ver e comparar antes de instalar.

Compartilhe

Compacte a pasta em um zip. O formato de distribuição está todo aqui. Não há catálogo no jogo; coloque-o em Nexus Mods.

EtapaO que
VerificarLimpe o validador, com --strict, antes de carregar.
CEPA mesma pasta, portanto o arquivo contém my_mod/mod.json.
VersãoAumenta version para mod.json em cada carregamento.
RequisitosListe seu dependencies também na página do Nexus.
De'Quais famílias você toca e quais IDs você substitui com override.

Nunca altere o id do seu pacote. É o namespace que carrega cada um dos seus IDs, o que outro pacote nomeia como uma dependência e o que um save coloca por escrito. Renomeá-lo faz com que todos os salvamentos existentes acreditem que seu pacote foi desinstalado e outro apareceu ao lado dele. Em vez disso, altere o name exibido.

Diga às pessoas duas coisas e você economizará mais chamadas de suporte do que com qualquer outro: o game_version contra o qual você construiu e se você colocou canon_safe.

A versão a ser escrita hoje é 0.0.0-dev. É aquele ao qual esta compilação responde e é aquele que todos os exemplos nesta página indicam, e é um único número em vez de um intervalo: quando o jogo for lançado, ele mudará aqui primeiro.

Os arquivos têm limites, decididos pelo cabeçalho e não após a extração:

  • Máximo de 4.096 entradas, nenhuma maior que 16 MB e 128 MB extraídos no total.
  • Um nome pode ter 200 caracteres e 8 pastas de profundidade.
  • Nada pode se expandir mais de 200 vezes, o que nenhum conteúdo honesto consegue: o texto é compactado em torno de quinze. Alguns kilobytes extraídos em gigabytes são o ataque para o qual esse número existe.
  • Uma entrada que não seja um simples arquivo ou pasta é rejeitada: link simbólico, link físico, dispositivo, fifo, soquete. O link simbólico é o que importa, pois seu nome pode ser completamente comum e a seguir escreve para onde aponta.
  • Um arquivo dentro do seu arquivo é rejeitado em vez de medido (.7z, .bz2, .gz, .pck, .rar, .tar, .xz, .zip). O exterior declara até onde se espalham as suas vozes; não pode declarar até onde se estendem os de um interno.

Não há nenhuma loja para postar hoje, e esta é a forma do que estará lá. A distribuição agora é o zip e a página do Nexus acima: Nada do que se segue é um campo que você preenche para um upload que você pode fazer esta semana. Está aqui porque os campos já estão declarados na construção, então uma rota para uma loja é uma questão de conectá-los em vez de inventá-los, e porque um pacote escrito hoje não precisará ser reescrito para viajar dessa forma.

Um pacote que passa por uma loja carrega mais coisas do que a mochila:

O que isso trazCampos
Quem éstable_id, version
De onde vemauthor, license, source_url, package_hash
O que uma loja diz sobre issocontent_rating, content_warnings, revocation_status
Como foi entreguestore, store_id, subscription_id
EstadoEle instalaO que isso significa
noneSimNada foi relatado.
reportedSimAlguém denunciou e nada foi decidido. O jogador é notificado e escolhe.
quarantinedNãoRealizado enquanto se aguarda decisão. Ele não instala e o que já está instalado não é excluído.
revokedNãoRetirado. Ele não é instalado e uma cópia instalada é desativada em vez de removida, porque os jogos salvos do jogador ainda nomeiam seu conteúdo.

Os dois estados que bloqueiam uma instalação ainda não excluem nada.

O que uma nova compilação pode fazer ao seu pacote

game_version não é um ornamento. O jogo compara o que você construiu com o que é:

VeredictoO que isso significa para você
supportedA construção que você nomeou é esta ou próxima o suficiente. Nada para fazer.
older_buildVocê construiu contra um jogo mais antigo. Ele carrega de qualquer maneira, e a possível surpresa viria do que mudou nesse meio tempo.
newer_buildVocê construiu um jogo mais recente do que aquele que está executando. O pacote é nomeado dessa forma, em vez de carregado pela metade, na esperança de que tudo o que ele usa já exista.
unreadableO game_version que você escreveu não é uma versão. Isso é sempre um erro de digitação.

O que você faz a respeito depende do que mudou:

AulaO que isso significaO que o jogo deve a você
inalteradoNada que um pacote possa observar foi movido.nenhum
aditivoHá algo novo e tudo o que estava lá ainda significa o que costumava significar.um aumento menor
quebraUm pacote escrito na superfície antiga agora pode estar incorreto sem ter sido modificado.um aumento maior

Uma alteração conta como anulada por um destes motivos: field_removed, default_changed, type_changed, constraint_changed, required_added, operation_removed, root_changed, format_changed, id_field_changed, catalogue_changed, family_removed, contract_major_changed_without_new_id. default_changed é aquele que parece aditivo e não é. Um campo cujos movimentos padrão reescrevem o comportamento de cada pacote que nunca o mencionou e nenhum de seus autores mudou nada. constraint_changed cobre limites e enumerações, enquanto raiz, formato, campo de identificação, outros metadados de catálogo e alterações de remoção de família alteram onde ou se um pacote pode ser lido.

Um nome que está sendo descontinuado fica obsoleto antes de ser removido e continua funcionando por pelo menos 2 versões secundárias após a versão que o descontinuou.

Política, em quatro frases

Quem está decidindo se vai gastar cem horas em um pacote está apenas fazendo uma pergunta: o que acontece com ele quando o jogo é atualizado. Aqui está a resposta, antes de haver uma lista para ler.

SolicitarResponder
Meu pacote ainda será carregado?Sim, a menos que um lançamento esteja listado abaixo como quebrado, e nenhum lançamento esteja quebrado sem aparecer lá primeiro.
Os salvamentos dos jogadores sobreviverão?Sim. Uma sessão que não consegue entender um salvamento se recusa a gravar nele em vez de substituí-lo, e um salvamento mantém os ids que não consegue resolver em vez de descartar coisas. Salva.
Quanto aviso eu recebo?Um nome é descontinuado antes de ser removido e continua funcionando por pelo menos duas versões secundárias após a versão que o descontinuou.
Como vou saber?A linha vai parar na tabela abaixo, com o que foi movido e o que mudou, antes do lançamento ao qual pertence.

Lançamentos que quebram pacotes

LiberarDataO que quebraO que fazer
Ainda nada. Nenhum lançamento quebrou um pacote.

A tabela está vazia e não é um espaço reservado. Ela existe agora para que a primeira linha tenha um lugar para pousar e para que a promessa acima seja escrita antes de ser testada, e não depois. Uma linha aqui nomeia o lançamento, o dia em que foi lançado, exatamente de que forma ele deixou de ser aceito e a alteração que corrige um pacote — e não "mudanças diversas".

O trabalho recebido que quebraria algo vai para a mesma tabela, marcada como chegando, antes de sair.

Se o jogo não começar

Um perfil que não consegue iniciar é tentado novamente um número limitado de vezes, então o jogo oferece um caminho de volta em vez de tentar indefinidamente.

Um perfil é repetido 3 vezes. Depois disso, o jogo para de tentar e oferece um desses.

  • tentar novamente Abaixo do limite de novas tentativas. O mesmo perfil é tentado novamente.
  • last_known_good É oferecido um perfil que foi lançado no passado. Nada é desinstalado.
  • safe_mode Nenhum pacote é carregado para uma sessão. O perfil permanece intacto e retorna quando o jogador solicita.

Onde falhou informa o que procurar:

Onde falhouQual é o seu objetivo?
discoveryLeia o que está instalado. Uma falha aqui geralmente é um pacote malformado.
provider_startInicie aquele que a composição selecionou. Uma falha aqui nomeia uma habilidade.
first_sceneA primeira cena que o jogador veria. Uma falha aqui é o conteúdo, não a fiação.

Nada disso desinstala seu pacote ou altera seus arquivos. O modo de segurança é uma sessão sem pacotes carregados e seu perfil está esperando por você quando você o solicita.

Uma conversão total

Ainda não é um caminho publicado para criadores. A compilação entende o manifesto e traz consigo o acessório Ashen Reach; um fluxo de trabalho empacotado e público não está fora de questão. Trate o dispositivo como um contrato de engenharia, não como uma promessa de que você pode publicá-lo hoje.

É declarado com type: total_conversion. Em seguida, fallback_policy decide se uma conversão parcialmente instalada mostra o conteúdo do jogo ou nada.

SubstituiNão é possível adicionar
Os lugares, as pessoas, a guerra, os mitos, o mapa, os nomes de tudo. Seus reinos, seus deuses, sua própria economia.Um novo tipo de coisa. Uma espada que bate com mais força é um número; uma arma que dispara um feixe e precisa das regras do feixe é um recurso, e os recursos são um código.

O que muda e o que não muda

Quase nada muda. A pasta é a pasta, mod.json é mod.json, as famílias são as mesmas famílias com os mesmos campos, os ids têm namespace da mesma maneira, o validador aplica as mesmas regras e a tela Mod relata os mesmos estados. Cada tutorial nesta página é um tutorial para construir uma parte de uma conversão. A distância entre um pacote que adiciona um comerciante e um pacote que é um reino inteiro é um valor recorde, não uma habilidade diferente.

Três coisas realmente mudam e vale a pena conhecer todas as três antes de começar:

O queComo
O pôstertype: total_conversion, e ao lado fallback_policy, que é vanilla ou none e vale vanilla se você não escrever. vanilla significa que uma conversão meio instalada mostra o conteúdo do jogo onde o seu está faltando; none significa que não mostra nada.
OrçamentosQuatro vezes o perfil normal – e um perfil, não uma isenção. As palavras da própria compilação: «Quatro vezes, não ilimitado: um limite que pode ser declarado não é um limite.» Se total_conversion removesse os limites, ele se tornaria a linha que todo pacote escreve para escapar deles.
Palavras não traduzidas param de recorrer às do jogoNormalmente, uma chave ausente vai para player_locale, depois para o idioma padrão do seu pacote, depois para o catálogo de jogos e depois para a própria chave. Numa conversão total, esse terceiro passo é removido. Uma chave que você não escreveu é vista como chave e é relatada.

Esse terceiro passo parece uma perda e é o oposto. Old Seat que surge em um mundo que não tem Old Seat não é uma tradução ligeiramente errada: é o jogo básico que brilha por baixo do que você construiu em cima dele. Retirar o passo significa que uma lacuna em suas palavras é algo sobre o qual você foi informado, em vez de algo que um jogador encontra.

Para onde isso vai

Vale a pena dizer isso claramente, porque muda o que vale a pena aprender.

O motor do Bonemark foi construído para lidar com mais do que o Bonemark. O cenário são dados: os lugares, as pessoas, a economia, os mitos e as palavras para tudo isso são registros dos mesmos tipos que esta página descreveu. É por isso que o tipo de conversão completo existe no manifesto e é por isso que a compilação traz consigo uma segunda configuração como um acessório, e não como um teste de uma linha de código.

Portanto, a forma de longo prazo não é “adicionar uma espada”. É que quem aprende essas famílias está aprendendo a construir um mundo nesse motor, e a distância entre um pacote que agrega um comerciante e um pacote que é um reino inteiro é um valor recorde e não uma habilidade diferente.

Steam Workshop é a direção para levar pacotes aos jogadores, e é por isso que Compartilhe descreve os campos de uma loja que ainda não vende nada. Assinar um pacote em vez de extraí-lo muda a forma como ele chega e nada sobre como é escrito: a mesma pasta, o mesmo mod.json, os mesmos ids.

Nenhuma data, para nenhum deles, e nenhum segundo cenário nomeado: existe um como acessório de engenharia, que não é o mesmo que um anúncio anunciado. O que se diz aqui é um rumo e o que custa estar pronto: ou seja, que aquilo que você aprende hoje não deixará de ser aquilo quando a porta se abrir.

Possui um mod

As mesmas condições em que todas as cenas de modding se estabeleceram, porque são elas que funcionam. Não há nada de incomum aqui e nada de enigmático.

Seu mod é seuOs discos que você escreveu, as imagens que você desenhou, o som que você fez. Eles permanecem seus. Publicar um mod não dá a ninguém o direito ao seu trabalho.
O conteúdo do jogo continua sendo o jogoConsulte o que quiser - substitua um id, corrija um campo, vista um objeto. Não o retire, não o embale novamente ou carregue cópias dele na bolsa. Isso é principalmente para você: um pacote não pode ocultar os arquivos do jogo, então é difícil cruzar a linha por acidente.
Os direitos autorais não se movem em nenhuma direçãoÉ o nome legal para as duas linhas acima, e vale a pena dizer claramente porque é o que as pessoas consideram natural ao contrário. Publicar um pacote não entrega seu trabalho ao estúdio; instalar um não revela o jogo para você. Os direitos autorais dos discos que você escreveu e da arte que você fez são seus, e os discos, a arte, o som e o cenário do Bonemark permanecem com o estúdio. A conversão total é um caso que vale a pena deixar explícito: substituir a configuração que um jogador vê não licencia a configuração substituída e um pacote ainda não pode transportar os arquivos do jogo.
Mods são gratuitosSem vendas, sem barreiras de pagamento, sem acesso antecipado mediante pagamento, em qualquer loja ou plataforma. E nem são nossos para vender: a mesma regra vincula o estúdio.
Doações estão bemUm pote de gorjetas, um Patreon, uma página de agradecimento. É o suporte para uma pessoa, não o preço de um mod, e toda cena saudável permite isso.
O trabalho de outra pessoa requer permissão delaUm personagem, um som, um sprite, um conjunto de registros de outro pacote: pergunte e cite o autor onde o jogador possa lê-lo.
As traduções são permitidas por padrãoQualquer pessoa pode traduzir seu pacote e publicar a tradução, citando você. Diga em sua página se preferir ser questionado primeiro.
Reutilize as perguntas primeiroAproveitar o pacote de alguém, dar continuidade a um abandonado, pegar os registros dele e colocá-los nos seus: pergunte a ele. O silêncio não é um sim.

Porque o Grátis não é negociável. Mods pagos foram testados em larga escala e sempre foram retirados: no momento em que o dinheiro está envolvido, as discussões são sobre quem é o dono de qual ideia, e não sobre o que construir a seguir, e a cena compartilhada começa a se manter. Neste ecossistema todos estão no mesmo nível, e isso inclui aqueles que fizeram o jogo.

Uma coisa podemos pedir. Que um pacote seja removido, e apenas por motivos restritos: ele carrega arquivos do jogo, se faz passar por alguém ou contém material ilegal no local onde está hospedado. Não porque não concordamos com ele.

Decidido pelo estúdio em 14/08/2026. O texto aqui é política; um advogado irá lê-lo antes que o modding seja aberto publicamente, e se isso mudar alguma palavra, esta página muda com você.

Onde perguntar

Discord, e ainda não está aberto. É onde as perguntas sobre modding serão respondidas, e o convite não está escrito em lugar nenhum porque não há nada para convidar ninguém. A marca Discord na primeira página é enfadonha pelo mesmo motivo; o dia em que acender é o dia em que esta linha conterá o endereço.

Dizer «Discord» antes que o endereço exista vale mais do que não dizer nada: diz-lhe onde procurar e diz-lhe para não ir caçar num fórum que nunca foi aberto.

Enquanto isso, o que responde a quase todas as perguntas sem que ninguém se envolva é Antes de pedir ajuda a alguém: o bloco de comprovação nomeia a compilação, os pacotes, os estados e o motivo por trás de cada recusa, e quase tudo que uma pessoa responderia já está lá.

Revisado em comparação com a construção: 2026-08-16. Cada rótulo indica um estado, não uma promessa.Leia os rótulos →