Custom databases
A database is the whole world the game races in: the grid, the circuits, the calendar, the economy and the balance. You can build one of your own — a different grid, another series, a rebalance — and the game will start a career from it.
For game version 1.0.3 · database format 7 · this page is in English only
Download the starter file
Start from this file, not from an empty one. Nobody builds sixteen teams and twenty-four circuits from a bare schema — take ours and change it. It is the database the game ships with, carrying a name of its own so the game will accept it beside the built-in one, and it imports cleanly before you have edited a single row.
Starter database
SQLite 3 · about 11 MB · database format 7
| What is in it | |
|---|---|
| Teams on the grid | 11 |
| Drivers racing them | 22 |
| Drivers in the file, with the reserves and the retired | 140 |
| Circuits | 24 |
| Calendar rounds | 24 |
| Written decisions, with 1,384 answers | 586 |
| Sponsors | 250 |
| Balance settings you can tune | 444 |
How it works
One fact explains everything else on this page: a database is the whole world, and a career is a copy of it.
When a career starts, the game copies the database you chose, byte for byte, and that copy becomes the career. It is brought forward if it was made for an older version of the game, and after that it is never reconciled with anything again. So a database is not a patch applied over the game — it is the game's content, complete, and a career built from one keeps it for good.
Three things follow, and they are the ones people are surprised by:
- Editing or removing a database never changes a career already in progress. The career has its own copy.
- A database has to be complete on its own. There is no falling back to the built-in one for the parts you left out.
- Your edits reach a career only when a new career is started from the file.
Quick start
- Download the starter file above.
- Open it in any SQLite tool — DB Browser for SQLite, the
sqlite3command line, a Python script, whatever you already use. - Change what you want, keeping to the rules below. Give it a new
db_nameanddb_versionin thesettingstable. - Put the file on your phone: a cable, a cloud drive, an email to yourself.
- In the game: main menu → Databases → Import Database, pick the file, and confirm what it shows you.
The game checks the file when you import it and, if it refuses, tells you exactly which rule the file broke. Nothing is destroyed by a bad import: the file is simply not added.
Name and version
Three rows in the settings table describe the file. Two are
yours; one belongs to the app.
| Row | Who sets it | What it is for |
|---|---|---|
db_name | You | The name the player sees, in the menu and on the Databases screen. |
db_version | You | The version the player sees. A label — never compared, never gates anything. |
schema_version | The app | Which database format the file is in. Leave it as the starter has it. |
Together, the name and the version are the file's identity, and the game refuses to install two databases with the same pair. It already holds the built-in one, so a byte copy of it is refused as a duplicate — which is exactly why the starter file arrives with a name of its own. When you publish a new cut of your database, change the version, or players who already have the old one cannot install it.
schema_version is different in kind. A file made for an
older game is brought forward automatically and needs nothing from you. A
file from a newer game cannot be made to fit and is refused — migrations
only run forwards. This page documents format 7.
World and career
Every table ships in the starter file. Some hold the world; some hold the career that will be played in it, and those have to go out the way the starter file has them — empty, or at their starting values.
The world — edit freely
The grid, the circuits, the calendar, the economy, the written decisions and the balance. A career is written into category 1, so that is the series every rule below is about. The second category in the starter file is cosmetic: its teams have no cars and nothing about it is checked.
The career — leave alone
Results, memories, messages, signed sponsors, family and season records are
written as a career is played, and a database you hand to someone else should
ship them empty. player_settings keeps its rows, with the starting
values the starter file has; the game writes the real ones when the career is
created. In settings, the rows without a comment are identity
and per-save flags rather than balance — leave those alone too, and keep
debug at 0.
The tables
What each table is, how many rows the starter file has, and whether it holds the world or the career. Open one to see its columns; the ones marked required are the columns the game reads, and a file missing one of them is refused.
| Table | Holds | Rows | What it is |
|---|---|---|---|
businesses | World | 1 | What a driver can invest in, and what it returns. |
cars | World | 26 | Two per team — power, aerodynamics, chassis, reliability. |
categories | World | 2 | The series. A career is always written into category 1. |
driver_assignments | World | 9 | Which seat each driver is assigned to. |
driver_seasons | Added on open | 0 | Season-by-season record per driver. Added by a migration; ship empty. |
driver_skills | World | 116 | The twelve skills that decide how a driver races. |
driver_stats | World | 140 | Career totals: starts, wins, poles, titles. |
drivers | World | 140 | Everyone on the grid, their contract and their standing. |
families | Career | 0 | The driver's family. Ship empty. |
interaction_answers | World | 1,384 | The answers to those decisions, and their effects. |
interactions | World | 586 | The written decisions, one text column per language. |
lifestyles | World | 44 | What a driver can own, and what it costs to keep. |
memories | Career | 0 | What a career remembers. Ship empty. |
messages | Career | 0 | The inbox. Ship empty. |
player_settings | Career | 15 | The player's week, year, money and energy. Keep the rows; leave the starting values. |
player_sponsors | Career | 0 | Sponsors actually signed. Ship empty. |
race_results | Career | 0 | Written as races are run. Ship empty. |
race_seasons | World | 24 | The calendar: a race, in a season, for a category. |
race_weekend_settings | Career | 8 | The current weekend's state. Leave at defaults. |
races | World | 24 | A race at a place, on a track, with its own weather odds. |
settings | World | 452 | Rows with a comment are the balance. Rows without are identity and per-save flags. |
sponsors | World | 250 | The sponsor market and the deals it offers. |
teams | World | 16 | The constructors: prestige, money, colours and logos. |
track_decorations | Added on open | 649 | Scenery. Added by a migration; only backfilled from our artwork for careers descended from the bundled file. |
track_knots | World | 981 | The racing line, as a curve of positioned knots. |
track_pit_knots | World | 192 | The pit lane, as a curve of its own. |
track_sectors | World | 72 | Where each sector ends, as an index into the knots. |
tracks | World | 24 | The circuit: grip, wear, scale, and the four pit markers. |
Columns
businesses
What a driver can invest in, and what it returns.
| Column | Type | |
|---|---|---|
id | integer | required |
name | varchar | required |
image | text | required |
level | integer | required |
income | integer | required |
base | integer | required |
is_owner | tinyint(1) | required |
cars
Two per team — power, aerodynamics, chassis, reliability.
| Column | Type | |
|---|---|---|
id | integer | required |
team_id | integer | required |
driver_id | integer | required |
power | integer | required |
aerodynamics | integer | required |
chassis | integer | required |
reliability | integer | required |
categories
The series. A career is always written into category 1.
| Column | Type | |
|---|---|---|
id | integer | required |
name | varchar | required |
prestige | integer | required |
logo | text | required |
driver_assignments
Which seat each driver is assigned to.
| Column | Type | |
|---|---|---|
id | integer | required |
driver_id | integer | required |
assignment | varchar | required |
driver_seasons
Season-by-season record per driver. Added by a migration; ship empty.
A migration creates this table on the phone, so a file without it still imports.
| Column | Type | |
|---|---|---|
id | integer | |
driver_id | integer | |
season | integer | |
team_id | integer | |
wdc_position | integer | |
wcc_position | integer | |
points | integer | |
wins | integer | |
podiums | integer |
driver_skills
The twelve skills that decide how a driver races.
| Column | Type | |
|---|---|---|
id | integer | required |
driver_id | integer | required |
defending | integer | required |
accuracy | integer | required |
focus | integer | required |
cornering | integer | required |
overtaking | integer | required |
qualifying | integer | required |
speed | integer | required |
tire_management | integer | required |
stamina | integer | required |
awareness | integer | required |
intelligence | integer | required |
driver_stats
Career totals: starts, wins, poles, titles.
| Column | Type | |
|---|---|---|
id | integer | required |
driver_id | integer | required |
seasons | integer | required |
races | integer | required |
wins | integer | required |
poles | integer | required |
podiums | integer | required |
titles | integer | required |
dnf | integer | required |
points | integer | required |
drivers
Everyone on the grid, their contract and their standing.
| Column | Type | |
|---|---|---|
id | integer | required |
team_id | integer | required |
country | varchar | required |
number | integer | required |
birth_year | integer | required |
reputation | integer | required |
learning | integer | required |
confidence | integer | required |
experience | integer | required |
prestige | integer | required |
relationship | integer | required |
contract_until | integer | required |
status | varchar | required |
name | varchar | required |
points | integer | required |
wdc | integer | required |
wcc | integer | required |
expected_number | integer | required |
families
The driver's family. Ship empty.
| Column | Type | |
|---|---|---|
id | integer | required |
is_eternal | tinyint(1) | required |
is_dead | tinyint(1) | required |
importance | integer | required |
relationship | integer | required |
kind | varchar | required |
name | varchar | required |
interaction_answers
The answers to those decisions, and their effects.
Only the English text is required. The other languages are used when present and fall back to English.
| Column | Type | |
|---|---|---|
id | integer | required |
interaction_id | integer | required |
text_en | varchar | required |
text_pt | varchar | |
text_es | varchar | |
text_de | varchar | |
text_it | varchar | |
text_fr | varchar | |
text_zh | varchar | |
text_tr | varchar | |
text_ru | varchar | |
text_ja | varchar | |
text_nl | varchar | |
effects | varchar | required |
interactions
The written decisions, one text column per language.
Only the English text is required. The other languages are used when present and fall back to English.
| Column | Type | |
|---|---|---|
id | integer | required |
who | varchar | required |
window | varchar | required |
question_en | varchar | required |
question_pt | varchar | |
question_es | varchar | |
question_de | varchar | |
question_it | varchar | |
question_fr | varchar | |
question_zh | varchar | |
question_tr | varchar | |
question_ru | varchar | |
question_ja | varchar | |
question_nl | varchar | |
conditions | varchar | required |
writes_memory | varchar | required |
cooldown_weeks | integer | required |
weight | integer | required |
lifestyles
What a driver can own, and what it costs to keep.
| Column | Type | |
|---|---|---|
id | integer | required |
category | varchar | required |
name | varchar | required |
is_owner | tinyint(1) | required |
image | text | required |
maintenance | integer | required |
price | integer | required |
memories
What a career remembers. Ship empty.
| Column | Type | |
|---|---|---|
id | integer | required |
type | varchar | required |
value | varchar | required |
times | integer | required |
last_time | integer | required |
messages
The inbox. Ship empty.
| Column | Type | |
|---|---|---|
id | integer | required |
type | varchar | required |
item1 | varchar | required |
item2 | varchar | required |
item3 | varchar | required |
is_read | int | required |
variation | int | required |
player_settings
The player's week, year, money and energy. Keep the rows; leave the starting values.
| Column | Type | |
|---|---|---|
id | integer | required |
item | varchar | required |
value | varchar | required |
player_sponsors
Sponsors actually signed. Ship empty.
| Column | Type | |
|---|---|---|
id | integer | required |
sponsor_id | integer | required |
races | integer | required |
reward | integer | required |
objective | varchar | required |
target | integer | required |
bonus | integer | required |
race_results
Written as races are run. Ship empty.
| Column | Type | |
|---|---|---|
id | integer | required |
race_season_id | integer | required |
driver_id | integer | required |
position | integer | required |
points | integer | required |
has_fastest_lap | tinyint(1) | required |
has_finished | tinyint(1) | required |
qualifying_position | integer | required |
team_id | integer | required |
race_seasons
The calendar: a race, in a season, for a category.
| Column | Type | |
|---|---|---|
id | integer | required |
race_id | integer | required |
season | integer | required |
week | integer | required |
laps | integer | required |
weather | text | required |
category_id | integer | required |
race_weekend_settings
The current weekend's state. Leave at defaults.
| Column | Type | |
|---|---|---|
id | integer | required |
item | varchar | required |
value | varchar | required |
races
A race at a place, on a track, with its own weather odds.
| Column | Type | |
|---|---|---|
id | integer | required |
name | text | required |
country | text | required |
rain_chance | integer | required |
weather_stability | integer | required |
track_id | integer | required |
settings
Rows with a comment are the balance. Rows without are identity and per-save flags.
| Column | Type | |
|---|---|---|
id | integer | required |
item | varchar | required |
value | varchar | required |
comment | text | required |
sponsors
The sponsor market and the deals it offers.
| Column | Type | |
|---|---|---|
id | integer | required |
name | varchar | required |
reputation | integer | required |
logo | text | required |
offer | integer | required |
races | integer | required |
offer_objective | varchar | required |
offer_target | integer | required |
offer_bonus | integer | required |
logo_dark | text | added on open |
teams
The constructors: prestige, money, colours and logos.
| Column | Type | |
|---|---|---|
id | integer | required |
category_id | integer | required |
name | varchar | required |
car | text | required |
logo | text | required |
icon | text | required |
prestige | integer | required |
wealthiness | integer | required |
planning | integer | required |
primary_color | varchar | required |
secondary_color | varchar | required |
points | integer | required |
wdc | integer | required |
on_primary_color | varchar | required |
wcc | integer | required |
relationship | integer | required |
on_secondary_color | varchar | added on open |
logo_dark | text | added on open |
icon_dark | text | added on open |
track_decorations
Scenery. Added by a migration; only backfilled from our artwork for careers descended from the bundled file.
A migration creates this table on the phone, so a file without it still imports.
| Column | Type | |
|---|---|---|
id | integer | |
track_id | integer | |
type | varchar | |
x | real | |
y | real | |
rotation | real | |
z | integer | |
info | text |
track_knots
The racing line, as a curve of positioned knots.
| Column | Type | |
|---|---|---|
id | integer | required |
track_id | integer | required |
position_x | real | required |
position_y | real | required |
position_z | real | required |
tangent_in_x | real | required |
tangent_in_y | real | required |
tangent_in_z | real | required |
tangent_out_x | real | required |
tangent_out_y | real | required |
tangent_out_z | real | required |
rotation_x | real | required |
rotation_y | real | required |
rotation_z | real | required |
rotation_w | real | required |
track_pit_knots
The pit lane, as a curve of its own.
| Column | Type | |
|---|---|---|
id | integer | required |
track_id | integer | required |
position_x | real | required |
position_y | real | required |
position_z | real | required |
tangent_in_x | real | required |
tangent_in_y | real | required |
tangent_in_z | real | required |
tangent_out_x | real | required |
tangent_out_y | real | required |
tangent_out_z | real | required |
rotation_x | real | required |
rotation_y | real | required |
rotation_z | real | required |
rotation_w | real | required |
track_sectors
Where each sector ends, as an index into the knots.
| Column | Type | |
|---|---|---|
id | integer | required |
track_id | integer | required |
knot_end | integer | required |
tracks
The circuit: grip, wear, scale, and the four pit markers.
| Column | Type | |
|---|---|---|
id | integer | required |
image | varchar | required |
grid_spacing | real | required |
tire_degradation | int | required |
fuel_consumption | int | required |
pit_knot_start | int | required |
pit_knot_end | int | required |
pit_knot_stop | int | required |
pixel_per_meter | real | required |
pit_knot_lap | int | required |
left_side | tinyint | required |
bottom_side | tinyint | required |
track_type | varchar | added on open |
A few columns and two tables are added by a migration when the file is opened on the phone, so a database authored against an older game need not have them. Everything else on this list has to be there.
What the game refuses
The file is checked on import. The game stops at the first problem and shows its message, so fix them one at a time — or read the whole list first and save yourself the round trips. Every rule about the world is about category 1.
| Code | The rule | What the player sees |
|---|---|---|
missing_table | Every table below exists. | This file has no 'T' table, so it is not a game database. |
missing_column | Every required column exists. | The 'T' table has no 'C' column, which the game reads. |
schema_too_new | schema_version is at most 7. | This database was made for a newer version of the game (its format is N, this version reads up to M). Update the game to use it. |
no_category | A row in categories with id 1. | There is no category with id 1, which is where a career starts. |
too_few_teams | At least 2 teams in category 1. | Category 1 has N team(s); a grid needs at least 2. |
driver_without_team | Every driver with a team sits on a team that exists. | Driver 'D' is on team N, which does not exist. |
team_short_of_drivers | Every category 1 team has 2 drivers with status active. | Team 'T' has N active driver(s); every team needs 2 to fill its cars. |
team_short_of_cars | Every category 1 team has 2 cars. | Team 'T' has N car(s); every team needs 2. |
car_without_driver | Each car's driver is an active driver on that team. | Car N on team 'T' belongs to driver M, who is not an active driver on that team. |
driver_without_skills | Every active driver has a driver_skills row. | Driver 'D' has no row in driver_skills, so the game cannot race them. |
no_tracks | At least one track. | There are no tracks to race on. |
track_short_of_knots | Every track has at least 3 knots. | Track N has K knot(s); a track needs at least 3 to draw. |
track_without_sectors | Every track has at least one sector. | Track N has no sectors. |
sector_off_track | Every sector's knot_end is a real knot index. | Track N: sector S ends at knot E, but the track has K knots (numbered 0 to K-1). |
track_short_of_pit_knots | Every track has at least 2 pit lane knots. | Track N has K pit lane knot(s); it needs at least 2. |
pit_marker_off_track | The four pit markers index knots that exist. | Track N: pit_knot_X is V, but the track has K knots (numbered 0 to K-1). |
no_races | At least one race. | There are no races. |
race_without_track | Every race's track exists. | Race 'R' is on track N, which does not exist. |
no_calendar | At least one calendar round for category 1. | There is no race calendar for category 1: race_seasons has no rows for it. |
round_without_race | Every round's race exists. | A round in the calendar points at race N, which does not exist. |
not_sqlite | The file opens as SQLite. | This file is not a database the game can read. |
already_installed | No installed database shares its name and version. | 'N' version V is already installed. Change the version in the file if this one is different. |
What is not checked is worth knowing too. Nothing looks at values that are merely strange: a driver with every skill at 100, two knots on top of each other, a sponsor that pays nothing. The game will run all of it. These rules are the floor under a career that can be created and raced at all — the starter file is the reference for what sensible looks like.
Importing it
Main menu → Databases → Import Database. The system file picker
opens — the Files app on iOS, the document picker on Android — and both reach
your downloads, your storage and any cloud drive you have installed. Every kind
of file is offered, because .sqlite is not a file type either
platform recognises; the check that matters is the one above.
Once you pick a file the game reads it and shows what it found: the name, the version, and how many teams, drivers and circuits are in it. Adding it is a separate confirmation.
Adding is not choosing. A database you add appears in the list, and you tap it to make it the one new careers start from; with more than one installed, the game asks which to use when a career begins. Removing a database leaves every career built from it untouched — again, the career has its own copy.
The game only ever reads a file from your own device. It cannot download a database and it cannot share one, so a database travels the way any other file does.
Notes and limits
- Circuit geometry is fiddly. Knots are the curve of the track,
sectors end on a knot index, and the pit lane is a curve of its own. The four
pit_knot_*columns on a track are indices into those curves, not row ids — two of them index the track, two the pit lane. - Scenery is ours.
track_decorationsis only filled in from the game's own artwork for careers descended from the built-in database, so circuits in a database of your own have exactly the scenery you give them. - Text is per language. The decision tables carry a column per language. Only English is required; the rest are used when present and fall back to English.
- Balance lives in
settings. Every tunable the simulation reads is a row there, marked by having a comment. A rebalance with nothing else changed is a perfectly good database. - Keep the format row. Leave
schema_versionas the starter file has it. It is the app's, not yours.
Something not working?
If the game refuses a file and the message does not explain why, or a database behaves in a way this page does not describe, write to us from the support page — include the refusal message and what you changed, and we will work it out.