Um pack de mods é um simples banco SQLite. O editor de mods é o jeito confortável de escrever um, mas nada impede você de abrir o arquivo por conta própria — e para certos trabalhos esse é de longe o caminho mais rápido:
- importar uma temporada real de uma planilha ou de um CSV;
- renomear quarenta patrocinadores, ou aumentar em 10 % o salário de cada piloto;
- gerar um pack a partir de um script, para refazê-lo sempre que os dados de origem mudarem;
- ler o pack de outra pessoa para ver como ela fez.
Esta página é a referência para isso. Ela documenta o que o jogo realmente lê — coluna por coluna — e as regras que segue. Nada aqui é detalhe interno: o carregador é deliberadamente tolerante, e saber o quanto ele é é justamente o que permite escrever um pack à mão com confiança.
Você nunca precisa desta página para fazer um mod. O editor de mods escreve todas as tabelas descritas aqui, confere seu trabalho e atualiza packs antigos. Recorra ao SQL quando quiser alterações em massa ou geração por script.
Abrir um pack
Qualquer ferramenta SQLite serve — o arquivo não tem cabeçalho próprio, nem compressão, nem criptografia.
Gráfico — o DB Browser for SQLite é gratuito, roda em Windows, macOS e Linux, e edita tabelas como uma planilha. É a entrada mais suave se você nunca escreveu SQL: abra o arquivo, vá em Navegar dados, escolha uma tabela e digite. Lembre-se de Gravar alterações antes de fechar.
Linha de comando — o sqlite3 vem com o macOS e com a maioria das distribuições Linux, e no Windows é um download pequeno:
sqlite3 my_pack.db
sqlite> .tables
sqlite> .schema teams
sqlite> SELECT name, country FROM teams ORDER BY sort;
sqlite> .quit
A partir de um script — o Python já traz SQLite, o que torna um pack uma saída de build natural:
import sqlite3
db = sqlite3.connect("my_pack.db")
db.execute("UPDATE drivers SET salary = CAST(salary * 1.1 AS INTEGER)")
db.commit()
db.close()
Trabalhe sempre numa cópia. Um pack é um único arquivo — fazer backup dele é um arrastar.
As regras que o carregador segue
Estas seis regras são o que torna segura a edição à mão. Vale lê-las antes do próprio esquema.
1 — Toda tabela é opcional. Um pack só com a tabela drivers é válido. Uma tabela ausente significa «aquela seção continua procedural», nunca um erro.
2 — Toda coluna é opcional. O carregador pergunta ao SQLite quais colunas sua tabela realmente tem e serve o resto como NULL. Então CREATE TABLE teams(name TEXT) funciona. Isso também significa que um pack escrito para uma versão mais antiga continua carregando, e que um erro de digitação num nome de coluna não é um erro — a coluna simplesmente nunca é lida, e esse é o único modo de falha a vigiar.
3 — Os tipos são tolerantes. Cada valor é lido como texto, não importa como foi guardado. 12, "12" e até 12.0 chegam todos como o número 12 onde se espera um número. Guarde o que for conveniente.
4 — As linhas são ordenadas por sort. Acrescente uma coluna inteira sort e as linhas são lidas nessa ordem; sem ela, vêm na ordem de inserção. A ordem importa para as equipes (o grid é construído nela) e para as etapas do calendário.
5 — Vazio significa «manter o que o jogo gerou». É a regra mais útil de todas. Uma cor vazia mantém a pintura gerada, um car_index vazio mantém o modelo gerado, um potencial em 0 deixa o gerador definir o teto. Você sobrescreve o que lhe interessa e deixa o resto em paz.
6 — Uma linha ruim é descartada, não é fatal. Uma equipe sem nome, um circuito com menos de três pontos, uma linha de histórico malformada — cada uma cai sozinha. O resto do pack carrega assim mesmo.
meta — as configurações do próprio pack
Duas colunas, key e value, uma linha por configuração. As chaves não diferenciam maiúsculas.
| Chave | Valor | Padrão |
|---|---|---|
name | O nome exibido no seletor | o nome do arquivo |
author | Seu nome — exibido com o pack | — |
schema_version | Versão de formato deste pack (atual: 2) | 1 |
min_game_version | Build mínima que o entende, ex. 0.5.4-6 | nenhuma |
scenario | new_series (você entra como equipe nova) ou imposed (você assume um grid já escrito) | new_series |
start_year | Ano civil da temporada 1 | o do jogo |
teams_mode · drivers_mode · sponsors_mode · suppliers_mode · circuits_mode | extend (soma-se ao mundo gerado) ou replace (só os seus) | extend |
active_series | Lista CSV dos campeonatos a disputar, ex. PFS,PF2 | todos os ativos |
rules | Lista CSV de identificadores de regulamento, ex. points_classic_top6,quali_107 | os da série |
replace também aceita only; imposed também aceita takeover ou existing. Um valor desconhecido cai no padrão em vez de falhar.
Duas chaves são um aperto de mão com o jogo, e é por isso que um pack nunca falha em silêncio:
- se
schema_versionfor maior do que a build entende, a linha do pack no seletor diz isso — «escrito para um formato mais novo» — e as partes ilegíveis são ignoradas; - se
min_game_versionfor mais nova que a build, a linha diz «precisa do jogo X ou mais recente».
Preencha as duas. Custam duas linhas e transformam um pack meio funcionando e enigmático numa mensagem clara.
CREATE TABLE meta(key TEXT, value TEXT);
INSERT INTO meta VALUES
('name', 'Temporada 1994'),
('author', 'Seu nome'),
('schema_version', '2'),
('min_game_version', '0.5.4-6'),
('scenario', 'imposed'),
('start_year', '1994'),
('teams_mode', 'replace'),
('drivers_mode', 'replace');
teams
| Coluna | Significado |
|---|---|
id | Chave estável. Aquilo a que pilotos, patrocinadores e fornecedores apontam. Qualquer texto único. |
name | Nome exibido. Uma linha sem nome é descartada. |
country | Nome do país (Germany) ou código ISO (de) — os dois funcionam |
budget_tier | small · medium · large — o comportamento da equipe, não só o caixa |
budget_musd | Orçamento inicial em milhões. Define também a faixa, a menos que budget_tier diga outra coisa |
reputation | 0-100 |
color1 · color2 · color3 | Hexadecimal, ex. #1A5FB4. Os três vazios = manter a pintura gerada |
car_index | Modelo de carro 0-11. Vazio = manter o gerado (0 é um carro de verdade, não «indefinido») |
livery · suit | Índices de variante; 255 = gerado |
logo | Um nome de linha images, um caminho relativo à pasta de mods, ou um simples número para um logo embutido |
car_image | Um nome de linha images para um sprite de carro próprio |
infra_engineering · _rnd · _chassis · _handling · _aero · _engine · _marketing · _scouting | Níveis de departamento 0-10. 0 = manter o gerado |
infra_academy | Idem, com teto 3 |
career_wins · career_titles · best_championship · founding_year | Palmarés, para um histórico escrito |
history | Temporadas passadas como temporada:posição:vitórias, separadas por ; ou quebras de linha |
Infraestrutura e palmarés só importam de verdade num cenário imposed, em que o grid precisa ser um negócio em andamento desde a primeira corrida.
drivers
| Coluna | Significado |
|---|---|
id | Chave estável |
first_name · last_name | Uma linha sem nenhum dos dois é descartada |
code | Sigla de três letras. Passa a maiúsculas ao carregar; uma repetição é renomeada em silêncio |
country | Código ISO — aqui o valor É a chave da bandeira |
age | 1-55. Menos de 16 é permitido para uma promessa: ele envelhece, fica oculto ao Scouting até os 14, e não pode ocupar uma vaga antes que as regras de idade da série permitam |
intelligence · pace · consistency · adaptability · stamina · aggressivity | As seis aptidões, 1-20 |
pot_intelligence … pot_aggressivity | Seus tetos, 0-20. 0 = deixe o gerador decidir |
curve_intelligence … curve_aggressivity | Identificadores de curva de evolução; 255 = padrão. Um identificador desconhecido cai no padrão em vez de congelar o atributo |
salary | Por temporada |
traits | Pares tipo:nível separados por vírgulas, ex. 3:1,7:2 |
face_sheet · face_index · helmet_index | Retrato; 255 = gerado |
helmet_hue_0 · _1 · _2 | Tons do capacete. Os três vazios = gerado |
team · team_id | A vaga. team_id vence se os dois estiverem preenchidos |
role | primary · secondary · reserve |
contract_years | 0-5 |
career_starts · career_wins · career_podiums · career_titles · best_finish | Palmarés |
fame | 0-100; 0 mantém o valor calculado |
Dois pilotos por equipe, um por vaga. Dois pilotos primary na mesma equipe deixam o carro 2 vazio — e um carro sem piloto não larga.
sponsors
| Coluna | Significado |
|---|---|
id | Chave estável |
name | Vazio, a linha é descartada |
sector | Setor de atuação — orienta o logo procedural |
color | Hexadecimal |
budget · prominence | 1-10 |
origin | Nome do país ou código ISO |
logo | Um nome de linha images ou um caminho |
team · team_id | Assiná-lo de antemão com uma equipe. Aceita uma lista separada por ; ou , |
O primeiro patrocinador de uma equipe vira o Principal, os demais Secundários.
suppliers
| Coluna | Significado |
|---|---|
id | Chave estável |
name | Vazio, a linha é descartada |
category | engine · tires · fuel |
color · origin · logo | Como nos patrocinadores |
budget · size | 1-10 |
money_per_gp | Dinheiro por corrida. Positivo = ele paga você, negativo = você paga ele |
contract | partnership (exclusivo) ou client. Vence sobre o sinal de money_per_gp |
duration | 0-5 temporadas |
team · team_id | Assinatura prévia; uma lista, como nos patrocinadores |
As estatísticas técnicas têm duas escritas, e as colunas nomeadas são a razão de ser desta página. Quatro casas genéricas (stat_a … stat_d) significavam coisas diferentes conforme a categoria, algo que nenhuma ferramenta de terceiros conseguia adivinhar. Escreva de preferência as colunas nomeadas — elas vencem assim que estiverem preenchidas e diferentes de zero:
| Categoria | Colunas nomeadas (0-10) |
|---|---|
engine | power · reliability · endurance · potential |
tires | performance · endurance · reliability · heat |
fuel | efficiency |
circuits
Os traçados desenhados à mão que o pack carrega. O editor de circuitos escreve essas linhas, mas a geometria é texto puro: um script também consegue.
| Coluna | Significado |
|---|---|
id | Chave estável — aquilo a que uma etapa do calendário aponta |
name | Vazio, a linha é descartada |
points | A linha central. Pares x,y unidos por ;. Com menos de três pontos a linha é descartada |
country · city | Vazio dá um lugar aleatório, porém estável |
target_km | Comprimento da volta; abaixo de 1 volta a 5 km |
character | O caráter do traçado — é o que a simulação realmente lê |
preset | Identificador de predefinição visual |
start_finish · pit_entry · pit_exit | Posições ao longo da volta; negativo ou ausente = deduzido |
year · downforce · tire_wear · overtaking | Guardados e exibidos, mas não simulados — em jogo esses três derivam do character |
calendar
Uma linha por etapa, em ordem sort, até 24.
| Coluna | Significado |
|---|---|
kind | circuit = usar um circuito do pack; qualquer outro valor = traçado gerado |
circuit · circuit_id | Qual. circuit_id é tentado primeiro |
character · target_km | Para uma etapa gerada |
Um pack que carrega um calendário substitui a temporada. Um pack que carrega circuitos sem calendário despeja seus traçados no acervo mundial e os deixa conquistar etapas sozinhos.
images
name (a chave a que as outras tabelas apontam) e data, os bytes do PNG como BLOB. Os logos são desenhados em 195×195; um sprite de carro próprio é uma vista de perfil voltada para a direita sobre transparência, com 256 px de altura.
Inserir uma imagem pela linha de comando:
sqlite3 my_pack.db "INSERT INTO images(name, data) VALUES('lotus.png', readfile('lotus.png'))"
…ou pelo Python:
db.execute("INSERT INTO images(name, data) VALUES(?, ?)",
("lotus.png", open("lotus.png", "rb").read()))
Depois aponte uma linha para lá: UPDATE teams SET logo = 'lotus.png' WHERE name = 'Lotus'.
Dois nomes que só diferem na pontuação (meu logo.png e meu-logo.png) vão parar no mesmo arquivo; o primeiro fica com ele e o segundo recebe um sufixo numerado, de modo que nada é sobrescrito em silêncio.
Um pack mínimo, do início ao fim
CREATE TABLE meta(key TEXT, value TEXT);
INSERT INTO meta VALUES
('name','Duas equipes'), ('schema_version','2'),
('min_game_version','0.5.4-6'), ('teams_mode','extend');
CREATE TABLE teams(sort INTEGER, id TEXT, name TEXT, country TEXT,
budget_tier TEXT, color1 TEXT, color2 TEXT);
INSERT INTO teams VALUES
(1,'t_alba','Alba Corse','Italy','large','#B3122C','#F2E8D5'),
(2,'t_nord','Nordwind GP','Germany','medium','#14304F','#C8D3DC');
CREATE TABLE drivers(sort INTEGER, id TEXT, first_name TEXT, last_name TEXT,
code TEXT, country TEXT, age INTEGER,
pace INTEGER, consistency INTEGER,
team_id TEXT, role TEXT);
INSERT INTO drivers VALUES
(1,'d_ros','Elio','Rossi','ROS','it',27,17,15,'t_alba','primary'),
(2,'d_ber','Karl','Berger','BER','de',31,15,17,'t_alba','secondary');
Esse é um pack completo e válido. Tudo o que não for mencionado continua procedural.
Conferir o seu trabalho
Pergunte ao jogo o que ele vê. Rode-o uma vez a partir de um terminal com --list-mods: ele imprime as pastas que percorre na ordem, e depois cada pack, circuito e idioma encontrados. É a primeira coisa a rodar quando um pack não aparece.
mod folders (read in this order):
/home/voce/.local/share/TheUndercut/mods
/caminho/do/jogo/mods (does not exist)
packs:
my_pack
Leia a linha do pack no seletor. Ali o jogo diz o que entendeu só pela metade — um formato mais novo, uma versão de jogo de que precisa, ou duas equipes com o mesmo nome, o que torna os vínculos ambíguos.
Abra-o uma vez no editor de mods. A aba Audit pega o que o SQL não enxerga: uma segunda vaga vazia, um piloto ligado a uma equipe inexistente, uma sigla repetida. Abrir um pack escrito à mão também carimba identificadores estáveis nas linhas que não os têm, e essa é a melhor coisa que se pode fazer a um pack escrito à mão.
Armadilhas que vale conhecer
- Uma coluna escrita errado é silenciosa.
colour1não écolor1; ela simplesmente nunca é lida. Se uma alteração parece não fazer nada, confira primeiro a grafia contra esta página —PRAGMA table_info(teams)lista o que sua tabela tem de verdade. - Os vínculos seguem primeiro o
id, depois o nome. Dê um identificador a cada linha e renomear uma equipe preserva os pilotos dela. Sem identificadores, renomeá-la joga seus pilotos no grupo de agentes livres. 0não quer dizer «indefinido» em todo lugar. Significa manter o gerado para potenciais, infraestrutura e fama — mascar_indexem0é um carro de verdade: deixe essa coluna vazia para manter o modelo gerado.- Um pack só se aplica na criação da carreira. Editá-lo não muda nada numa carreira já em andamento. Comece outra.
- O arquivo precisa ficar onde está. Logos e sprites de carro são lidos dele durante toda a vida da carreira.
- Grave suas alterações. Um navegador gráfico as mantém numa transação pendente — feche-o sem Gravar alterações e nada terá sido salvo.
Veja também
- Packs de mods — o que cada seção significa dentro do jogo
- Editor de mods — a ferramenta que escreve tudo isso por você
- Modding de circuitos — desenhar os traçados que um pack carrega
- Publicar na Steam Workshop — compartilhar o pack pronto