From d8d9ec65438b6d9d369bcb3a4f0304c7db0ab4c7 Mon Sep 17 00:00:00 2001
From: Branden J Brown
Date: Fri, 21 Aug 2026 15:02:57 -0400
Subject: [PATCH] zenno/doc/mdb: document sparks
---
zenno/src/routes/doc/mdb/+page.svelte | 248 ++++++++++++++++++++++++++
1 file changed, 248 insertions(+)
diff --git a/zenno/src/routes/doc/mdb/+page.svelte b/zenno/src/routes/doc/mdb/+page.svelte
index 5606ad9..c3158b3 100644
--- a/zenno/src/routes/doc/mdb/+page.svelte
+++ b/zenno/src/routes/doc/mdb/+page.svelte
@@ -3,6 +3,66 @@
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 supportCardEffects = [
[1, 'Friendship Bonus'],
[2, 'Mood Effect'],
@@ -96,6 +156,164 @@
>, but a few categories that have useful strings are missing from there.
+ Sparks
+
+ Internally called succession factors. Relevant text_data categories include 147 for spark names and 172 for spark descriptions,
+ both indexed by factor ID.
+
+ Spark Data
+ Queries should join with succession_factor inside.
+
+ - Spark ID is factor_id. This identifies the combination of spark variety and its star level.
+ -
+ factor_group_id 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.
+
+ - rarity is the star level, 1-indexed.
+ - grade is 2 for unique (green) sparks and 1 otherwise.
+ -
+ factor_type is roughly the color type of the spark plus extra subdivisions for white sparks:
+
+
+
+ | Type ID |
+ Spark Type |
+ Color |
+
+
+
+ {#each sparkTypes as [typ, name, cls] (typ)}
+
+ | {typ} |
+ {name} |
+ |
+
+ {/each}
+
+
+ Types 8 and above should release with 4anni.
+
+ -
+ effect_group_id may give something like the distribution of spark effects. For current Global data, it's in bijection
+ with factor_type × rarity. It doesn't join with anything else in the mdb.
+
+
+ Spark Effects
+
+ succession_factor_effect defines all possible effects that each spark can yield (but not their distributions). Effects
+ are organized by factor_group_id rather than by factor_id, 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.
+
+
+ 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.
+
+
+ -
+ The server chooses a random effect_id from the hidden distribution for the spark's effect_group_id.
+
+ -
+ The client (and server) selects all rows matching the spark's factor_group_id and the random rolled effect_id, i.e. 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. There may be several such effects.
+
+ -
+ For each result row, apply the effect according to the target_type, with value_1 and value_2 as its possible arguments:
+
+
+
+ | target_type |
+ Description |
+ value_1 Usage |
+ value_2 Usage |
+
+
+
+ {#each sparkEffects as [target, name, val1, val2] (target)}
+
+ | {target} |
+ {name} |
+ {val1} |
+ {val2} |
+
+ {/each}
+
+
+ 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.
+
+
+
+ E.g., all succession_factor_effect data for Lovely Spring Breeze (Mejiro Bright's green spark) is:
+
+
+
+
+ | id |
+ factor_group_id |
+ effect_id |
+ target_type |
+ value_1 |
+ value_2 |
+
+
+
+ {#each lovelySpringBreeze as [id, group, effect, typ, val1, val2] (id)}
+
+ | {id} |
+ {group} |
+ {effect} |
+ {typ} |
+ {val1} |
+ {val2} |
+
+ {/each}
+
+
+
+ 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.
+
+
+ Initial Inspiration Effects
+
+ succession_initial_factor 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.
+
+
+ There are six rows with factor_type = 1, referring to blue sparks.
+ value_1 refers to the star level of each individual spark.
+ value_2 identifies whether the effect applies to starting stats (0) or raised max stats (1).
+ add_point is the amount to add to the respective field.
+
+
+ Pink sparks, i.e. factor_type = 2, have four rows.
+ value_1 is the lower threshold of total star count, and value_2 is the upper threshold.
+ add_point is the number of levels to raise the corresponding aptitude.
+
+
+ factor_type = 3 for unique sparks has three rows.
+ add_point is always 0. The (value_1, value_2) 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 overcapped stats, so one
+ would expect it to related to those. (In particular, it does not appear to be related to the starting skill hints.)
+
+
+ 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.
+
+
Support cards
Relevant text_data categories include 75 for name including variant, 76 for variant alone, 77 for character name. Category
@@ -285,3 +503,33 @@
+
+