Wiki in costruzione. Molti concetti qui descritti provengono dall'alpha 0.2 e possono ancora cambiare. La wiki sarà finalizzata per la versione 1.0 — per ora serve ad aiutare i tester chiusi e, più avanti, i giocatori dell'accesso anticipato a orientarsi. Per le informazioni più aggiornate e affidabili, entra nel Discord — è lì che le novità vengono annunciate per prime e dove puoi chiedere direttamente.

Entra nel Discord per le ultime novità

Modificare un pack in SQL

Lo schema completo di un pack di mod, tabella per tabella, gli strumenti per aprirlo — sqlite3, DB Browser, uno script Python — e le regole che segue il caricatore.

In questa pagina

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.

Editor di mod nel gioco · verificato DB Browser modifica come un foglio sqlite3 · Python massa · generazione my_pack.db un file SQLite Il gioco legge alla creazione

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.

ChiaveValorePredefinito
nameIl nome mostrato nel selettoreil nome del file
authorIl vostro nome — mostrato col pack—
schema_versionVersione di formato di questo pack (attuale: 2)1
min_game_versionBuild minima che lo comprende, es. 0.5.4-6nessuna
scenarionew_series (entrate come scuderia nuova) o imposed (rilevate una griglia già scritta)new_series
start_yearAnno solare della stagione 1quello del gioco
teams_mode · drivers_mode · sponsors_mode · suppliers_mode · circuits_modeextend (si aggiunge al mondo generato) o replace (solo i vostri)extend
active_seriesElenco CSV dei campionati da far correre, es. PFS,PF2tutti gli attivi
rulesElenco CSV di identificatori di regolamento, es. points_classic_top6,quali_107quelli 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_version supera 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

ColonnaSignificato
idChiave stabile. Ciò a cui puntano piloti, sponsor e fornitori. Qualunque stringa unica.
nameNome visualizzato. Una riga senza nome viene saltata.
countryNome del paese (Germany) o codice ISO (de) — vanno entrambi
budget_tiersmall · medium · large — il comportamento della scuderia, non solo la cassa
budget_musdBudget iniziale in milioni. Fissa anche la fascia, salvo diverso budget_tier
reputation0-100
color1 · color2 · color3Esadecimale, es. #1A5FB4. Tutti e tre vuoti = tieni la livrea generata
car_indexModello di vettura 0-11. Vuoto = tieni quello generato (0 è una vettura vera, non «non impostato»)
livery · suitIndici di variante; 255 = generato
logoUn nome di riga images, un percorso relativo alla cartella mods, o un semplice numero per un logo integrato
car_imageUn nome di riga images per uno sprite di vettura personalizzato
infra_engineering · _rnd · _chassis · _handling · _aero · _engine · _marketing · _scoutingLivelli di reparto 0-10. 0 = tieni il generato
infra_academyIdem, con tetto a 3
career_wins · career_titles · best_championship · founding_yearPalmarès, per una storia scritta
historyStagioni 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

ColonnaSignificato
idChiave stabile
first_name · last_nameUna riga priva di entrambi viene saltata
codeSigla di tre lettere. Resa maiuscola al caricamento; un doppione viene rinominato in silenzio
countryCodice ISO — qui il valore È la chiave della bandiera
age1-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 · aggressivityLe sei abilità, 1-20
pot_intelligence … pot_aggressivityI loro tetti, 0-20. 0 = lascia decidere al generatore
curve_intelligence … curve_aggressivityIdentificatori di curva di crescita; 255 = predefinito. Un identificatore sconosciuto ricade sul predefinito invece di congelare la statistica
salaryA stagione
traitsCoppie tipo:livello separate da virgole, es. 3:1,7:2
face_sheet · face_index · helmet_indexRitratto; 255 = generato
helmet_hue_0 · _1 · _2Tinte del casco. Tutte e tre vuote = generato
team · team_idIl sedile. team_id vince se ci sono entrambi
roleprimary · secondary · reserve
contract_years0-5
career_starts · career_wins · career_podiums · career_titles · best_finishPalmarès
fame0-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

ColonnaSignificato
idChiave stabile
nameSe vuoto la riga viene saltata
sectorSettore merceologico — guida il logo procedurale
colorEsadecimale
budget · prominence1-10
originNome del paese o codice ISO
logoUn nome di riga images o un percorso
team · team_idFirmarlo 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

ColonnaSignificato
idChiave stabile
nameSe vuoto la riga viene saltata
categoryengine · tires · fuel
color · origin · logoCome per gli sponsor
budget · size1-10
money_per_gpDenaro a gara. Positivo = vi paga, negativo = lo pagate
contractpartnership (esclusivo) o client. Vince sul segno di money_per_gp
duration0-5 stagioni
team · team_idFirma 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:

CategoriaColonne con nome (0-10)
enginepower · reliability · endurance · potential
tiresperformance · endurance · reliability · heat
fuelefficiency

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.

ColonnaSignificato
idChiave stabile — ciò a cui punta una gara del calendario
nameSe vuoto la riga viene saltata
pointsLa linea mediana. Coppie x,y unite da ;. Sotto i tre punti la riga viene scartata
country · cityVuoto dà un luogo casuale ma stabile
target_kmLunghezza del giro; sotto 1 ricade a 5 km
characterIl carattere del tracciato — è ciò che la simulazione legge davvero
presetIdentificatore di preset visivo
start_finish · pit_entry · pit_exitPosizioni lungo il giro; negativo o assente = dedotto
year · downforce · tire_wear · overtakingMemorizzati e mostrati, ma non simulati — in gioco quei tre discendono da character

calendar

Una riga per gara, in ordine sort, fino a 24.

ColonnaSignificato
kindcircuit = usa un circuito del pack; qualunque altro valore = tracciato generato
circuit · circuit_idQuale. circuit_id viene provato per primo
character · target_kmPer 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. colour1 non è 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.
  • 0 non vuol dire «non impostato» dappertutto. Significa tieni il generato per potenziali, infrastruttura e fama — ma car_index a 0 è 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