Files
horse/cmd/racedb/schema-00.sql
T
zephyr c43f6b8292
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
cmd/racedb: program to load races into an sqlite db
2026-10-06 21:00:37 -04:00

235 lines
7.7 KiB
SQL

-- trained_chara lists horses who appear in races.
CREATE TABLE IF NOT EXISTS trained_chara (
-- id is the DB-internal ID of the Uma.
-- It does not come from the game and should not be supplied in DDL.
id INTEGER PRIMARY KEY,
trainer TEXT NOT NULL,
trainer_id INTEGER NOT NULL, -- 0 for NPC umas e.g. in practice races
trained_chara_id INTEGER NOT NULL,
chara_id INTEGER NOT NULL,
chara_name TEXT NOT NULL,
-- card_id is the Uma herself, e.g. 100201 for [Innocent Silence] Silence Suzuka.
card_id INTEGER NOT NULL,
rarity INTEGER NOT NULL,
mob_id INTEGER NOT NULL, -- 0 for Umas that are not mobs
-- Raw stats.
raw_speed INTEGER NOT NULL,
raw_stamina INTEGER NOT NULL,
raw_power INTEGER NOT NULL,
raw_guts INTEGER NOT NULL,
raw_wit INTEGER NOT NULL,
-- Aptitudes.
turf INTEGER NOT NULL,
dirt INTEGER NOT NULL,
sprint INTEGER NOT NULL,
mile INTEGER NOT NULL,
medium INTEGER NOT NULL,
long INTEGER NOT NULL,
front_runner INTEGER NOT NULL,
pace_chaser INTEGER NOT NULL,
late_surger INTEGER NOT NULL,
end_closer INTEGER NOT NULL,
-- Other data.
fans INTEGER NOT NULL,
rank INTEGER NOT NULL,
rank_score INTEGER NOT NULL,
UNIQUE (trainer_id, trained_chara_id)
) STRICT;
-- Insert trained chara ID 0 to represent no Uma.
INSERT OR IGNORE INTO trained_chara (
id,
trainer,
trainer_id,
trained_chara_id,
chara_id, chara_name,
card_id,
mob_id,
raw_speed, raw_stamina, raw_power, raw_guts, raw_wit,
turf, dirt,
sprint, mile, medium, long,
front_runner, pace_chaser, late_surger, end_closer,
fans,
rank, rank_score
)
VALUES (0, '', 0, 0, 0, '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-- trained_chara_skill lists the skills each observed horse owns.
CREATE TABLE IF NOT EXISTS trained_chara_skill (
trained_chara INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
skill_id INTEGER NOT NULL,
level INTEGER NOT NULL,
UNIQUE (trained_chara, skill_id)
) STRICT;
CREATE INDEX IF NOT EXISTS trained_chara_skill_by_trained_chara ON trained_chara_skill (trained_chara);
-- race_course_set is the accumulated information of observed race courses.
CREATE TABLE IF NOT EXISTS race_course_set (
id INTEGER PRIMARY KEY,
race_track_id INTEGER NOT NULL,
distance INTEGER NOT NULL,
ground INTEGER NOT NULL,
inout INTEGER NOT NULL,
turn INTEGER NOT NULL,
fence_set INTEGER NOT NULL,
float_lane_max INTEGER NOT NULL,
course_set_status_id INTEGER NOT NULL,
finish_time_min INTEGER NOT NULL,
finish_time_min_random_range INTEGER NOT NULL,
finish_time_max INTEGER NOT NULL,
finish_time_max_random_range INTEGER NOT NULL,
section_distance REAL NOT NULL,
distance_type INTEGER NOT NULL,
furlong_number INTEGER NOT NULL,
base_speed REAL NOT NULL
) STRICT;
-- race_config is observed configurations of races including the race type.
CREATE TABLE IF NOT EXISTS race_config (
-- id is the DB-internal ID of the race config.
id INTEGER PRIMARY KEY,
type INTEGER NOT NULL,
course_set_id INTEGER NOT NULL REFERENCES race_course_set (id) ON DELETE RESTRICT,
ground_condition INTEGER NOT NULL,
weather INTEGER NOT NULL,
season INTEGER NOT NULL,
time INTEGER NOT NULL,
num_horse INTEGER NOT NULL,
UNIQUE (type, course_set_id, ground_condition, weather, season, time, num_horse)
) STRICT;
CREATE INDEX IF NOT EXISTS race_config_by_type ON race_config (type);
-- race is all observed races.
CREATE TABLE IF NOT EXISTS race (
-- id is the DB-internal ID of the race.
id INTEGER PRIMARY KEY,
config_id INTEGER NOT NULL REFERENCES race_config (id),
seed INTEGER NOT NULL,
distance_diff_max REAL NOT NULL,
frame_count INTEGER NOT NULL,
-- There is no consistent ID for races, and even race seeds have been found
-- to collide well above the expected rate for a uniform distribution.
-- In order to prevent adding duplicates of races each time the tool is run,
-- we include the list of all horse IDs present in the race.
-- Analysis on the horses in the race should instead use the race_horse table.
-- Horse entries here are 0 where there is actually no horse at that gate.
horse_1 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_2 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_3 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_4 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_5 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_6 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_7 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_8 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_9 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_10 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_11 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_12 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_13 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_14 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_15 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_16 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_17 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_18 INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
UNIQUE (
config_id,
seed,
horse_1,
horse_2,
horse_3,
horse_4,
horse_5,
horse_6,
horse_7,
horse_8,
horse_9,
horse_10,
horse_11,
horse_12,
horse_13,
horse_14,
horse_15,
horse_16,
horse_17,
horse_18
)
) STRICT;
CREATE INDEX IF NOT EXISTS race_by_config ON race (config_id);
-- race_horse pairs each instance of a horse with its condition and performance
-- in a given race.
CREATE TABLE IF NOT EXISTS race_horse (
race INTEGER NOT NULL REFERENCES race (id) ON DELETE CASCADE,
horse INTEGER NOT NULL REFERENCES trained_chara (id) ON DELETE CASCADE,
horse_index INTEGER NOT NULL,
post INTEGER NOT NULL,
finish_order INTEGER NOT NULL,
finish_time_raw REAL NOT NULL,
finish_time_scaled REAL NOT NULL,
finish_diff_time_from_prev REAL NOT NULL,
running_style INTEGER NOT NULL,
running_style_ex INTEGER NOT NULL,
active_distance_aptitude INTEGER NOT NULL,
active_surface_aptitude INTEGER NOT NULL,
mood INTEGER NOT NULL,
mood_coef REAL NOT NULL,
base_speed REAL NOT NULL,
base_stamina REAL NOT NULL,
base_power REAL NOT NULL,
base_guts REAL NOT NULL,
base_wit REAL NOT NULL,
popularity INTEGER NOT NULL,
popularity_rank_left INTEGER NOT NULL,
popularity_rank_center INTEGER NOT NULL,
popularity_rank_right INTEGER NOT NULL,
start_delay REAL NOT NULL,
spurt_start_distance REAL NOT NULL,
PRIMARY KEY (race, horse),
UNIQUE (race, horse_index),
CHECK (horse != 0)
) STRICT;
-- race_frame holds the actual received frames.
CREATE TABLE IF NOT EXISTS race_frame (
race INTEGER NOT NULL REFERENCES race (id) ON DELETE CASCADE,
frame_time REAL NOT NULL,
horse_index INTEGER NOT NULL,
distance REAL NOT NULL,
lane INTEGER NOT NULL, -- scale -4
speed INTEGER NOT NULL, -- scale -2
hp INTEGER NOT NULL,
temptation INTEGER NOT NULL,
block_front_horse_index INTEGER NOT NULL,
PRIMARY KEY (race, frame_time, horse_index)
) STRICT;
-- race_event holds raw received race events.
-- Views such as race_event_skill_activate, race_event_spot_struggle_activate, &c.
-- interpret events per type.
CREATE TABLE IF NOT EXISTS race_event (
race INTEGER NOT NULL REFERENCES race (id) ON DELETE CASCADE,
frame_time REAL NOT NULL,
type INTEGER NOT NULL,
param_0 INTEGER,
param_1 INTEGER,
param_2 INTEGER,
param_3 INTEGER,
param_4 INTEGER,
param_5 INTEGER
) STRICT;
CREATE INDEX IF NOT EXISTS race_event_by_race ON race_event (race);
CREATE INDEX IF NOT EXISTS race_event_by_type ON race_event (type);