Un pack di mod è un semplice database SQLite. L’editor di mod è il modo comodo di scriverne uno, ma nulla vi impedisce di aprire il file voi stessi — e per certi lavori è di gran lunga la strada più rapida:
- importare una stagione reale da un foglio di calcolo o da un CSV;
- rinominare quaranta sponsor, o alzare del 10 % lo stipendio di ogni pilota;
- generare un pack da uno script, per rifarlo ogni volta che i dati di partenza cambiano;
- leggere il pack di qualcun altro per vedere come ha fatto.
Questa pagina è il riferimento per tutto ciò. Documenta quello che il gioco legge davvero — colonna per colonna — e le regole che segue. Nulla qui è un dettaglio privato: il caricatore è volutamente tollerante, e sapere quanto lo è è proprio ciò che permette di scrivere un pack a mano con fiducia.
Questa pagina non serve mai per fare un mod. L’editor di mod scrive tutte le tabelle descritte qui, controlla il vostro lavoro e aggiorna i pack più vecchi. Passate a SQL quando volete modifiche di massa o generazione da script.
Aprire un pack
Va bene qualunque strumento SQLite — il file non ha intestazioni proprie, né compressione, né cifratura.
In grafica — DB Browser for SQLite è gratuito, gira su Windows, macOS e Linux, e modifica le tabelle come un foglio di calcolo. È l’ingresso più dolce se non avete mai scritto SQL: aprite il file, andate su Sfoglia dati, scegliete una tabella e digitate. Ricordatevi di Scrivi modifiche prima di chiudere.
Riga di comando — sqlite3 è incluso in macOS e nella maggior parte delle distribuzioni Linux, e su Windows è un piccolo download:
sqlite3 my_pack.db
sqlite> .tables
sqlite> .schema teams
sqlite> SELECT name, country FROM teams ORDER BY sort;
sqlite> .quit
Da uno script — Python include SQLite, il che rende un pack un naturale prodotto di build:
import sqlite3
db = sqlite3.connect("my_pack.db")
db.execute("UPDATE drivers SET salary = CAST(salary * 1.1 AS INTEGER)")
db.commit()
db.close()
Lavorate sempre su una copia. Un pack è un solo file — farne il backup è un trascinamento.
Le regole che segue il caricatore
Queste sei regole sono ciò che rende sicura la modifica a mano. Vale la pena leggerle prima dello schema stesso.
1 — Ogni tabella è opzionale. Un pack con la sola tabella drivers è valido. Una tabella assente significa «quella sezione resta procedurale», mai un errore.
2 — Ogni colonna è opzionale. Il caricatore chiede a SQLite quali colonne la vostra tabella ha davvero e serve il resto come NULL. Quindi CREATE TABLE teams(name TEXT) funziona. Significa anche che un pack scritto per una versione più vecchia continua a caricarsi, e che un refuso in un nome di colonna non è un errore — quella colonna semplicemente non viene mai letta, ed è l’unico modo di fallimento da sorvegliare.
3 — I tipi sono tolleranti. Ogni valore viene letto come testo, comunque sia memorizzato. 12, "12" e perfino 12.0 arrivano tutti come il numero 12 dove serve un numero. Memorizzate ciò che vi è comodo.
4 — Le righe sono ordinate per sort. Aggiungete una colonna intera sort e le righe vengono lette in quell’ordine; senza di essa arrivano nell’ordine di inserimento. L’ordine conta per le scuderie (la griglia si costruisce con quello) e per le gare del calendario.
5 — Vuoto significa «tieni ciò che il gioco ha generato». È la regola più utile di tutte. Un colore vuoto tiene la livrea generata, un car_index vuoto tiene il modello generato, un potenziale a 0 lascia al generatore il tetto. Sovrascrivete ciò che vi interessa e lasciate stare il resto.
6 — Una riga sbagliata viene saltata, non è fatale. Una scuderia senza nome, un circuito con meno di tre punti, una riga di storico malformata — ciascuna cade da sola. Il resto del pack si carica lo stesso.
meta — le impostazioni del pack stesso
Due colonne, key e value, una riga per impostazione. Le chiavi non distinguono maiuscole e minuscole.
| Chiave | Valore | Predefinito |
|---|---|---|
name | Il nome mostrato nel selettore | il nome del file |
author | Il vostro nome — mostrato col pack | — |
schema_version | Versione di formato di questo pack (attuale: 2) | 1 |
min_game_version | Build minima che lo comprende, es. 0.5.4-6 | nessuna |
scenario | new_series (entrate come scuderia nuova) o imposed (rilevate una griglia già scritta) | new_series |
start_year | Anno solare della stagione 1 | quello del gioco |
teams_mode · drivers_mode · sponsors_mode · suppliers_mode · circuits_mode | extend (si aggiunge al mondo generato) o replace (solo i vostri) | extend |
active_series | Elenco CSV dei campionati da far correre, es. PFS,PF2 | tutti gli attivi |
rules | Elenco CSV di identificatori di regolamento, es. points_classic_top6,quali_107 | quelli della serie |
replace accetta anche only; imposed accetta anche takeover o existing. Un valore sconosciuto ricade sul predefinito invece di fallire.
Due chiavi sono una stretta di mano col gioco, ed è il motivo per cui un pack non fallisce mai in silenzio:
- se
schema_versionsupera ciò che la build comprende, la riga del pack nel selettore lo dice — «scritto per un formato più recente» — e le parti illeggibili vengono ignorate; - se
min_game_versionè più recente della build, la riga dice «richiede il gioco X o successivo».
Compilatele entrambe. Costano due righe e trasformano un pack a metà funzionante e misterioso in un messaggio chiaro.
CREATE TABLE meta(key TEXT, value TEXT);
INSERT INTO meta VALUES
('name', 'Stagione 1994'),
('author', 'Il vostro nome'),
('schema_version', '2'),
('min_game_version', '0.5.4-6'),
('scenario', 'imposed'),
('start_year', '1994'),
('teams_mode', 'replace'),
('drivers_mode', 'replace');
teams
| Colonna | Significato |
|---|---|
id | Chiave stabile. Ciò a cui puntano piloti, sponsor e fornitori. Qualunque stringa unica. |
name | Nome visualizzato. Una riga senza nome viene saltata. |
country | Nome del paese (Germany) o codice ISO (de) — vanno entrambi |
budget_tier | small · medium · large — il comportamento della scuderia, non solo la cassa |
budget_musd | Budget iniziale in milioni. Fissa anche la fascia, salvo diverso budget_tier |
reputation | 0-100 |
color1 · color2 · color3 | Esadecimale, es. #1A5FB4. Tutti e tre vuoti = tieni la livrea generata |
car_index | Modello di vettura 0-11. Vuoto = tieni quello generato (0 è una vettura vera, non «non impostato») |
livery · suit | Indici di variante; 255 = generato |
logo | Un nome di riga images, un percorso relativo alla cartella mods, o un semplice numero per un logo integrato |
car_image | Un nome di riga images per uno sprite di vettura personalizzato |
infra_engineering · _rnd · _chassis · _handling · _aero · _engine · _marketing · _scouting | Livelli di reparto 0-10. 0 = tieni il generato |
infra_academy | Idem, con tetto a 3 |
career_wins · career_titles · best_championship · founding_year | Palmarès, per una storia scritta |
history | Stagioni passate come stagione:posizione:vittorie, separate da ; o da a capo |
Infrastruttura e palmarès contano davvero solo nello scenario imposed, dove la griglia deve essere un’attività già avviata dalla prima gara.
drivers
| Colonna | Significato |
|---|---|
id | Chiave stabile |
first_name · last_name | Una riga priva di entrambi viene saltata |
code | Sigla di tre lettere. Resa maiuscola al caricamento; un doppione viene rinominato in silenzio |
country | Codice ISO — qui il valore È la chiave della bandiera |
age | 1-55. Sotto i 16 è ammesso per un giovane: invecchia, resta nascosto allo Scouting fino a 14 anni e non può avere un sedile finché le regole d’età della serie non lo consentono |
intelligence · pace · consistency · adaptability · stamina · aggressivity | Le sei abilità, 1-20 |
pot_intelligence … pot_aggressivity | I loro tetti, 0-20. 0 = lascia decidere al generatore |
curve_intelligence … curve_aggressivity | Identificatori di curva di crescita; 255 = predefinito. Un identificatore sconosciuto ricade sul predefinito invece di congelare la statistica |
salary | A stagione |
traits | Coppie tipo:livello separate da virgole, es. 3:1,7:2 |
face_sheet · face_index · helmet_index | Ritratto; 255 = generato |
helmet_hue_0 · _1 · _2 | Tinte del casco. Tutte e tre vuote = generato |
team · team_id | Il sedile. team_id vince se ci sono entrambi |
role | primary · secondary · reserve |
contract_years | 0-5 |
career_starts · career_wins · career_podiums · career_titles · best_finish | Palmarès |
fame | 0-100; 0 tiene il valore calcolato |
Due piloti per scuderia, uno per sedile. Due piloti primary nella stessa squadra lasciano vuota la vettura 2 — e una vettura senza pilota non prende il via.
sponsors
| Colonna | Significato |
|---|---|
id | Chiave stabile |
name | Se vuoto la riga viene saltata |
sector | Settore merceologico — guida il logo procedurale |
color | Esadecimale |
budget · prominence | 1-10 |
origin | Nome del paese o codice ISO |
logo | Un nome di riga images o un percorso |
team · team_id | Firmarlo in anticipo con una scuderia. Accetta un elenco separato da ; o , |
Il primo sponsor di una squadra ne diventa il Principale, gli altri Secondari.
suppliers
| Colonna | Significato |
|---|---|
id | Chiave stabile |
name | Se vuoto la riga viene saltata |
category | engine · tires · fuel |
color · origin · logo | Come per gli sponsor |
budget · size | 1-10 |
money_per_gp | Denaro a gara. Positivo = vi paga, negativo = lo pagate |
contract | partnership (esclusivo) o client. Vince sul segno di money_per_gp |
duration | 0-5 stagioni |
team · team_id | Firma anticipata; un elenco, come per gli sponsor |
Le statistiche tecniche hanno due scritture, e le colonne con nome sono la ragione d’essere di questa pagina. Quattro caselle generiche (stat_a … stat_d) significavano cose diverse a seconda della categoria, cosa che nessuno strumento di terze parti poteva indovinare. Scrivete piuttosto le colonne con nome — vincono non appena sono valorizzate e diverse da zero:
| Categoria | Colonne con nome (0-10) |
|---|---|
engine | power · reliability · endurance · potential |
tires | performance · endurance · reliability · heat |
fuel | efficiency |
circuits
I tracciati disegnati a mano che il pack porta con sé. L’editor di circuiti scrive queste righe, ma la geometria è testo semplice: può farlo anche uno script.
| Colonna | Significato |
|---|---|
id | Chiave stabile — ciò a cui punta una gara del calendario |
name | Se vuoto la riga viene saltata |
points | La linea mediana. Coppie x,y unite da ;. Sotto i tre punti la riga viene scartata |
country · city | Vuoto dà un luogo casuale ma stabile |
target_km | Lunghezza del giro; sotto 1 ricade a 5 km |
character | Il carattere del tracciato — è ciò che la simulazione legge davvero |
preset | Identificatore di preset visivo |
start_finish · pit_entry · pit_exit | Posizioni lungo il giro; negativo o assente = dedotto |
year · downforce · tire_wear · overtaking | Memorizzati e mostrati, ma non simulati — in gioco quei tre discendono da character |
calendar
Una riga per gara, in ordine sort, fino a 24.
| Colonna | Significato |
|---|---|
kind | circuit = usa un circuito del pack; qualunque altro valore = tracciato generato |
circuit · circuit_id | Quale. circuit_id viene provato per primo |
character · target_km | Per una gara generata |
Un pack che porta un calendario sostituisce la stagione. Un pack che porta circuiti senza calendario versa i suoi tracciati nel bacino mondiale e li lascia conquistare le gare da soli.
images
name (la chiave a cui puntano le altre tabelle) e data, i byte del PNG come BLOB. I loghi si disegnano a 195×195; uno sprite di vettura personalizzato è una vista laterale rivolta a destra su trasparenza, alta 256 px.
Inserire un’immagine da riga di comando:
sqlite3 my_pack.db "INSERT INTO images(name, data) VALUES('lotus.png', readfile('lotus.png'))"
…oppure da Python:
db.execute("INSERT INTO images(name, data) VALUES(?, ?)",
("lotus.png", open("lotus.png", "rb").read()))
Poi fate puntare lì una riga: UPDATE teams SET logo = 'lotus.png' WHERE name = 'Lotus'.
Due nomi che differiscono solo per la punteggiatura (mio logo.png e mio-logo.png) finiscono nello stesso file; il primo se lo tiene e il secondo riceve un suffisso numerato, così nulla viene sovrascritto in silenzio.
Un pack minimo, dall’inizio alla fine
CREATE TABLE meta(key TEXT, value TEXT);
INSERT INTO meta VALUES
('name','Due scuderie'), ('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');
Questo è un pack completo e valido. Tutto ciò che non è menzionato resta procedurale.
Verificare il proprio lavoro
Chiedete al gioco cosa vede. Avviatelo una volta da un terminale con --list-mods: stampa le cartelle che esamina nell’ordine, poi ogni pack, circuito e lingua trovati. È la prima cosa da lanciare quando un pack non compare.
mod folders (read in this order):
/home/voi/.local/share/TheUndercut/mods
/percorso/del/gioco/mods (does not exist)
packs:
my_pack
Leggete la riga del pack nel selettore. Lì il gioco dice cosa ha capito solo a metà — un formato più recente, una versione di gioco che gli serve, o due scuderie con lo stesso nome, cosa che rende ambigui i collegamenti.
Apritelo una volta nell’editor di mod. La sua scheda Audit coglie ciò che l’SQL non può vedere: un secondo sedile vuoto, un pilota legato a una scuderia inesistente, una sigla doppia. Aprire un pack scritto a mano vi imprime anche identificatori stabili sulle righe che non ne hanno, ed è la cosa migliore che si possa fare a un pack scritto a mano.
Trappole da conoscere
- Una colonna scritta male è silenziosa.
colour1non ècolor1; semplicemente non viene mai letta. Se una modifica sembra non fare nulla, verificate prima l’ortografia rispetto a questa pagina —PRAGMA table_info(teams)elenca ciò che la vostra tabella ha davvero. - I collegamenti seguono prima
id, poi il nome. Date un identificatore a ogni riga e rinominare una scuderia le conserva i piloti. Senza identificatori, rinominarla manda i suoi piloti tra gli svincolati. 0non vuol dire «non impostato» dappertutto. Significa tieni il generato per potenziali, infrastruttura e fama — macar_indexa0è una vettura vera: lasciate quella colonna vuota per tenere il modello generato.- Un pack si applica solo alla creazione della carriera. Modificarlo non cambia nulla in una carriera già avviata. Iniziatene una nuova.
- Il file deve restare dov’è. Loghi e sprite delle vetture vi vengono letti per tutta la vita della carriera.
- Scrivete le vostre modifiche. Un browser grafico le tiene in una transazione in sospeso — chiudetelo senza Scrivi modifiche e non sarà stato salvato nulla.
Vedi anche
- Pack di mod — cosa significa ogni sezione in gioco
- Editor di mod — lo strumento che scrive tutto questo per voi
- Modding dei circuiti — disegnare i tracciati che un pack porta con sé
- Pubblicare sullo Steam Workshop — condividere il pack finito