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 jogo | Os 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 tela | No relatório | O que isso significa |
|---|---|---|
| Carregado | active | Carregável, sem obstáculos. |
| Inválido | invalid | O manifesto traz scripts bloqueados ou arquivos executáveis. |
| Requer outro mod | skipped_missing_dependency | Uma dependência declarada está ausente ou desabilitada. |
| Requer outro mod | skipped_incompatible_dependency | Uma dependência declarada está fora do seu alcance. |
| Ignorado | incompatible | O mod tem como alvo uma versão mais recente do jogo. |
| Conflitante | conflict | Dois mods carregáveis apontam para o mesmo ID de substituição (eles permanecem carregáveis; load_order vence, ambos relatados). |
| Desabilitado | disabled | Você desligou ou nunca ligou. Os pacotes são de escolha livre: colocar um na pasta instala e não liga. |
| Ligado — reinicie para carregar | — | Você ligou e ninguém leu ainda. Seu conteúdo não estará no jogo até você reiniciar. |
| Desligado – reinicie para baixar | — | Você 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 rejectedNove 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 que | Por que não | Isso vai mudar |
|---|---|---|
A família quests | Ele é 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 pacote | Descritores 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 pacote | Descritores 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 total | A 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 recurso | Decidido 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 feito | Uma 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.
| Palavra | O que isso significa |
|---|---|
| Pacote | Seu mod. Uma pasta com seu nome. |
| Manifesto | mod.json, no topo dessa pasta. Quem é você, o que você traz. |
| Registro | Uma coisa você adiciona. Uma espada é um recorde. |
| Família | Tipo de coisa. Espadas, capacetes e pão são todos items. Cada família tem sua própria pasta. |
| Eu ia | your_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ê quer | Vá para |
|---|---|
| Construindo algo do início ao fim | Comece pelo que você quer fazer — os seis tutoriais, apenas um pacote |
| Carregue um arquivo em dez minutos | Um mod em dez minutos |
| Pesquise campos para uma família e um exemplo | As famílias, uma por uma |
| Veja tudo o que você tem permissão para fazer | Toda família |
| Mudando algo que o jogo já traz consigo | Mudar o que o jogo já tem |
| Adicione sua própria arte, som, letras ou cor | Imagens, som, letras, cor |
| Desenhe um lugar no Tiled | Seus 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 erro | Cada código de diagnóstico |
| Saiba o que um mod nunca pode fazer | O que um mod nunca pode fazer |
| Não quebre o salvamento de alguém | Salva |
| Coloque-o onde as pessoas possam levá-lo | Compartilhe |
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á adicionando | As famílias que fazem isso | Onde estão escritos |
|---|---|---|
| Comércio e mercadorias | goods, vendor_inventories, caravans, recipes | Coisas, comércio e os números por trás de uma briga |
| Coisas que um jogador traz consigo | items, combat_balance | Coisas, comércio e os números por trás de uma briga |
| Pessoas | npc_definitions, mercenary_templates, noble_houses, relationships, perks, enemy_archetypes, enemy_variants, group_archetypes | Pessoas, casas e o que podem fazer |
| Lugares e edifícios | buildings, pois, maps, world_generation | O mundo e os lugares nele |
| Palavras que um jogador lê | locales, dialogue, scenes, lore, mr_lines, quest_plans, quest_metadata, progress | História, missões e as palavras que um jogador lê |
| Como parece e como soa | images, audio, fonts, themes, effects, presentation_bindings, screens | Como tudo parece e soa |
| Comandos e dificuldades | input_bindings, settings, adaptive | O que o jogador controla e o que assiste |
O que você precisa
| O jogo | Necessário | Sem Godot, sem compilador, sem etapas de construção. |
| Um editor de texto que entende JSON | Necessário | VS Code, Sublime, Notepad++ — tudo grátis. O Bloco de Notas do Windows funciona e não irá ajudá-lo. |
| Um editor de pixel art | Apenas pela sua arte | Aseprite (~20 €), ou grátis: LibreSprite, Piskel, Krita, GIMP. |
| Um editor de áudio | Apenas pelo seu som | Audacity. Efeitos curtos do nada: sfxr, ChipTone. |
| Ladrilhado | Somente para seus mapas | Livre. 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ê quer | Vá para | Quanto 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 consigo | Um item para carregar | 10 minutos, depois do acima |
| Adicione uma pessoa que vende | Um comerciante que o detém | 30 minutos |
| Adicione uma porta em um assentamento | O serviço de um edifício | 20 minutos |
| Adicione um lugar no mapa mundial | Um lugar no mapa | 20 minutos |
| Mudando algo que o jogo já possui | Mudando o que já existe | 15 minutos |
| Desenhe um mapa, escreva uma missão, traga arte | Seus mapas, Suas missões, Imagens, som, letras, cor | por 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 recurso | Ainda 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 teve | Nada 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á vendendo | Moedas | E |
|---|---|---|
| Argila, pedra, junco | 1 | o chão. Cavar ou cortar, não há trabalho dentro |
| Grão, madeira | 2 | |
| Vela | 3 | uma noite leve |
| Lã, peixe, uvas | 4 | |
| Pão | 6 | comida de um dia |
| Sal, mel, corda | 8 | |
| Pano (peça) | 10 | tecido com 2 lãs e 1 junco |
| Ferro refinado, peixe salgado | 12 | |
| Pimenta preta | 14 | uma importação, e você pode sentir isso |
| Couro, queijo | 15 | |
| Vinho | 25 | |
| Armas de uma mão | 50–300 | a banda, nem um único valor |
| Armas de duas mãos | 150–600 | |
| Prato pesado | 500–1500 | o 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.jsonComece 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"]
}
]| Campo | Por que esse valor |
|---|---|
id | O 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_name | O 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ê. |
category | MANUFACTURED, 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_tier | PRESERVED — 90 dias, como a vela do jogo. A cera é preservada; não é preservado para sempre. PERISHABLE dura 7 dias e ETERNAL nunca apodrece. |
base_price | 9. 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. |
weight | 0,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_class | Que profissão ela exerce? chandler é aquele que o pacote de referência usa. |
daily_consumption_class | Quem consome. household significa que as cidades o consomem constantemente e é isso que mantém o comerciante abastecido. |
tags | Palavras 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.jsonUma 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"]
}
]| Campo | Por que esse valor |
|---|---|
id | Sua 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. |
category | MATERIAL, que é a vela do jogo. Não CONSUMABLE: você não come nada. |
rarity | COMMON. Raridade é o que as mesas de saque e as lojas leem quando rolam; acontece uma coisa comum. |
weight | 0,4, como a mercadoria. Quando os dois não concordam, a mochila do jogador e a caravana não concordam no mesmo item. |
max_stack | 20, 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_value | 10 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.jsonEste é 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
}
]
}
]| Campo | Por que esse valor |
|---|---|
settlement_id | Use 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_id | Juntos 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_multiplier | 1,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_rate | 0,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_stock | 6. 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_days | 2, 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_standing | 0: Qualquer pessoa pode comprar. Acima de zero estão as ações que ela mantém para as pessoas de quem gosta. |
kind | Em 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.jsonVocê 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"
}
]| Campo | Por que esse valor |
|---|---|
label | As palavras na porta. Se você omitir, o jogo colocará seu id em maiúscula e será lido como um id. |
role | O 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. |
color | Cera 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_service | shop — 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.jsonAs 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
}
]| Campo | Por que esse valor |
|---|---|
kind | RUINS — 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_radius | 2.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_modifier | 0,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_loot | Falso: 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 fileDuas 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" }
]
}
]| Escolha | Por que |
|---|---|
patch, não replace | replace 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 → 4 | Uma 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 tags | A ú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ção | tags.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ê adicionou | Onde aparece | A captura |
|---|---|---|
goods | Em 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_inventories | O 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. |
items | Em 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_definitions | O 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. |
buildings | A 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. |
pois | No 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
| Campo | O que fa |
|---|---|
id | No exemplo acima. O nome do seu pacote. Deve corresponder exatamente à pasta e é a palavra antes dos dois pontos em cada ID que você escreve. |
name | No exemplo acima. O que um jogador vê. Letras maiúsculas e espaços são adequados aqui. |
version | No exemplo acima. Você escolhe. Aumente sempre que você mudar alguma coisa. |
game_version | No exemplo acima. A compilação para a qual você fez isso. |
content_types | No 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. |
dependencies | No exemplo acima. Os pacotes que você precisa. Um nome ou um objeto com optional: true. |
load_order | No exemplo acima. Quem vai primeiro quando dois pacotes tocam a mesma coisa. O mais baixo carrega primeiro. |
overrides | No 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_safe | No exemplo acima. Se o seu mod se encaixa na história do jogo. É você quem diz aos jogadores, não quem decide o jogo. |
roots | Uma 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_version | Que tipo de manifesto você está escrevendo. As operações Alterar o que o jogo já possui requerem 2. Esta compilação lê até 2. |
type | Que 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. |
capabilities | O 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_tier | Nã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. |
supersedes | Os 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_policy | Em que um pacote recorre quando algo que ele substitui está faltando. Um de vanilla, none. |
campaign | A campanha que uma conversão possui. |
campaign_package | Declare 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 questNomes 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.descriptionAs 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 isto | Língua | Cabeçalho da coluna | |
|---|---|---|---|
en | Inglês | en | o idioma de origem |
it | italiano | it | |
fr | Francês | fr | |
de | Alemão | de | |
es | Espanhol | es | |
pt-BR | Portuguê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| Regra | Por que |
|---|---|
| Cada chave cabe no seu namespace | northern_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 é rejeitada | Nã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 resposta | Ele é 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 dois | Um 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ê quer | Operação | O que você precisa |
|---|---|---|
| Adicione algo novo | add | Seu próprio id com seu próprio namespace. Nada mais. |
| Reescreva um dos registros do jogo | replace | O ID do registro listado em overrides. Um registro completo: não herda nada. |
| Mude um campo e deixe o resto em paz | patch | overrides, mais "manifest_version": 2 em mod.json. |
| Aposentar um recorde | remove | overrides, 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ção | O que fa | Requer | Recusar |
|---|---|---|---|
add | Forneça um registro novo e completo em seu namespace. | id com namespace | um ID que já existe, seja do jogo base ou de outro mod |
replace | Fornecer um registro completo para um id que já existe, tendo-o declarado. | substituir declarado, registro completo | um ID ausente do registro e um ID que o manifesto não lista em overrides |
patch | Altere os campos nomeados de um registro existente e deixe o resto como está. | substituição declarada, alterações | um id ausente no registro, um campo que a família não permite e qualquer forma de modificação fora de patch_operations |
remove | Retire um registro existente e deixe uma lápide em seu lugar. | substituição declarada, família removível | um 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
valueemfield, o que quer que estivesse lá antes. Está escrito comfieldevalue. - unset — Remove
fielddo registro, para que o leitor veja o valor padrão da família. Está escrito comfield. - append_unique — Adiciona
valueà lista emfieldse ainda não estiver lá. Está escrito comfieldevalue. - remove_value — Remove cada ocorrência de
valueda lista emfield. Está escrito comfieldevalue.
- 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 sobre | Decidido | Evidência | Valores |
|---|---|---|---|
packages | ao carregar | all_of, none_of | IDs de mod enviados ao lado do seu |
campaign | ao carregar | is, any_of, not_any_of | a campanha a partir da qual a partida começou |
locale | ao carregar | is, any_of, not_any_of | o idioma em que você está jogando |
season | enquanto joga | is, any_of, not_any_of | spring, summer, autumn, winter |
weather | enquanto joga | is, any_of, not_any_of | um id do clima que o jogo rolou |
day_phase | enquanto joga | is, any_of, not_any_of | dawn, day, dusk, night |
day | enquanto joga | at_least, at_most | quantos dias durou a partida |
| Julgamento | Leva | Verdadeiro quando |
|---|---|---|
is | um nome | a resposta é exatamente essa |
any_of | uma lista | a resposta é uma daquelas |
not_any_of | uma lista | a resposta é nenhuma dessas |
at_least | um número | a resposta é essa ou superior |
at_most | um número | a resposta é essa ou menor |
all_of | uma lista | eles estão todos lá |
none_of | uma lista | nã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 springUm 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ília | remove | O que acontece |
|---|---|---|
goods | Sim | Retirado. Ainda resolve o id, fora do que o jogo oferece. |
vendor_inventories | Sim | Cancelado. A linha é removida. |
| todo o resto | Não | Rejeitado, 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 confrontos | O que acontece |
|---|---|
| Campos diferentes do mesmo registro | Ambos se aplicam. Nada está perdido. |
| O mesmo campo simples | Vence 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 completo | O 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_value | Sem conflitos. Ambos dizem o que a lista deveria conter, não o que deveria ser. |
| Um pacote retira um registro, outro o altera ou substitui | A retirada permanece. A operação posterior é recusada, qualquer que seja a ordem de carregamento. |
| Dois pacotes que vestem o mesmo assunto | A ordem de carregamento vence posteriormente, o perdedor é nomeado no relatório. |
| Um pacote que envolve o conteúdo de outro pacote | Refused. |
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.
| Tipo | Arquivo | Instalado | O que isso significa |
|---|---|---|---|
image | .png, .webp | Sim | O arquivo é lido e a textura é construída. |
audio | .ogg, .wav | Não | Os 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, .otf | Não | Os 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ília | Pasta | Aceitar | Campos obrigatórios |
|---|---|---|---|
images | content/assets/images | .png, .webp | id, file, format |
audio | content/assets/audio | .ogg, .wav (descompactado) | id, file, codec, role |
fonts | content/assets/fonts | .ttf, .otf | id, file, format, sizes, covers, fallback_font |
themes | content/assets/themes | fichas de cor | id, tokens |
effects | content/assets/effects | modelos hospedeiros | id, 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
fileque contém..ou~, ou que começa com/,\,res://ouuser://, é 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ília | Campo | O que é |
|---|---|---|
items | icon_id | O ícone em um item que você carrega. |
npc_definitions | portrait_id | O retrato de um NPC com nome. |
perks | icon | O í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"
}
]| Slot | Você carrega | Onde aparece | alternative_key | Retirou |
|---|---|---|---|---|
portrait | image | O quadro do diálogo, para o id do locutor. | obrigatório | Sim |
sprite | image | Uma ficha de tropa, um terreno de mapa mundial ou uma construção em um assentamento. | — | Sim |
icon | image | Células de inventário, para qualquer item — seu ou do jogo. | obrigatório | Sim |
banner | image | As cores da casa na página de seu diário. | — | Sim |
voice | audio | Soa quando a linha do locutor aparece. | obrigatório | ainda não |
use_sound | audio | Soa quando um item é usado e o uso entra em vigor. | — | ainda não |
ambience | audio | Ele circula enquanto o jogador está naquele terreno. | — | ainda não |
theme | theme | Qual das suas paletas usa a interface. | — | Sim |
font | font | Qual dos seus personagens usa a interface. | — | ainda não |
effect | effect | Tempo 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.
| Papel | Para | Cursor |
|---|---|---|
music | Músicas | Música |
ambience | Salas, horas, lugares | Ambiente |
sfx | Efeitos curtos | Efeitos |
voice | Piadas faladas | Efeitos |
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 registro | Pixel 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. |
| Cavilhas | 16 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 interface | Os 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"
}
]| Regra | O que isso significa |
|---|---|
| O kit | Blocos de 16 pixels, ortogonais, canto inferior direito, finalizados. |
| Níveis são funções, não nomes | ground, collision e walkable são obrigatórios. Um nível denominado collisions é rejeitado em vez de ignorado. |
| A geometria se declara | A á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 namespace | northern_reach:towpath, não towpath. |
world_origin | Onde 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 nada | Uma disposição rejeitada não coloca absolutamente nada. |
| Sem rotas | Uma 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.
| Tipo | O que é |
|---|---|
arc | A história. Lista as missões que contém. |
quest | A tarefa: quem dá, como se chama, quanto paga. |
objective | Uma coisa que o jogador deve fazer. |
ending | Como 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"]
}
]| Objetivo | Assisti hoje |
|---|---|
collect_item | sim - você está carregando alguma coisa o suficiente |
defeat_unit | sim - você já matou o suficiente de alguma coisa |
earn_coin | sim - você tem dinheiro suficiente |
reach_place | sim - você visitou um assentamento |
survive_days | sim - dias suficientes se passaram |
speak_to, deliver_item, defend_place, escort_unit, learn_lore | não — rejeitado nominalmente em vez de aceito e nunca concluído |
| Recompensa | Entregue hoje |
|---|---|
give_item, receive_coin | Sim |
change_relation | sim, quando o assunto é o jogador |
| os outros cinco | recusou 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 umkind.kindindica qual dos quatro registros é esse. Uma recompensa escrita comkindé 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.
| Verificar | Leva | Ele pergunta | Respondido hoje |
|---|---|---|---|
companion_present | companion | Esse companheiro está lá para ouvir. | Sim |
faction_stance | faction, stance | Uma facção está onde a opção espera. | sim, para hostile — qualquer outro valor é rejeitado antes da primeira medida |
has_coin | coin | O jogador pode pagar. | Sim |
has_item | item, count | O jogador está carregando isso com ele. | Sim |
has_knowledge | lore | O jogador foi informado disso. | Sim |
has_trait | trait | O player foi construído assim. | Sim |
lacks_knowledge | lore | O jogador ainda não foi informado disso. | Sim |
quest_state | quest, state | Uma missão é onde a opção espera. | Sim |
relation_at_least | subject, target, regard | Um lado pensa pelo menos isso do outro. | Sim |
season | season | Estamos nessa parte do ano. | Sim |
time_of_day | phase | Estamos nessa parte do dia. | Sim |
| Comando | Leva | Atrás | Feito hoje |
|---|---|---|---|
change_relation | subject, target, delta | Altere uma reputação dentro das regras de relacionamento publicadas pelo host. | Sim |
give_item | item, count | Entregue algo. | Sim |
grant_knowledge | lore | Diz algo ao jogador. | Sim |
open_shop | vendor | Coloca os suprimentos de um comerciante na tela. | Sim |
pay_coin | coin | O jogador paga. | Sim |
receive_coin | coin | O jogador é pago. | Sim |
recruit_companion | companion | Adicione alguém ao grupo quando as regras de recrutamento publicadas pelo host permitirem. | Sim |
set_quest_state | quest, state | Leve 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_combat | encounter | Fecha a conversa. | Sim |
take_item | item, count | Isso tira alguma coisa. | Sim |
travel_to | destination | Mova 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_coinouhas_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" }
]
}
]| Piada | Leva | Tempos | Jogado hoje |
|---|---|---|---|
ask_name | prompt_key | a cena espera por ela | Sim |
end | — | a cena continua | Sim |
fade_in | seconds | a cena espera por ela | Sim |
fade_out | seconds | a cena espera por ela | Sim |
lock_player | — | a cena continua | Sim |
narrate | line_key, seconds | a cena espera por ela | Sim |
play_cue | cue | a cena continua | Sim |
remove_actor | actor | a cena continua | Sim |
say | actor, line_key | a cena espera por ela | Sim |
show_exit | — | a cena continua | Sim |
start_dialogue | graph | a cena espera por ela | Sim |
unlock_player | — | a cena continua | Sim |
wait | seconds | a cena espera por ela | Sim |
walk_to | actor, anchor | a cena espera por ela | Sim |
- 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.jsonO 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.
| # | Sintoma | O que o validador diz |
|---|---|---|
| 1 | O caminho da pasta está errado | WARN: 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. |
| 2 | O id não tem dois pontos | ERROR: add needs an id under your own namespace. frost_blade é rejeitado; northern_reach:frost_blade é aceito. |
| 3 | O JSON está quebrado | ERROR: 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. |
| 4 | O arquivo está no pacote errado | A 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. |
| 5 | Um campo obrigatório está faltando | O 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=1Um 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ília | Estado | Pasta em seu pacote | Comando de relatório | O que é |
|---|---|---|---|---|
adaptive | Pronto para usar | content/player/adaptive | modding_adaptive_report | Perfis que analisam o andamento de uma partida e sugerem uma abordagem diferente. |
audio | Validado, nada o consome ainda | content/assets/audio | modding_audio_report | 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. |
buildings | Pronto para usar | content/world/buildings | modding_building_report | Definições de edifícios e serviços do assentamento: rótulo, cor, função e interior reaproveitado. |
caravans | Pronto para usar | content/logistics/caravans | modding_caravan_report | 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. |
combat_balance | Pronto para usar | content/combat/balance | modding_combat_balance_report | Valores de equilíbrio de combate limitados que ajustam os parâmetros existentes do solucionador sem adicionar regras, operações ou mecânicas. |
dialogue | Pronto para usar | content/narrative/dialogue | modding_dialogue_report | Conversas como registros: o gráfico, suas piadas e as escolhas que nele constam. |
effects | Pronto para usar | content/assets/effects | modding_effect_report | Tempo, poeira, faíscas e luzes, compostas a partir dos modelos que o anfitrião disponibiliza. |
enemy_archetypes | Pronto para usar | content/threat/enemy_archetypes | modding_enemy_archetype_report | 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. |
enemy_variants | Pronto para usar | content/combat/enemy_variants | modding_enemy_variant_report | 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. |
fonts | Validado, nada o consome ainda | content/assets/fonts | modding_font_report | 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. |
goods | Pronto para usar | content/economy/goods | modding_goods_report | Bens comercializáveis e suas propriedades econômicas. |
group_archetypes | Pronto para usar | content/strategic/group_archetypes | modding_group_archetype_report | 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. |
images | Pronto para usar | content/assets/images | modding_image_report | 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. |
input_bindings | Pronto para usar | content/input | modding_input_report | Ações próprias de um pacote, com a chave que desejarem. |
items | Pronto para usar | content/inventory/items | modding_items_report | Itens de inventário, incluindo armas e armaduras. |
locales | Pronto para usar | content/locale | modding_locale_report | 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. |
lore | Pronto para usar | content/narrative/lore | modding_lore_report | Entradas do Codex: lugares, pessoas, eventos, costumes e coisas sobre as quais um mundo conta histórias. |
maps | Pronto para usar | content/world/maps | modding_map_report | 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. |
mercenary_templates | Pronto para usar | content/character/mercenaries | modding_mercenary_report | 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. |
mr_lines | Pronto para usar | content/medieval_realism/structured | modding_mr_lines_report | Linhas estruturadas de realismo medieval, roteadas por arquivo e id de linha em vez de um campo de id no JSON. |
noble_houses | Pronto para usar | content/politics/noble_houses | modding_noble_house_report | Dados iniciais de uma casa nobre: o senhor, o herdeiro, cujos assentamentos respondem à casa, e quem conta como rival ou aliado. |
npc_definitions | Pronto para usar | content/narrative/npcs | modding_npc_report | Definições de NPCs Nomeados. |
perks | Pronto para usar | content/character/perks | modding_perk_report | Privilégios declarativos: gatilhos e efeitos, sem nenhum manipulador escrito em código. |
pois | Pronto para usar | content/world/pois | modding_poi_report | Pontos de interesse colocados por coordenadas no mapa mundial manuscrito. |
presentation_bindings | Pronto para usar | content/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. |
progress | Pronto para usar | content/player/progress | - | Registros de progressão do jogador: objetivos, perfis de dificuldade seguros e perfis de partida dentro das regras do anfitrião. |
quest_metadata | Pronto para usar | content/narrative/quest_metadata | modding_quest_metadata_report | Registros de metadados da missão, indexados por quest_id em vez de id. |
quest_plans | Pronto para usar | content/narrative/quest_plans | modding_quest_plan_report | 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. |
quests | Verificado, ainda não instalado | content/narrative/quests | - | Recursos de missão manuscritos, carregados por rota em vez de interpretados como registros. |
recipes | Pronto para usar | content/economy/recipes | - | Receitas artesanais: o que se consome, o que sai, onde é feito, quanto custa e qual a probabilidade de estragar. |
relationships | Pronto para usar | content/companion/relationships | - | Padrões de parceiros, políticas de relacionamento limitado, condições de recrutamento e títulos declarativos. |
scenes | Pronto para usar | content/narrative/scenes | modding_scene_report | Cenas encenadas: a sala, quem está nela e as falas que se desdobram em ordem. |
screens | Pronto para usar | content/ui/screens | modding_screen_report | Layouts de tela: quais seções cabem em qual painel da tela o jogo já possui e em que ordem. |
settings | Pronto para usar | content/settings | modding_settings_report | Opções que um jogador pode alterar, declaradas em vez de sorteadas. |
themes | Pronto para usar | content/assets/themes | modding_theme_report | Paletas de interface como tokens: cores, tamanhos e espaçamentos nomeados, com pares cujo contraste o jogador deve ser capaz de ler. |
vendor_inventories | Pronto para usar | content/world/vendor_inventories | modding_vendor_inventory_report | Tabelas de abastecimento do comerciante. |
world_generation | Pronto para usar | content/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:
| Seria | Para onde iria | O que é |
|---|---|---|
feature_extension | ainda não há pasta | Um 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ê:
| Responder | O que o resgate faz |
|---|---|
preserve_inert_reference | O id permanece, não resolve nada e é relatado. Aquele que o jogador tinha ainda tem nome. |
substitute_placeholder | Um substituto estável pertencente ao mecanismo responde, então o mundo carrega de qualquer maneira e o ID original é mantido por perto. |
drop_optional_presentation | A 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
role | Sim | corda |
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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
origin_settlement_id | Sim | corda |
destination_settlement_id | Sim | corda |
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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
file | Sim | texto, fixed shape |
name_key | Sim | corda |
world_origin | Sim | lista 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
display_name | Sim | corda |
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_reportcuida 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.
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | qualquer um |
id | Sim | texto, id |
stream | Sim | texto, id |
tables | Sim | objeto |
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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
archetype_id | Sim | corda |
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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
display_name | Sim | corda |
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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
display_name | Sim | corda |
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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
skill | Sim | texto, fixed shape |
name_key | Sim | corda |
kind | Sim | road, junction, lateral, capstone |
col | Sim | inteiro de 0 a 4 |
row | Sim | inteiro de 1 a 7 |
level | Sim | inteiro 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_reportcuida 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:
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
kind | Sim | bond |
relation | Sim | corda |
subject | Sim | corda |
target | Sim | corda |
initial_regard | Sim | inteiro de -100 a 100 |
policy | Sim | corda |
description_key | - | corda |
name_key | - | corda |
note_key | - | corda |
Um registro com kind: companion_template:
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
kind | Sim | companion_template |
unit | Sim | corda |
recruit | Sim | corda |
loyalty | Sim | corda |
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:
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
kind | Sim | recruit_terms |
means | Sim | corda |
cost | - | inteiro de 0 a 1.000.000 |
description_key | - | corda |
name_key | - | corda |
requires_bond | - | corda |
Um registro com kind: relationship_policy:
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
kind | Sim | relationship_policy |
relation_kinds | Sim | lista de cordas |
bounds | Sim | objeto |
bands | Sim | lista 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
values | Sim | objeto |
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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, 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_reportcuida 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
inputs | Sim | objeto |
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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
display_name | Sim | corda |
entries | Sim | lista 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:
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | dialogue_graph |
id | Sim | corda |
entry | Sim | corda |
description_key | - | texto, fixed shape |
name_key | - | texto, fixed shape |
speaker | - | corda |
Um registro com kind: dialogue_node:
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | dialogue_node |
id | Sim | corda |
graph | Sim | qualquer um |
voice | Sim | line |
speaker | Sim | corda |
line_key | Sim | qualquer um |
conditions | - | qualquer um |
description_key | - | qualquer um |
name_key | - | qualquer um |
reveals | - | qualquer um |
Um registro com kind: dialogue_node:
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | dialogue_node |
id | Sim | corda |
graph | Sim | qualquer um |
voice | Sim | narration |
line_key | Sim | qualquer um |
conditions | - | qualquer um |
description_key | - | qualquer um |
name_key | - | qualquer um |
reveals | - | qualquer um |
Um registro com kind: dialogue_node:
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | dialogue_node |
id | Sim | corda |
graph | Sim | qualquer um |
voice | Sim | end |
conditions | - | qualquer um |
description_key | - | qualquer um |
line_key | - | qualquer um |
name_key | - | qualquer um |
reveals | - | qualquer um |
Um registro com kind: dialogue_option:
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | dialogue_option |
id | Sim | corda |
node | Sim | corda |
label_key | Sim | texto, fixed shape |
goto | Sim | corda |
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.
| Coluna | Necessário | Valores |
|---|---|---|
key | Sim | texto, 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 Brinalore
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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
category | Sim | place, person, event, custom, thing |
title_key | Sim | corda |
body_key | Sim | corda |
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.
| Coluna | Necessário | Valores |
|---|---|---|
line_id | Sim | texto, 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_onlyprogress
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_reportcuida 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:
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
kind | Sim | achievement |
name_key | Sim | corda |
description_key | Sim | corda |
condition | Sim | lista de objetos |
campaign | - | corda |
hidden | - | booleano |
icon | - | banner, blade, coin, crown, hand, road,… |
Um registro com kind: difficulty_profile:
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
kind | Sim | difficulty_profile |
name_key | Sim | corda |
modifiers | Sim | objeto |
campaign | - | corda |
description_key | - | corda |
permadeath | - | booleano |
Um registro com kind: run_profile:
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
kind | Sim | run_profile |
name_key | Sim | corda |
difficulty | Sim | corda |
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.
| Campo | Necessário | Valores |
|---|---|---|
quest_id | Sim | texto, 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:
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | qualquer um |
id | Sim | texto, id |
stages | Sim | lista |
description_key | - | texto, fixed shape |
name_key | - | texto, fixed shape |
Um registro com kind: ending:
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | qualquer um |
id | Sim | texto, id |
arc | Sim | corda |
requires | Sim | lista |
description_key | - | texto, fixed shape |
epilogue_key | - | texto, fixed shape |
name_key | - | texto, fixed shape |
Um registro com kind: objective:
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | qualquer um |
id | Sim | texto, id |
quest | Sim | corda |
goal | Sim | collect_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:
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | qualquer um |
id | Sim | texto, id |
name_key | Sim | texto, fixed shape |
giver | Sim | corda |
objectives | Sim | lista |
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_reportcuida 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
beats | Sim | lista 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
file | Sim | texto, fixed shape |
codec | Sim | ogg, wav |
role | Sim | music, 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
template | Sim | dust_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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
file | Sim | texto, fixed shape |
format | Sim | ttf, otf |
sizes | Sim | lista de inteiros de 8 a 96 |
covers | Sim | lista |
fallback_font | Sim | corda |
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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
file | Sim | texto, fixed shape |
format | Sim | png, 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_reportcuida 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
subject | Sim | texto, id |
kind | Sim | building, faction, interface, item, region, tile,… |
slot | Sim | ambience, banner, effect, font, icon, portrait,… |
cue | Sim | texto, 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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
screen | Sim | character_sheet |
panels | Sim | objeto |
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.
| Campo | Necessário | Valores |
|---|---|---|
id | Sim | texto, id |
tokens | Sim | objeto |
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:
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | qualquer um |
id | Sim | texto, id |
name_key | Sim | texto, fixed shape |
policy | Sim | enemy_composition, event_cadence, hint_frequency, pace_economy, pace_encounters, weather_variety |
reads | Sim | lista |
fallback_policy | Sim | enemy_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:
| Campo | Necessário | Valores |
|---|---|---|
kind | Sim | qualquer um |
id | Sim | texto, id |
profile | Sim | texto, id |
thresholds | Sim | lista 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.
| Campo | Necessário | Valores |
|---|---|---|
action_id | Sim | texto, id |
label_key | Sim | corda |
context | Sim | exploration, combat, menu, global |
suggested_keyboard | Sim | corda |
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.
| Campo | Necessário | Valores |
|---|---|---|
key | Sim | texto, id |
type | Sim | bool, int, float, string, enum |
default | Sim | qualquer um |
scope | Sim | installation, campaign, presentation |
label_key | Sim | corda |
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.
| Comando | A mesma coisa na tela do Mod |
|---|---|
modding_open_folder | o caminho na parte superior e o botão próximo a ele |
modding_manifest_report | a coluna de status e a linha abaixo de cada linha |
modding_<family>_report | as contagens em cada pacote e Mostrar detalhes |
modding_preflight_report | Verifique a compatibilidade |
modding_roots_report, modding_safety_report | Copiar o relatório |
modding_reload | Sem 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 loadmodding_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.
| Comando | O que isso te diz |
|---|---|
modding_roots_report | Raízes e pegadas de mods de dados |
modding_manifest_report | Estados de modificação (ativo/inválido/ignorado/conflitante) |
modding_fingerprint_report | Pegadas determinísticas de salvamentos (save_wired=no) |
modding_safety_report | Postura segura (mods de comportamento desativados, arquivos bloqueados) |
modding_preflight_report | Veredicto VERDE/VERMELHO em todos os mods ativos |
modding_packaging_report | Detecção PCK/ZIP de nível 2 (desativada por padrão) |
modding_campaign_report | Modding_campaign_report [id] - campanhas instaladas somente leitura; com um id, você vai lá |
modding_condition_report | O que o mundo publica para condições recordes |
modding_reload | Modding_reload [all] - releia os pacotes; all somente se não houver jogo em andamento |
modding_binding_report | Links de envio: vinculados/rejeitados/substituídos |
modding_open_folder | Cria (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 itemsEle 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" --jsonA 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-baselineEsta é 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>" --jsonLê 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-runtimeO 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ódigo | O que causou isso | O que fazer |
|---|---|---|
adaptive_brings_a_model | Um 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_back | Um 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_invalid | O 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_budget | Um 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_key | Uma 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_step | Uma 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_reference | Um 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_reference | Uma 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_leaked | A 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_aspect | Uma 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_budget | A 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_refused | Nada 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_affordance | Um 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_invalid | Existe 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_mismatch | O 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_missing | O 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_missing | Nenhum 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_refused | Um 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_used | Um 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_refused | Um 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_overran | Um 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_invalid | Uma 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_alternative | Informaçã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_budget | Enviar 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_used | Um 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_recorded | Uma 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_offered | Em 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_unwritable | A 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_rejected | Um 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_offered | Abaixo 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_offered | O 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_exceeded | O 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_degraded | Uma 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_exceeded | Um 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_warning | Alé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_dimension | Houve 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_profile | Um 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_identity | Um 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_invalid | A 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_found | Uma 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_handler | Dados 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_invalid | O 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_missing | Um 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_unenterable | Um 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_property | Uma 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_formula | Um 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_expired | Um 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_invalid | O 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_budget | Um 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_unreachable | Uma 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_operation | Uma 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_status | Um 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_reference | Um 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_reference | Um 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_allowed | Uma 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_unclassified | Existe 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_file | Um 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_family | Uma 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_missing | Ausente 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_family | Uma 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_family | A 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_leak | Um 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_expression | Um 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_end | Uma 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_invalid | O 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_node | Um 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_budget | Um 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_key | Uma 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_reveal | Um 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_step | Um 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_reference | Um 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_mismatch | Os 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_invalid | O 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_offline | A 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_reported | Algué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_revoked | O 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_deferred | Há 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_refused | Um 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_invalid | O 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_bounds | Um 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_overridden | Um 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_reference | Uma 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_source | Um 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_degraded | Um 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_dropped | Um 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_refused | Um 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_field | O 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_namespace | O 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_field | Falta 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_incomplete | A 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_unbounded | Falta 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_capability | A 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_autoload | O 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_fallback | Um 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_refused | Um 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_refused | Um 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_grid | Uma 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_mismatch | Bytes 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_used | Uma 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_refused | Uma 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_cancelled | Uma 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_mismatch | Os 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_field | A 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_refused | A 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_field | Falta 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_rejected | A 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_unbounded | Falta 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_format | O 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_platform | O 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_conflict | A 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_orphaned | Uma 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_action | Um 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_field | A 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_namespace | O 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_unreachable | A 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_field | Uma 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_chord | Um 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_context | O 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_invalid | O 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_definition | Um 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_replaced | Um 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_reference | Um 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_text | Texto 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_data | Uma 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_path | Um 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_anchor | Dois 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_invalid | O 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_mismatch | Um 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_missing | Um 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_failed | O 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_package | Um 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_budget | Um 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_reference | Um 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_subset | Algo 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_surface | Um 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_collision | Uma 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_failed | Ele 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_vanilla | Uma 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_required | O 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_invalid | O 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_lost | Uma 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_budget | Um 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_outside | Um 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_namespace | Um 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_key | Uma 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_step | Uma 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_reference | Um 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_capability | Um 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_refused | Uma 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_inactive | A 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_capability | Um 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_kind | Um 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_untrusted | O 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_required | O 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_applied | Um 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_expression | Um 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_unreachable | Um 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_invalid | O 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_applied | Um 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_budget | Um 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_key | Uma 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_unfinishable | Uma 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_step | Uma 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_reference | Um 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_gap | Um 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_code | Um 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_state | Um 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_invalid | O 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_unreachable | Um 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_lost | O 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_collision | Um 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_relation | Um 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_reference | Um 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_invalidated | Itens 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_missing | Ningué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_budget | Um 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_refused | Uma 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_required | Uma 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_tombstoned | Um 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_absent | A 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_matches | Nada 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_absent | Conteú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_carried | Estado 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_moved | Uma 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_original | A 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_missing | A 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_made | Foi 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_mode | Os 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_preserved | Um 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_invalid | A 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_migrated | Um 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_missing | Um 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_required | O 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_withheld | Um 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_refused | Um 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_unresolved | Um 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_path | Um 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_invalid | Um 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_absent | Um 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_budget | Mais 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_key | Um 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_service | Serviç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_reference | Um 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_leak | Descobriu-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_path | Um 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_invalid | O 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_definition | Uma 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_collision | O 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_sided | Uma 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_reference | Um 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_ignored | O 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_malformed | Um 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_orphaned | Nenhum 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_rejected | O 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_reserved | Um pacote reivindicou um namespace que pertence ao host. | O namespace é um dos convidados. Pegue aquele do seu pacote. |
state_schema_future | Foi 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_migrated | Estado 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_old | Indique 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_namespace | O 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_policy | Um 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_invalid | O 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_budget | Um 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_key | Uma 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_term | Uma 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_reference | Um 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_weightless | Um 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_executable | Um 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_low | Um 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_refused | Um tema que esta build não registra. | Leia a propriedade que o relatório nomeia e informe dentro do que ele permite. |
tombstone_blocks_campaign | A 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_substituted | Um 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_recorded | Um 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_recovered | O 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_reference | Algo 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_code | Um 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_category | Uma 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_invalid | O 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_behaviour | Um 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_reference | Um 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_missing | Um 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_inconsistent | Um 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_control | Um 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_randomness | Um 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_invalid | O 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_reference | Um 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ódigo | Scripts, extensões, executáveis, arquivos shell — em qualquer lugar do seu pacote. |
| Sem cenas ou arquivos de recursos | Um registro apontando para um é rejeitado mesmo que o arquivo não esteja lá. |
| Sem escurecimento dos arquivos base | Um mod adiciona e altera registros; ele não pode substituir arquivos do jogo. |
| Nenhum tipo novo de coisa | Um novo privilégio sim, um novo tipo de privilégio não. |
| Sem comandos, carregamentos automáticos ou configurações de projeto | Não é de todo acessível. |
| Sem cancelamentos reais | remove 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://ouuser://. 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.
| Tamanho | Um pacote | Todos | Se ele superar isso |
|---|---|---|---|
records | 20 000 | 120 000 | reject |
decoded_image_bytes | 256 MB | 1 GB | reject |
decoded_audio_bytes | 128 MB | 512 MB | reject |
map_cells | 4 194 304 | 8 388 608 | reject |
map_objects | 65 536 | 262 144 | reject |
effect_instances | 4 096 | 16 384 | degrade |
provider_frame_usec | 2 000 | 8 000 | degrade |
worker_tasks | 8 | 32 | reject |
queue_depth | 512 | 2 048 | degrade |
teardown_msec | 100 | 400 | warn |
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.
| Regra | Por que |
|---|---|
| Nunca renomeie um ID | Todo resgate que o utilizou permanece encalhado. Adicione um novo e deixe o antigo em paz. |
| Desinstalar você nunca exclui as coisas de um jogador | Salvar 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.
| Veredicto | Ele pode escrever seu salvamento | O que isso significa |
|---|---|---|
compatible | Sim | A composição corresponde àquela sob a qual foi feita a poupança. |
degraded | Sim | Entendi, com algum conteúdo nomeado ausente. O jogo continua e a ausência é comunicada. |
incompatible | Não, o arquivo é deixado sozinho | A sessão não pode respeitar o que diz o salvamento. O arquivo original é deixado sozinho. |
| O que há de diferente | Veredicto | O que isso significa |
|---|---|---|
identical_composition | compatible | Mesmas embalagens, mesmas versões, mesma composição. |
mod_added | compatible | Um pacote do qual o resgate nunca soube nada. Nada do que ele gravou mudou. |
mod_missing | degraded | Um pacote cujo nome foi salvo não está instalado. Seus IDs ainda estão no arquivo e permanecem lá. |
mod_upgraded_compatible | degraded | Um 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_incompatible | incompatible | Uma 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_missing | incompatible | A campanha em si está ausente. Cada id no arquivo pertence a um mundo que não está instalado. |
safe_mode_disabled | degraded | A 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_preserved | degraded | O 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.
| Etapa | O que |
|---|---|
| Verificar | Limpe o validador, com --strict, antes de carregar. |
| CEP | A mesma pasta, portanto o arquivo contém my_mod/mod.json. |
| Versão | Aumenta version para mod.json em cada carregamento. |
| Requisitos | Liste 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 traz | Campos |
|---|---|
| Quem é | stable_id, version |
| De onde vem | author, license, source_url, package_hash |
| O que uma loja diz sobre isso | content_rating, content_warnings, revocation_status |
| Como foi entregue | store, store_id, subscription_id |
| Estado | Ele instala | O que isso significa |
|---|---|---|
none | Sim | Nada foi relatado. |
reported | Sim | Alguém denunciou e nada foi decidido. O jogador é notificado e escolhe. |
quarantined | Não | Realizado enquanto se aguarda decisão. Ele não instala e o que já está instalado não é excluído. |
revoked | Não | Retirado. 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 é:
| Veredicto | O que isso significa para você |
|---|---|
supported | A construção que você nomeou é esta ou próxima o suficiente. Nada para fazer. |
older_build | Você construiu contra um jogo mais antigo. Ele carrega de qualquer maneira, e a possível surpresa viria do que mudou nesse meio tempo. |
newer_build | Você 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. |
unreadable | O 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:
| Aula | O que isso significa | O que o jogo deve a você |
|---|---|---|
| inalterado | Nada que um pacote possa observar foi movido. | nenhum |
| aditivo | Há algo novo e tudo o que estava lá ainda significa o que costumava significar. | um aumento menor |
| quebra | Um 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.
| Solicitar | Responder |
|---|---|
| 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
| Liberar | Data | O que quebra | O 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 falhou | Qual é o seu objetivo? |
|---|---|
discovery | Leia o que está instalado. Uma falha aqui geralmente é um pacote malformado. |
provider_start | Inicie aquele que a composição selecionou. Uma falha aqui nomeia uma habilidade. |
first_scene | A 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.
| Substitui | Nã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 que | Como |
|---|---|
| O pôster | type: 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çamentos | Quatro 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 jogo | Normalmente, 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 é seu | Os 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 jogo | Consulte 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 gratuitos | Sem 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 bem | Um 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 dela | Um 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ão | Qualquer 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 primeiro | Aproveitar 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á.