Compare commits

...
4 Commits
Author SHA1 Message Date
zephyr e92ce64b17 zenno: fix aptitude level type for umas
ci/woodpecker/push/zenno Pipeline failed
ci/woodpecker/push/horsebot Pipeline was successful
2026-08-21 15:34:39 -04:00
zephyr 8d2a0e6c0d zenno/doc/mdb: include succession_initial_factor 2026-08-21 15:31:22 -04:00
zephyr 6b8b494739 zenno/doc/mdb: divide support card docs into sections 2026-08-21 15:12:42 -04:00
zephyr d8d9ec6543 zenno/doc/mdb: document sparks 2026-08-21 15:02:57 -04:00
2 changed files with 310 additions and 13 deletions
+12 -12
View File
@@ -1,3 +1,5 @@
import * as race from '$lib/race';
/**
* Uma or character card definitions.
*/
@@ -21,16 +23,16 @@ export interface Uma {
*/
variant: string;
sprint: AptitudeLevel;
mile: AptitudeLevel;
medium: AptitudeLevel;
long: AptitudeLevel;
front: AptitudeLevel;
pace: AptitudeLevel;
late: AptitudeLevel;
end: AptitudeLevel;
turf: AptitudeLevel;
dirt: AptitudeLevel;
sprint: race.AptitudeLevel;
mile: race.AptitudeLevel;
medium: race.AptitudeLevel;
long: race.AptitudeLevel;
front: race.AptitudeLevel;
pace: race.AptitudeLevel;
late: race.AptitudeLevel;
end: race.AptitudeLevel;
turf: race.AptitudeLevel;
dirt: race.AptitudeLevel;
/**
* ID of the Uma's unique skill.
@@ -66,8 +68,6 @@ export interface Uma {
skill_pl5: number;
}
export type AptitudeLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
export async function uma(): Promise<Uma[]> {
const resp = await fetch('/api/global/uma');
return resp.json();
+298 -1
View File
@@ -3,6 +3,82 @@
import Sec from '../Sec.svelte';
import Mono from '../Mono.svelte';
const sparkTypes = [
[1, 'Stat', 'spark-color-blue'],
[2, 'Aptitude', 'spark-color-pink'],
[3, 'Unique', 'spark-color-green'],
[4, 'Skill', 'spark-color-white'],
[5, 'Race', 'spark-color-white'],
[6, 'Scenario', 'spark-color-white'],
[7, 'Carnival Bonus', 'spark-color-red'],
[8, 'Distance', 'spark-color-white'],
[9, 'Hidden', 'spark-color-white'],
[10, 'Surface', 'spark-color-white'],
[11, 'Style', 'spark-color-white'],
] as const;
const sparkEffects = [
[1, 'Speed', 'Amount'],
[2, 'Stamina', 'Amount'],
[3, 'Power', 'Amount'],
[4, 'Guts', 'Amount'],
[5, 'Wit', 'Amount'],
[6, 'Skill Points', 'Amount'],
[7, 'Random Stat', 'Amount', '(always 1)'],
[11, 'Turf Aptitude', 'Levels'],
[12, 'Dirt Aptitude', 'Levels'],
[21, 'Front Runner Aptitude', 'Levels'],
[22, 'Pace Chaser Aptitude', 'Levels'],
[23, 'Late Surger Aptitude', 'Levels'],
[24, 'End Closer Aptitude', 'Levels'],
[31, 'Sprint Aptitude', 'Levels'],
[32, 'Mile Aptitude', 'Levels'],
[33, 'Medium Aptitude', 'Levels'],
[34, 'Long Aptitude', 'Levels'],
[41, 'Skill Hint', 'Skill ID', 'Hint Levels'],
[51, 'Carnival Bonus', 'Skill ID', '(always 1)'],
[61, 'Max Speed', 'Amount'],
[62, 'Max Stamina', 'Amount'],
[63, 'Max Power', 'Amount'],
[64, 'Max Guts', 'Amount'],
[65, 'Max Wit', 'Amount'],
] as const;
const lovelySpringBreeze = [
[1469, 107401, 1, 41, 900741, 1],
[2521, 107401, 1, 62, 1, 0],
[2523, 107401, 1, 64, 1, 0],
[2522, 107401, 1, 65, 1, 0],
[1470, 107401, 2, 41, 900741, 2],
[2524, 107401, 2, 62, 2, 0],
[2526, 107401, 2, 64, 1, 0],
[2525, 107401, 2, 65, 1, 0],
[1471, 107401, 3, 41, 900741, 2],
[2528, 107401, 3, 62, 2, 0],
[2530, 107401, 3, 64, 1, 0],
[2529, 107401, 3, 65, 2, 0],
[2527, 107401, 4, 41, 900741, 3],
[2532, 107401, 4, 62, 2, 0],
[2534, 107401, 4, 64, 2, 0],
[2533, 107401, 4, 65, 2, 0],
] as const;
const successionInitialFactor = [
[1, 1, 1, 0, 5],
[2, 1, 2, 0, 12],
[3, 1, 3, 0, 21],
[4, 2, 1, 3, 1],
[5, 2, 4, 6, 2],
[6, 2, 7, 9, 3],
[7, 2, 10, 999, 4],
[8, 1, 1, 1, 4],
[9, 1, 2, 1, 9],
[10, 1, 3, 1, 16],
[11, 3, 1, 1, 0],
[12, 3, 2, 2, 0],
[13, 3, 3, 4, 0],
] as const;
const supportCardEffects = [
[1, 'Friendship Bonus'],
[2, 'Mood Effect'],
@@ -96,11 +172,196 @@
>, but a few categories that have useful strings are missing from there.
</p>
<Sec h={2} id="supports">Support cards</Sec>
<Sec h={2} id="sparks">Sparks</Sec>
<p>
Internally called succession factors. Relevant <Mono>text_data</Mono> categories include 147 for spark names and 172 for spark descriptions,
both indexed by factor ID.
</p>
<Sec h={3} id="succession_factor">Spark Data</Sec>
<p>Queries should join with <Mono>succession_factor</Mono> inside.</p>
<ul class="ml-4 list-disc pb-4">
<li>Spark ID is <Mono>factor_id</Mono>. This identifies the combination of spark variety and its star level.</li>
<li>
<Mono>factor_group_id</Mono> gives the variety. E.g., the star levels of the February S. spark are factor IDs 1000101, 1000102,
and 1000103, but all three have group ID 10001.
</li>
<li><Mono>rarity</Mono> is the star level, 1-indexed.</li>
<li><Mono>grade</Mono> is 2 for unique (green) sparks and 1 otherwise.</li>
<li>
<Mono>factor_type</Mono> is roughly the color type of the spark plus extra subdivisions for white sparks:
<table class="table-fixed border text-center">
<thead>
<tr>
<th scope="col" class="px-2">Type ID</th>
<th scope="col" class="px-2">Spark Type</th>
<th scope="col" class="px-2">Color</th>
</tr>
</thead>
<tbody>
{#each sparkTypes as [typ, name, cls] (typ)}
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
<td>{typ}</td>
<td>{name}</td>
<td><div class={['bg-spark mx-auto h-4 w-4 border', cls]}></div></td>
</tr>
{/each}
</tbody>
</table>
Types 8 and above should release with 4anni.
</li>
<li>
<Mono>effect_group_id</Mono> may give something like the distribution of spark effects. For current Global data, it's in bijection
with <Mono>factor_type</Mono> &times; <Mono>rarity</Mono>. It doesn't join with anything else in the mdb.
</li>
</ul>
<Sec h={3} id="succession_factor_effect">Spark Effects</Sec>
<p>
<Mono>succession_factor_effect</Mono> defines all possible effects that each spark can yield (but not their distributions). Effects
are organized by <Mono>factor_group_id</Mono> rather than by <Mono>factor_id</Mono>, which implies to some degree that all
star levels of a given spark have the same possible results with different distributions, although it is possible that some
values have zero probability for some star levels.
</p>
<p>
The process by which the game determines the effects of a given spark proc during (Classic and Senior) inspiration is as
follows, or semantically equivalent.
</p>
<ol class="ml-4 list-decimal pb-4">
<li>
The server chooses a random <Mono>effect_id</Mono> from the hidden distribution for the spark's <Mono>effect_group_id</Mono
>.
</li>
<li>
The client (and server) selects <i>all</i> rows matching the spark's <Mono>factor_group_id</Mono> and the random rolled <Mono
>effect_id</Mono
>, i.e. <Mono
>SELECT target_type, value_1, value_2 FROM succession_factor_effect WHERE factor_group_id = $current_spark_factor_group_id
AND effect_id = $random_choice_effect</Mono
>. There may be several such effects.
</li>
<li>
For each result row, apply the effect according to the <Mono>target_type</Mono>, with <Mono>value_1</Mono> and <Mono
>value_2</Mono
> as its possible arguments:
<table class="table-fixed border text-center">
<thead>
<tr>
<th scope="col" class="px-2"><Mono>target_type</Mono></th>
<th scope="col" class="px-2">Description</th>
<th scope="col" class="px-2"><Mono>value_1</Mono> Usage</th>
<th scope="col" class="px-2"><Mono>value_2</Mono> Usage</th>
</tr>
</thead>
<tbody>
{#each sparkEffects as [target, name, val1, val2] (target)}
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
<td>{target}</td>
<td>{name}</td>
<td>{val1}</td>
<td>{val2}</td>
</tr>
{/each}
</tbody>
</table>
When effect 41 applies to a skill which is already at its maximum hint value (including from previous spark procs in the same
inspiration), a small amount (1-5, perhaps?) of some number (one? two?) of random stats is applied instead, but the details of
this are not known.
</li>
</ol>
<p>
E.g., <a
href="https://hakuraku.moe/masterdata?q=SELECT+*+FROM+%22succession_factor_effect%22+WHERE+factor_group_id+%3D+107401+ORDER+BY+factor_group_id%2C+effect_id%2C+target_type"
target="_blank"
rel="noopener noreferrer">all <Mono>succession_factor_effect</Mono> data for Lovely Spring Breeze</a
> (Mejiro Bright's green spark) is:
</p>
<table class="mb-4 table-fixed border text-center">
<caption><Mono>succession_factor_effect</Mono></caption>
<thead>
<tr>
<th scope="col" class="px-2"><Mono>id</Mono></th>
<th scope="col" class="px-2"><Mono>factor_group_id</Mono></th>
<th scope="col" class="px-2"><Mono>effect_id</Mono></th>
<th scope="col" class="px-2"><Mono>target_type</Mono></th>
<th scope="col" class="px-2"><Mono>value_1</Mono></th>
<th scope="col" class="px-2"><Mono>value_2</Mono></th>
</tr>
</thead>
<tbody>
{#each lovelySpringBreeze as [id, group, effect, typ, val1, val2] (id)}
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
<td>{id}</td>
<td>{group}</td>
<td>{effect}</td>
<td>{typ}</td>
<td>{val1}</td>
<td>{val2}</td>
</tr>
{/each}
</tbody>
</table>
<p>
When the spark procs, the server rolls an effect ID of 1, 2, 3, or 4 according to some hidden distribution, then it applies
all four effects with that effect ID.
</p>
<Sec h={3} id="succession_initial_factor">Initial Inspiration Effects</Sec>
<p>
<Mono>succession_initial_factor</Mono> defines thresholds for initial inspiration, i.e. the immediate effects of sparks upon starting
a run. There is not much consistency to its format, but it has only thirteen rows, reproduced here.
</p>
<table class="mb-4 table-fixed border text-center">
<caption><Mono>succession_initial_factor</Mono></caption>
<thead>
<tr>
<th scope="col" class="px-2"><Mono>id</Mono></th>
<th scope="col" class="px-2"><Mono>factor_type</Mono></th>
<th scope="col" class="px-2"><Mono>value_1</Mono></th>
<th scope="col" class="px-2"><Mono>value_2</Mono></th>
<th scope="col" class="px-2"><Mono>add_point</Mono></th>
</tr>
</thead>
<tbody>
{#each successionInitialFactor as [id, typ, val1, val2, add] (id)}
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
<td>{id}</td>
<td>{typ}</td>
<td>{val1}</td>
<td>{val2}</td>
<td>{add}</td>
</tr>
{/each}
</tbody>
</table>
<p>
There are six rows with <Mono>factor_type = 1</Mono>, referring to blue sparks.
<Mono>value_1</Mono> refers to the star level of each individual spark.
<Mono>value_2</Mono> identifies whether the effect applies to starting stats (0) or raised max stats (1).
<Mono>add_point</Mono> is the amount to add to the respective field.
</p>
<p>
Pink sparks, i.e. <Mono>factor_type = 2</Mono>, have four rows.
<Mono>value_1</Mono> is the lower threshold of total star count, and <Mono>value_2</Mono> is the upper threshold.
<Mono>add_point</Mono> is the number of levels to raise the corresponding aptitude.
</p>
<p>
<Mono>factor_type = 3</Mono> for unique sparks has three rows.
<Mono>add_point</Mono> is always 0. The (<Mono>value_1</Mono>, <Mono>value_2</Mono>) pairs are (1, 1), (2, 2), and (3, 4), but
the meaning is unclear; all rows for this factor type were added in the 1 Jul patch that introduced raised stat caps, so one
would expect it to be related to those. (In particular, it does not appear to be related to the starting skill hints.)
</p>
<p>
In all cases, there is no direct association between the spark and its actual initial effects. They must be derived from the
spark's normal effects instead.
</p>
<Sec h={2} id="supports">Support Cards</Sec>
<p>
Relevant <Mono>text_data</Mono> categories include 75 for name including variant, 76 for variant alone, 77 for character name. Category
151 gives support card effect names, 154 gives effect descriptions, 150 gives unique effect names, and 155 gives unique effect descriptions.
</p>
<Sec h={3} id="support_card_data">Support Card Data</Sec>
<p>
Queries should join with <Mono>support_card_data</Mono> inside.
</p>
@@ -131,6 +392,8 @@
<li><Mono>outing_max</Mono> is the number of recreation events with the card, for pals and groups.</li>
<li><Mono>effect_id</Mono> is the specific instance of Pure Passion the card can grant, for groups.</li>
</ul>
<Sec h={3} id="support_card_effect_table">Support Card Effects</Sec>
<p>
<Mono>support_card_effect_table</Mono> gives progressions of support card stats. There is one row per stat per support card. Unique
effects are not included.
@@ -163,6 +426,8 @@
to no interpolation).
</li>
</ul>
<Sec h={3} id="support_card_unique_effect">Unique Effects</Sec>
<p>Unique effect data is in <Mono>support_card_unique_effect</Mono>.</p>
<ul class="ml-4 list-disc pb-4">
<li>
@@ -254,6 +519,8 @@
</ul>
</li>
</ul>
<Sec h={3} id="single_mode_hint_gain">Hints</Sec>
<p>
Lastly, the table <Mono>single_mode_hint_gain</Mono> lists the effects of hints during career.
</p>
@@ -285,3 +552,33 @@
</li>
</ul>
</Article>
<style>
.spark-color-white {
--spark-color: #e1e2e1;
}
.spark-color-blue {
--spark-color: #37b9f4;
}
.spark-color-pink {
--spark-color: #ff78b2;
}
.spark-color-green {
--spark-color: #91d02e;
}
.spark-color-red {
--spark-color: #f46052;
}
.bg-spark {
background-color: var(--spark-color);
}
.fg-spark {
color: var(--spark-color);
}
</style>