zenno: use data from api

This commit is contained in:
2026-06-05 14:31:10 -04:00
parent 871fd5fdcc
commit a848c8eb72
15 changed files with 369 additions and 322 deletions

View File

@@ -44,7 +44,7 @@ func main() {
level slog.Level
textfmt string
)
flag.StringVar(&addr, "http", ":80", "`address` to bind HTTP server")
flag.StringVar(&addr, "http", ":13669", "`address` to bind HTTP server")
flag.StringVar(&mdbf, "mdb", "", "`path` to master.mdb")
flag.StringVar(&public, "public", "", "`dir`ectory containing the website to serve")
flag.StringVar(&tokenFile, "token", "", "`file` containing the Discord bot token")
@@ -154,7 +154,7 @@ func main() {
}
srv := http.Server{
Addr: addr,
Handler: mux,
Handler: httpmiddle.Logger(mux),
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
BaseContext: func(l net.Listener) context.Context { return ctx },

View File

@@ -4,7 +4,7 @@
interface Props {
id: string;
characters: Character[];
characters: Character[] | null;
value: number;
class?: ClassValue | null;
optionClass?: ClassValue | null;
@@ -18,7 +18,7 @@
{#if !required}
<option value="0" class={optionClass}></option>
{/if}
{#each characters as c (c.chara_id)}
{#each characters ?? [] as c (c.chara_id)}
<option value={c.chara_id} class={optionClass}>{c.name}</option>
{/each}
</select>

View File

@@ -3,39 +3,37 @@
ABILITY_SCALE_NAME,
ABILITY_TYPE_FORMAT,
DURATION_SCALE_NAME,
skills,
Target,
TARGET_FORMAT,
tenThousandths,
ZERO_SKILL,
type Ability,
type Skill,
} from './data/skill';
interface CommonProps {
hint?: string;
interface Props {
skill: Skill | null | undefined;
mention?: boolean;
}
type Props = CommonProps & ({ skill: number; name?: never } | { name: string; skill?: never });
const ZERO_SKILL: Skill = {
skill_id: 0,
name: 'Skill data is loading...',
description: 'Skill data is still loading, or else something went wrong.',
group: 0,
rarity: 1,
group_rate: 1,
wit_check: false,
activations: [],
icon_id: 0,
};
let { hint, mention, skill, name }: Props = $props();
let { mention, skill }: Props = $props();
function splitCond(c: string): string[] {
return c.replaceAll('&', ' & ').split('@');
}
const s: Readonly<Skill> = $derived.by(() => {
const l =
skill != null ? skills.global.filter((s) => s.skill_id === skill) : skills.global.filter((s) => s.name.includes(name!));
if (name != null) {
console.warn(`skills specified as ${name} (${hint}):`, l);
}
if (l.length === 0) {
return ZERO_SKILL;
}
return l[0];
});
const s = $derived(skill ?? ZERO_SKILL);
const activationClass = $derived(s.activations.length === 1 ? null : 'block my-2 border rounded-md');
const spanClass = $derived(mention ? 'italic' : 'font-bold');

View File

@@ -1,19 +1,17 @@
<script lang="ts">
import { sparks } from '$lib/data/spark';
import { type Spark } from '$lib/data/spark';
interface Props {
spark: number;
region?: keyof typeof sparks;
spark: Spark | null | undefined;
}
const { spark, region = 'global' }: Props = $props();
const { spark }: Props = $props();
const cur = $derived(sparks[region].find((s) => s.spark_id === spark));
const curClass = $derived.by(() => {
if (cur == null) {
if (spark == null) {
return [];
}
switch (cur.type) {
switch (spark.type) {
case 1:
return ['stat'];
case 2:
@@ -32,17 +30,17 @@
return [];
}
});
const stars = $derived('★'.repeat(cur?.rarity ?? 0));
const stars = $derived('★'.repeat(spark?.rarity ?? 0));
</script>
{#if cur != null}
{#if spark != null}
<div
class={[
curClass,
'spark mx-1 flex items-center rounded-xl px-2 py-1 transition ease-in hover:shadow-md hover:ease-out motion-safe:duration-75 motion-safe:hover:-translate-y-0.5 dark:shadow-neutral-950',
]}
>
<span>{cur.name}</span>
<span>{spark.name}</span>
<span class="ml-2 text-xl text-amber-800 text-shadow-md dark:text-amber-300">{stars}</span>
</div>
{/if}

View File

@@ -1,5 +1,3 @@
import globalJSON from '../../../../global/affinity.json';
/**
* Precomputed character pair and trio affinity.
*/
@@ -24,9 +22,10 @@ export interface Affinity {
affinity: number;
}
export const affinity = {
global: globalJSON as Affinity[],
} as const;
export async function affinity(): Promise<Affinity[]> {
const resp = await fetch('/api/global/affinity');
return resp.json();
}
export function lookup(aff: Affinity[], chara_a: number, chara_b: number, chara_c?: number): number {
const [a, b, c] = [chara_a, chara_b, chara_c ?? Infinity].sort((a, b) => a - b);

View File

@@ -1,5 +1,4 @@
import type { RegionalName } from '$lib/regional-name';
import globalJSON from '../../../../global/character.json';
/**
* Character definitions.
@@ -16,11 +15,11 @@ export interface Character {
name: string;
}
export const character = {
global: globalJSON as Character[],
};
export async function character(): Promise<Character[]> {
const resp = await fetch('/api/global/character');
return resp.json();
}
export const charaNames = globalJSON.reduce(
(m, c) => m.set(c.chara_id, { en: c.name }),
new Map<Character['chara_id'], RegionalName>(),
);
export function charaNames(charas: Character[]) {
return charas.reduce((m, c) => m.set(c.chara_id, { en: c.name }), new Map<number, RegionalName>());
}

View File

@@ -1,5 +1,4 @@
import type { RegionalName } from '$lib/regional-name';
import globalJSON from '../../../../global/conversation.json';
/**
* Lobby conversation data.
@@ -17,10 +16,6 @@ export interface Conversation {
* Location ID of the conversation.
*/
location: 110 | 120 | 130 | 210 | 220 | 310 | 410 | 420 | 430 | 510 | 520 | 530;
/**
* English name of the location, for convenience.
*/
location_name: string;
/**
* First character in the conversation.
* Not necessarily equal to chara_id.
@@ -40,16 +35,17 @@ export interface Conversation {
condition_type: 0 | 1 | 2 | 3 | 4;
}
export const conversation = {
global: globalJSON as Conversation[],
};
export async function conversation(): Promise<Conversation[]> {
const resp = await fetch('/api/global/conversation');
return resp.json();
}
export const byChara = {
global: globalJSON.reduce(
export function byChara(convos: Conversation[]) {
return convos.reduce(
(m, c) => m.set(c.chara_id, (m.get(c.chara_id) ?? []).concat(c as Conversation)),
new Map<Conversation['chara_id'], Conversation[]>(),
),
};
new Map<number, Conversation[]>(),
);
}
export const locations: Record<Conversation['location'], { name: RegionalName; group: 1 | 2 | 3 | 4 | 5 }> = {
110: { name: { en: 'right side front' }, group: 1 },
@@ -74,12 +70,12 @@ function locCharas(convos: Conversation[], locGroup: 1 | 2 | 3 | 4 | 5) {
return [...m].toSorted((a, b) => b[1] - a[1]); // descending
}
export const groupPopulars = {
global: {
1: locCharas(conversation.global, 1),
2: locCharas(conversation.global, 2),
3: locCharas(conversation.global, 3),
4: locCharas(conversation.global, 4),
5: locCharas(conversation.global, 5),
},
};
export function groupPopulars(convos: Conversation[]) {
return {
1: locCharas(convos, 1),
2: locCharas(convos, 2),
3: locCharas(convos, 3),
4: locCharas(convos, 4),
5: locCharas(convos, 5),
};
}

View File

@@ -1,6 +1,3 @@
import skillGlobal from '../../../../global/skill.json';
import groupGlobal from '../../../../global/skill-group.json';
/**
* Skill data.
*/
@@ -323,22 +320,12 @@ export interface SkillGroup {
skill_bad?: number;
}
export const skills = {
global: skillGlobal as Skill[],
} as const;
export async function skills(): Promise<Skill[]> {
const resp = await fetch('/api/global/skill');
return resp.json();
}
export const skillGroups = {
global: groupGlobal as SkillGroup[],
} as const;
export const ZERO_SKILL: Readonly<Skill> = {
skill_id: 0,
name: 'invalid skill',
description: 'an invalid skill was specified',
group: 0,
rarity: 1,
group_rate: 1,
wit_check: false,
activations: [],
icon_id: 0,
} as const;
export async function skillGroups(): Promise<SkillGroup[]> {
const resp = await fetch('/api/global/skill-group');
return resp.json();
}

View File

@@ -1,5 +1,3 @@
import globalJSON from '../../../../global/spark.json';
/**
* Sparks, or succession factors.
*/
@@ -48,6 +46,7 @@ export interface SparkEffect {
value2: number;
}
export const sparks = {
global: globalJSON as Spark[],
} as const;
export async function sparks(): Promise<Spark[]> {
const resp = await fetch('/api/global/spark');
return resp.json();
}

View File

@@ -1,5 +1,3 @@
import globalJSON from '../../../../global/uma.json';
/**
* Uma or character card definitions.
*/
@@ -70,6 +68,7 @@ export interface Uma {
export type AptitudeLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
export const uma = {
global: globalJSON as Uma[],
};
export async function uma(): Promise<Uma[]> {
const resp = await fetch('/api/global/uma');
return resp.json();
}

View File

@@ -1,30 +1,42 @@
<script lang="ts">
import { character, charaNames } from '$lib/data/character';
import { byChara, locations, groupPopulars } from '$lib/data/convo';
import { character, charaNames, type Character } from '$lib/data/character';
import { byChara, locations, groupPopulars, conversation, type Conversation } from '$lib/data/convo';
import CharaPick from '$lib/CharaPick.svelte';
import { onMount } from 'svelte';
const characters = character.global.filter((c) => byChara.global.has(c.chara_id));
let conversations: Conversation[] = $state([]);
const convoMap = $derived(byChara(conversations));
const popular = $derived(groupPopulars(conversations));
let characters: Character[] = $state([]);
const names = $derived(charaNames(characters ?? []));
const minSuggest = 8;
onMount(async () => {
const [convos, charas] = await Promise.all([conversation(), character()]);
conversations = convos;
characters = charas.filter((c) => convoMap.has(c.chara_id));
});
let charaID = $state(1001);
let convo = $state(1);
const options = $derived(byChara.global.get(charaID) ?? []);
const options = $derived(convoMap.get(charaID) ?? []);
const cur = $derived(options.find((c) => c.number === convo));
const cur1Name = $derived(cur?.chara_1 && charaNames.get(cur.chara_1)?.en);
const cur2Name = $derived(cur?.chara_2 && charaNames.get(cur.chara_2)?.en);
const cur3Name = $derived(cur?.chara_3 && charaNames.get(cur.chara_3)?.en);
const cur1Name = $derived(cur?.chara_1 && names.get(cur.chara_1)?.en);
const cur2Name = $derived(cur?.chara_2 && names.get(cur.chara_2)?.en);
const cur3Name = $derived(cur?.chara_3 && names.get(cur.chara_3)?.en);
const alone = $derived([cur?.chara_1, cur?.chara_2, cur?.chara_3].filter((x) => x != null).length == 1 ? ' alone' : '');
const suggested = $derived.by(() => {
const suggested = $derived.by(async () => {
if (cur == null) {
return [];
}
const u = groupPopulars.global[locations[cur.location].group].filter(
(s) => charaNames.get(s[0]) != null && s[0] !== cur.chara_1 && s[0] !== cur.chara_2 && s[0] !== cur.chara_3,
const u = popular[locations[cur.location].group].filter(
(s) => names.get(s[0]) != null && s[0] !== cur.chara_1 && s[0] !== cur.chara_2 && s[0] !== cur.chara_3,
);
const r = u.length <= minSuggest ? u : u.filter((s) => s[1] >= u[minSuggest][1]);
return r.map(([chara_id, count]) => ({ chara_id, count }));
return r.map(([chara_id, count]) => ({ chara_id, chara_name: names.get(chara_id), count }));
});
const curLoc = $derived(cur != null ? locations[cur.location] : null);
</script>
<h1 class="text-4xl">Lobby Conversations</h1>
@@ -42,7 +54,10 @@
</select>
</div>
</div>
{#if cur}
{#await suggested}
<div class="mt-4 w-full text-center text-3xl">Loading...</div>
{:then suggested}
{#if cur}
<div class="shadow-sm transition-shadow hover:shadow-md">
<div class="mt-8 flex text-center text-lg">
<span class="flex-1">{cur1Name}{alone}</span>
@@ -54,7 +69,7 @@
{/if}
</div>
<div class="flex w-full text-center text-lg">
<span class="flex-1">at {locations[cur.location].name.en}</span>
<span class="flex-1">at {curLoc?.name.en}</span>
</div>
</div>
<div class="mt-4 block text-center">
@@ -62,12 +77,14 @@
</div>
<div class="mt-4 grid text-center shadow-sm transition-shadow ease-in hover:shadow-md hover:ease-out md:grid-cols-4">
{#each suggested as s (s.chara_id)}
<span>{charaNames.get(s.chara_id)?.en}: {s.count}&#xd7;</span>
<span>{s.chara_name?.en}: {s.count}&#xd7;</span>
{/each}
</div>
<div class="mt-4 block text-center">
<span>
Set these characters to fixed positions (main, upgrades, story, races) to maximize the chance of getting this conversation.
Set these characters to fixed positions (main, upgrades, story, races) to maximize the chance of getting this
conversation.
</span>
</div>
{/if}
{/if}
{/await}

View File

@@ -20,13 +20,13 @@
tocViewed = true;
obs.disconnect();
}
}
};
$effect(() => {
if (tocElem == null) {
return;
}
const obs = new IntersectionObserver(observeTOC, {rootMargin: "20% 0px"});
const obs = new IntersectionObserver(observeTOC, { rootMargin: '20% 0px' });
obs.observe(tocElem);
});

View File

@@ -20,12 +20,93 @@
} from '$lib/race';
import Skill from '$lib/Skill.svelte';
import StatChart from '$lib/StatChart.svelte';
import { onMount } from 'svelte';
import Article from '../Article.svelte';
import Sec from '../Sec.svelte';
import * as skill from '$lib/data/skill';
let raceLen = $state(2000);
let secSpeedStyle = $state(RunningStyle.FrontRunner);
let allSkillsList: skill.Skill[] = $state([]);
onMount(async () => {
allSkillsList = await skill.skills();
});
const allSkills = $derived(allSkillsList.reduce((m, s) => m.set(s.skill_id, s), new Map<number, skill.Skill>()));
const skills = $derived({
view: allSkills.get(100021),
sfv: allSkills.get(100101),
uma2: allSkills.get(100321),
falcoUlt: allSkills.get(100461),
palmerUlt: allSkills.get(100641),
kfc: allSkills.get(110041),
cacao: allSkills.get(110261),
right: allSkills.get(200012),
left: allSkills.get(200022),
firm: allSkills.get(200152),
compSpirit: allSkills.get(200282),
professor: allSkills.get(200331),
cornerAdept: allSkills.get(200332),
cornerConn: allSkills.get(200341),
rushingGale: allSkills.get(200371),
conc: allSkills.get(200431),
focus: allSkills.get(200432),
centerStage: allSkills.get(200451),
pp: allSkills.get(200452),
ramp: allSkills.get(200462),
nsm: allSkills.get(200491),
nn: allSkills.get(200492),
homestretchHaste: allSkills.get(200512),
ttl: allSkills.get(200531),
earlyLead: allSkills.get(200532),
escapeArtist: allSkills.get(200541),
fastPaced: allSkills.get(200542),
unrestrained: allSkills.get(200551),
encroaching: allSkills.get(200641),
spurt: allSkills.get(200642),
turboSprint: allSkills.get(200651),
tunes: allSkills.get(200721),
greed: allSkills.get(201081),
speedEater: allSkills.get(201082),
siphon: allSkills.get(201221),
murmurGold: allSkills.get(201161),
longStraights: allSkills.get(201172),
blast: allSkills.get(201173),
straights: allSkills.get(201242),
corners: allSkills.get(201252),
sixthSense: allSkills.get(201261),
dd: allSkills.get(201262),
topRunner: allSkills.get(201271),
leadersPride: allSkills.get(201272),
moxie: allSkills.get(201282),
eyes: allSkills.get(201441),
savvy: allSkills.get(201522),
lucky7: allSkills.get(201562),
gw: allSkills.get(201601),
thh: allSkills.get(201611),
loneWolf: allSkills.get(201641),
slipstream: allSkills.get(201651),
pto: allSkills.get(201661),
risky: allSkills.get(202032),
runaway: allSkills.get(202051),
burningWIT: allSkills.get(210051),
ignitedWIT: allSkills.get(210052),
radiant: allSkills.get(210061),
redshiftInherit: allSkills.get(900041),
pulseInherit: allSkills.get(900061),
anglingInherit: allSkills.get(900201),
pumpInherit: allSkills.get(900271),
inesInherit: allSkills.get(900311),
uma2Inherit: allSkills.get(900321),
beyondInherit: allSkills.get(900591),
vcInherit: allSkills.get(900681),
pastaInherit: allSkills.get(900141),
kfcInherit: allSkills.get(910041),
barcaroleInherit: allSkills.get(910151),
cacaoInherit: allSkills.get(910261),
mummyCreekInherit: allSkills.get(910451),
});
function mean2(x: [number, number]): number {
return (x[0] + x[1]) * 0.5;
}
@@ -193,7 +274,7 @@
At the start of late race, if they have enough HP remaining for their last spurt, horses accelerate from the mid race base
target speed to their spurt speed, which varies by speed stat, distance aptitude, running style, race distance, and guts stat,
in decreasing order of effect. "Last spurt" and "last spurt phase" are different and unrelated things; the latter is only used
mechanically in the condition for <Skill skill={200512} hint="homestretch haste" mention />.
mechanically in the condition for <Skill skill={skills.homestretchHaste} mention />.
</p>
<p>
Speed skills add a flat amount of target speed, generally +0.15 m/s for white skills, +0.25 m/s for double circle skills and
@@ -204,8 +285,8 @@
<Sec h={3} id="runaway">Runaway</Sec>
<p>
The skill <Skill skill={202051} hint="runaway" /> converts front runners into the <i>Great Escape</i> running style. However,
no player has ever uttered the words "Great Escape" when talking about Umamusume, presumably because Runaway is a much cooler
The skill <Skill skill={skills.runaway} /> converts front runners into the <i>Great Escape</i> running style. However, no
player has ever uttered the words "Great Escape" when talking about Umamusume, presumably because Runaway is a much cooler
name. ("Great Escape" is a direct translation of Japanese 大逃げ <i>oonige</i>, whereas "Front Runner" is a more liberal
localization of 逃げ <i>nige</i> that technically just means "escape.")
</p>
@@ -239,32 +320,31 @@
</p>
<ul class="mb-4 list-disc pl-4">
<li>
<Skill skill={900201} hint="angling" />, sometimes called Rod, is currently the second best skill in the game. Its condition
<Skill skill={skills.anglingInherit} />, sometimes called Rod, is currently the second best skill in the game. Its condition
is to be in first place on any late race corner, which is the case immediately at the start of late race on all medium
tracks,
<a href="#niigata-1600">all but one mile</a>, and some sprints.
</li>
<li>
On long distance tracks, <Skill skill={900681} hint="vc" /> takes that role instead. The front two horses get it, and it has half
On long distance tracks, <Skill skill={skills.vcInherit} /> takes that role instead. The front two horses get it, and it has half
the acceleration value.
</li>
<li>
On those sprints where Angling is dead, the front-specific option is <Skill skill={900141} hint="pasta" /> (VPP, or Pasta). Multi-front
builds also have access to <Skill skill={910451} hint="mummy creek" /> (HCreek). It takes both of them to equal Angling, so such
sprints may be better served gambling on <Skill skill={200651} hint="turbo sprint" mention />, <Skill
skill={200371}
hint="rushing gale"
On those sprints where Angling is dead, the front-specific option is <Skill skill={skills.pastaInherit} /> (VPP, or Pasta). Multi-front
builds also have access to <Skill skill={skills.mummyCreekInherit} /> (HCreek). It takes both of them to equal Angling, so such
sprints may be better served gambling on <Skill skill={skills.turboSprint} mention />, <Skill
skill={skills.rushingGale}
mention
/>, and possibly <Skill skill={200551} hint="unrestrained" mention /> instead. Front runners are especially strong on sprints
for <a href="#spot-struggle">other reasons</a> anyway.
/>, and possibly <Skill skill={skills.unrestrained} mention /> instead. Front runners are especially strong on sprints for
<a href="#spot-struggle">other reasons</a> anyway.
</li>
</ul>
<p>
<Skill skill={200491} hint="nsm" /> is the best skill in the game. Unfortunately, for the most part, it's bad on front runners;
generally not a win condition. Activating NSM requires not being in first, which means whoever <i>was</i> used Angling and is
pulling away from you before you accumulate the blocked time to activate it. That said, on VC tracks specifically, NSM or its
white version <Skill skill={200492} hint="nn" mention /> can be an option for multi-front builds, since the two frontmost horses
get VC and final corner lane movement hasn't happened.
<Skill skill={skills.nsm} /> is the best skill in the game. Unfortunately, for the most part, it's bad on front runners; generally
not a win condition. Activating NSM requires not being in first, which means whoever <i>was</i> used Angling and is pulling
away from you before you accumulate the blocked time to activate it. That said, on VC tracks specifically, NSM or its white
version <Skill skill={skills.nn} mention /> can be an option for multi-front builds, since the two frontmost horses get VC and final
corner lane movement hasn't happened.
</p>
<Sec h={2} id="positioning">Positioning Mechanics</Sec>
@@ -357,14 +437,13 @@
/>
</div>
<p>
Front runners have access to the skill <Skill skill={201262} hint="dd" />, which forces a horse who uses it to move outward to
a specific distance from the rail. DD almost always ends shortly before the horse has finished accelerating to early race
speed, so it does not convert the move lane speed modifier into distance.
Front runners have access to the skill <Skill skill={skills.dd} />, which forces a horse who uses it to move outward to a
specific distance from the rail. DD almost always ends shortly before the horse has finished accelerating to early race speed,
so it does not convert the move lane speed modifier into distance.
</p>
<p>
We get advantage from move lane speed modifier by following DD with <Skill skill={200452} hint="pp" /> or <Skill
skill={210052}
hint="ignited wit"
We get advantage from move lane speed modifier by following DD with <Skill skill={skills.pp} /> or <Skill
skill={skills.ignitedWIT}
/>. DD created an opportunity for those return skills to convert into huge forward speed. This setup is called
<i>lane combo</i>.
</p>
@@ -379,13 +458,12 @@
an efficient pickup as a short burst of high speed to gain position.
</p>
<p>
The gold versions of lane combo skills &ndash; <Skill skill={201261} hint="gold dd" mention />, <Skill
skill={200451}
hint="gold pp"
The gold versions of lane combo skills &ndash; <Skill skill={skills.sixthSense} mention />, <Skill
skill={skills.centerStage}
mention
/>, <Skill skill={210051} hint="burning wit" mention /> &ndash; are excellent to take on parents, but they generally make lane combo
itself less effective. They have stronger lane change movement boosts, which does not affect the forward speed boost and is likely
to make it last a shorter time, since the horse will return to the rail more quickly.
/>, <Skill skill={skills.burningWIT} mention /> &ndash; are excellent to take on parents, but they generally make lane combo itself
less effective. They have stronger lane change movement boosts, which does not affect the forward speed boost and is likely to make
it last a shorter time, since the horse will return to the rail more quickly.
</p>
<p>
For the same reasons, Ignited WIT is a bit stronger than PP, because it has a <i>smaller</i> effect value and also a longer base
@@ -509,9 +587,9 @@
<p>
For the most part, there's nothing you can do about the no-overtake zone. The exception to this is with Smart Falcon, who has
a speed unique that can fire on any mid race straight. On Tokyo 1600 (both turf and dirt), the first corner is far enough into
mid race that <Skill skill={100461} hint="falco ult" /> is likely to fire before entering the no-overtake zone, helping to propel
her into a lead that other front runners can't challenge until the corner begins &ndash; which is especially strong because it's
harder to pass on corners, and on those tracks, that corner lasts all the way into late race.
mid race that <Skill skill={skills.falcoUlt} /> is likely to fire before entering the no-overtake zone, helping to propel her into
a lead that other front runners can't challenge until the corner begins &ndash; which is especially strong because it's harder to
pass on corners, and on those tracks, that corner lasts all the way into late race.
</p>
<Sec h={2} id="skills">Skills</Sec>
@@ -522,37 +600,34 @@
</p>
<ul class="mb-4 list-disc pl-4">
<li>
On miles, <Skill skill={201082} hint="speed eater" /> is the strongest speed skill in the game, because it is both a full strength
speed skill (i.e. +0.15 target speed for base 3s) and a full strength speed debuff. It plays both offense and defense simultaneously.
On miles, <Skill skill={skills.speedEater} /> is the strongest speed skill in the game, because it is both a full strength speed
skill (i.e. +0.15 target speed for base 3s) and a full strength speed debuff. It plays both offense and defense simultaneously.
Every front runner should have it on every mile. Speed Eater technically has a gold version, <Skill
skill={201081}
hint="gold speed eater"
skill={skills.greed}
mention
/>, but Cygames apparently recognized that it must not ever be allowed to exist, because there's still no source of it on
JP.
</li>
<li>
<Skill skill={201611} hint="thh" /> is a full strength speed skill that is triggered by other skills, so it excels at stacking
&ndash; triggering THH with another speed skill is very likely to secure a pass.
<Skill skill={skills.thh} /> is a full strength speed skill that is triggered by other skills, so it excels at stacking &ndash;
triggering THH with another speed skill is very likely to secure a pass.
</li>
<li>
<Skill skill={200462} hint="ramp" /> is only a half strength speed skill (base 1.8s), but it fires upon overtake, which helps
to turn that into a complete pass.
<Skill skill={skills.ramp} /> is only a half strength speed skill (base 1.8s), but it fires upon overtake, which helps to turn
that into a complete pass.
</li>
<li>
<Skill skill={201661} hint="pto" /> and <Skill skill={201651} hint="slipstream" /> are mechanically similar full-strength speed
skills with cooldowns, so they can fire multiple times per race. Slipstream requires not being in first, and it's always wasted
if it triggers during the <a href="#no-zone">no-overtake zone</a>, so it's marginally weaker. Both want multi-front builds.
<Skill skill={skills.pto} /> and <Skill skill={skills.slipstream} /> are mechanically similar full-strength speed skills with
cooldowns, so they can fire multiple times per race. Slipstream requires not being in first, and it's always wasted if it triggers
during the <a href="#no-zone">no-overtake zone</a>, so it's marginally weaker. Both want multi-front builds.
</li>
</ul>
<Sec h={3} id="gate-skills">Gate Skills</Sec>
<p>
Gate skills are <Skill skill={201601} hint="gw" /> (GW), <Skill skill={200532} hint="early lead" />, and <Skill
skill={200431}
hint="conc"
/> (Conc), as well as all green skills including <Skill skill={202051} hint="runaway" mention /> (but excluding <Skill
skill={201562}
hint="lucky 7"
Gate skills are <Skill skill={skills.gw} /> (GW), <Skill skill={skills.earlyLead} />, and <Skill skill={skills.conc} /> (Conc),
as well as all green skills including <Skill skill={skills.runaway} mention /> (but excluding <Skill
skill={skills.lucky7}
mention
/>). These skills activate the moment the race starts. Other running styles can largely ignore them, but for front runners,
they are critical.
@@ -574,33 +649,31 @@
/>
</div>
<p>
GW must be combined with <Skill skill={200532} hint="el" /> if you want any chance of being first out of early race. The gold version
of EL, <Skill skill={200531} hint="ttl" />, is highly accessible as the skill from the Mihono Bourbon Wit event SSR. In
practice, I've found it adds fewer lengths over the white, and hence less positioning ability, than a mid race gold speed
skill. It is still absolutely <i>good</i>, and Bourbon Wit is a very usable card (treat her as a speed card that gives extra
energy on wit), but I don't consider it mandatory anymore.
GW must be combined with <Skill skill={skills.earlyLead} /> if you want any chance of being first out of early race. The gold version
of EL, <Skill skill={skills.ttl} />, is highly accessible as the skill from the Mihono Bourbon Wit event SSR. In practice,
I've found it adds fewer lengths over the white, and hence less positioning ability, than a mid race gold speed skill. It is
still absolutely <i>good</i>, and Bourbon Wit is a very usable card (treat her as a speed card that gives extra energy on
wit), but I don't consider it mandatory anymore.
</p>
<p>
Conc is less critical. It's worth taking on horses who have it, but it isn't worth using support card slots just to get it. On
the other hand, its white version, <Skill skill={200432} hint="focus" />, is bad; its only real use is as a backup gate skill
for GW when you don't have enough greens available.
the other hand, its white version, <Skill skill={skills.focus} />, is bad; its only real use is as a backup gate skill for GW
when you don't have enough greens available.
</p>
<Sec h={3} id="spurt-skills">Spurt Skills</Sec>
<p>
Because they are post-Angling, skills that activate in the final spurt are typically less interesting to front runners.
Notable exceptions are <Skill skill={910151} hint="barcarole" /> and, on Tokyo turf, <Skill
skill={900311}
hint="ines inherit"
Notable exceptions are <Skill skill={skills.barcaroleInherit} /> and, on Tokyo turf, <Skill
skill={skills.inesInherit}
/><!-- skill name ends with ! -->
These are good inherits for those who don't have easy access to <Skill skill={910261} hint="cacao" mention /> and <Skill
skill={910041}
hint="kfc"
These are good inherits for those who don't have easy access to <Skill skill={skills.cacaoInherit} mention /> and <Skill
skill={skills.kfcInherit}
mention
/>.
</p>
<p>
<Skill skill={900061} hint="pulse" /> is another spurt skill that may come up sometimes and is interesting to think about. It's
<Skill skill={skills.pulseInherit} /> is another spurt skill that may come up sometimes and is interesting to think about. It's
a 0.25 speed skill that requires being in at best second place to activate. Is it worth it to take?
</p>
<p>
@@ -618,9 +691,8 @@
<Sec h={3} id="others-skills">Other Horses' Skills</Sec>
<p>There are two categories of other horses' skills to think about.</p>
<p>
The first is stamina debuffs: <Skill skill={201441} hint="eyes" />, <Skill skill={201161} hint="murmur" />, <Skill
skill={201221}
hint="siphon"
The first is stamina debuffs: <Skill skill={skills.eyes} />, <Skill skill={skills.murmurGold} />, <Skill
skill={skills.siphon}
/>. My conclusion is that Global doesn't understand how to build debuffers, so front runners can mostly ignore these &ndash;
assume one will hit you, but not three.
</p>
@@ -631,9 +703,9 @@
</p>
<p>
The other category of skills to think about is other horses' uniques.
<Skill skill={100101} hint="sfv" />, <Skill skill={100321} hint="u=ma2" />, and a number of others need tight positioning,
requiring something like 2-4 or 3-4 in CM. The number of front runners in the match can dictate whether it's ever possible for
those uniques to activate. This is the fundamental idea behind <a href="#triple-front">triple front</a> builds.
<Skill skill={skills.sfv} />, <Skill skill={skills.uma2} />, and a number of others need tight positioning, requiring
something like 2-4 or 3-4 in CM. The number of front runners in the match can dictate whether it's ever possible for those
uniques to activate. This is the fundamental idea behind <a href="#triple-front">triple front</a> builds.
</p>
<Sec h={3} id="skill-timing">Skill Timing</Sec>
@@ -692,11 +764,10 @@
the early and mid race skills you can manage.
<a href="#gate-skills">Gate skills</a> are especially important, because runaways have a tremendously higher early race target
speed. If there is a real difference between a correctly built runaway blocker and a runaway ace, it's that <Skill
skill={910261}
hint="cacao"
skill={skills.cacaoInherit}
mention
/>
and <Skill skill={910041} hint="kfc" mention /> are arguably more appropriate inherits than Angling, but the argument isn't strong
and <Skill skill={skills.kfcInherit} mention /> are arguably more appropriate inherits than Angling, but the argument isn't strong
if you're still able to hit a good stat line on your runaway.
</p>
<p>
@@ -729,21 +800,19 @@
<Sec h={3} id="long-double-front">Long Double Front</Sec>
<p>
At long distances, double front has different implications.
<Skill skill={900681} hint="vc" /> is the front runner win condition, and the front two horses both get it. With late race being
before the final corner and hence extra move lane not having started, you can take advantage of <Skill
skill={200492}
hint="nn"
/> to turn the <i>second place</i> front runner into the winner.
<Skill skill={skills.vcInherit} /> is the front runner win condition, and the front two horses both get it. With late race being
before the final corner and hence extra move lane not having started, you can take advantage of <Skill skill={skills.nn} /> to turn
the <i>second place</i> front runner into the winner.
</p>
<p>
Building for second place to bunny with NN does not mean manipulating stats and skills to force one of the front runners into
second. Both fronts need to be strong enough to be adjacent at late race start, and you have to beat other people's front
runners, too. (Especially since VC and <Skill skill={200641} hint="encroaching" mention /> are currently the only consistent accels
for long distance.) So, double front for long is ultimately about the same as double front for other distances, just with different
runners, too. (Especially since VC and <Skill skill={skills.encroaching} mention /> are currently the only consistent accels for
long distance.) So, double front for long is ultimately about the same as double front for other distances, just with different
goals when choosing the legacy.
</p>
<p>
Given that NN is good, it's also worth considering the gold version, <Skill skill={200491} hint="nsm" /><!-- ends with ! -->
Given that NN is good, it's also worth considering the gold version, <Skill skill={skills.nsm} /><!-- ends with ! -->
NSM is a better skill for the long double front build, but for now, the only way to get it while running MANT is from Yukino Bijin
Wit. That card's numbers are not great. It's still possible to get a good stat line using her, but it will take more careers to
get there than to just get NN from Fine Motion.
@@ -752,8 +821,7 @@
If you're feeling adventurous, runaway is another consideration for double (and triple) front on long distances. Your ace
(hopefully) still gets VC, but the runaway paces up the race. As mentioned in the <a href="#solo-front">solo front</a>
section, this especially punishes end closers, who tend to be popular on long tracks because of <Skill
skill={200642}
hint="straight spurt"
skill={skills.spurt}
mention
/>. It also keeps your ace in <a href="#front-modes">overtake mode</a>, which is better than speed-up mode, for position keep.
</p>
@@ -771,9 +839,8 @@
One type of support that all front runners do automatically is helping to kill position-based pace chaser skills. Such skills
have conditions that translate into needing to be in 3rd or 4th, or sometimes 2nd through 4th, to activate. When you're
bringing three front runners, if anyone else brings a single other one, they're going to occupy 2-4 naturally. If there happen
to be three others, then even late/end win cons like <Skill skill={900591} hint="beyond" mention /> and <Skill
skill={900271}
hint="pump"
to be three others, then even late/end win cons like <Skill skill={skills.beyondInherit} mention /> and <Skill
skill={skills.pumpInherit}
mention
/> are dead.
</p>
@@ -794,10 +861,9 @@
An SS support doesn't strictly need as much in the way of mid race skills, since her main job is to give the others overtake
mode and then be passed. It's nonetheless a good idea to take those skills for less risk if your other fronts have a poor
showing. In addition to the normal front win cons, it's potentially strong to take unconditional gambles like <Skill
skill={200341}
hint="corner conn"
skill={skills.cornerConn}
mention
/> and <Skill skill={210061} hint="radiant" mention />.
/> and <Skill skill={skills.radiant} mention />.
</p>
<p>
SS supports do best on medium and long tracks, because you want to be building <i>everyone</i> for spot struggle on miles and
@@ -808,11 +874,7 @@
<Sec h={3} id="chariot">Chariot</Sec>
<p>
A front runner build that I have seen but not attempted is the chariot: a runaway with a strong mid race but insufficient HP
to spurt stays in front of one or two other front runners who have <Skill
skill={200491}
hint="nsm"
mention
/><!-- ends with ! -->
to spurt stays in front of one or two other front runners who have <Skill skill={skills.nsm} mention /><!-- ends with ! -->
</p>
<p>
I saw a team using a chariot in CM13 round 2 day 2; that team had an overall eleven wins at the time. Maybe their horses just
@@ -828,7 +890,7 @@
<p>Most front runners enjoy easy careers thanks to strong kits and little chance to be blocked.</p>
<p>
Currently, this chapter is about MANT (a.k.a. Trackblazer). Unity Cup is still useful &ndash; obviously for runaways, but also
for spinning up an <Skill skill={210052} hint="ignited wit" mention /> legacy.
for spinning up an <Skill skill={skills.ignitedWIT} mention /> legacy.
</p>
<Sec h={3} id="support-cards">Support Cards</Sec>
@@ -838,47 +900,41 @@
</p>
<ul class="mb-4 list-disc pl-4">
<li>
Ines Fujin gives <Skill skill={201082} hint="speed eater" mention />, <Skill skill={201661} hint="pto" mention />, and <Skill
skill={201651}
hint="slipstream"
Ines Fujin gives <Skill skill={skills.speedEater} mention />, <Skill skill={skills.pto} mention />, and <Skill
skill={skills.slipstream}
mention
/>. Her guts SSR is the Kitasan Black of guts cards, with 15% training effectiveness and 80 specialty priority. She also has
a relatively new wit SR that is decently strong even at LB0, though still objectively beaten by Marv SR until MLB.
</li>
<li>
Marvelous Sunday, both power SSR and wit SR versions, give <Skill skill={200462} hint="ramp" mention /> and <Skill
skill={201611}
hint="thh"
Marvelous Sunday, both power SSR and wit SR versions, give <Skill skill={skills.ramp} mention /> and <Skill
skill={skills.thh}
mention
/> as hints. The SSR has 15% race bonus, while the SR has 10% race bonus and gives +3 hints. The numbers on both are otherwise
disappointing, but those elements alone are enough to justify using them.
</li>
<li>
Cards that give generic or distance-specific gold speed skills, especially mid race ones, are very valuable to front
runners. Since <Skill skill={200331} hint="professor" mention /> is strong, Kitasan Black is still around despite only 5% race
bonus. El Condor Pasa gives <Skill skill={200721} hint="tunes" mention />.
runners. Since <Skill skill={skills.professor} mention /> is strong, Kitasan Black is still around despite only 5% race bonus.
El Condor Pasa gives <Skill skill={skills.tunes} mention />.
</li>
<li>
For parent runs, Smart Falcon SSR is mandatory. She gives guaranteed <Skill skill={201601} hint="gw" mention /> in her chain,
and her gold skill is <Skill skill={200451} hint="gold pp" mention />, which you want for building a
For parent runs, Smart Falcon SSR is mandatory. She gives guaranteed <Skill skill={skills.gw} mention /> in her chain, and her
gold skill is <Skill skill={skills.centerStage} mention />, which you want for building a
<a href="#lane-combo">lane combo</a> legacy. On ace runs, she is acceptable if you own her at MLB, but you'd rather get her skills
from inheritance and use the card slot for a strong speed skill.
</li>
<li>
Seiun Sky SSR is another good parent card for parents. Her chain starts with <Skill skill={201262} hint="dd" mention /> and ends
with
<Skill skill={200541} hint="escape artist" mention /> (albeit agemasen). She also carries a <Skill
skill={201611}
hint="thh"
mention
/> hint. Unfortunately, between being a stamina card and not being Super Creek, she isn't viable for ace runs.
Seiun Sky SSR is another good parent card for parents. Her chain starts with <Skill skill={skills.dd} mention /> and ends with
<Skill skill={skills.escapeArtist} mention /> (albeit agemasen). She also carries a <Skill skill={skills.thh} mention /> hint.
Unfortunately, between being a stamina card and not being Super Creek, she isn't viable for ace runs.
</li>
<li>Other parenting cards include Kawakami Princess speed and Hishi Akebono guts, for gold versions of lane combo skills.</li>
</ul>
<p>
A future sight advisory: Maruzensky's speed SSR is coming in early July. At this point, you should probably be saving all your
carats for her. She is an extremely strong stat stick and gives <Skill skill={201271} hint="top runner" mention />, the gold
version of <Skill skill={201272} hint="leader's pride" mention />.
carats for her. She is an extremely strong stat stick and gives <Skill skill={skills.topRunner} mention />, the gold version
of <Skill skill={skills.leadersPride} mention />.
</p>
<Sec h={3} id="career-skills">Taking Skills</Sec>
@@ -890,38 +946,37 @@
your chance of getting skills you don't have hints for.
</p>
<p>
<Skill skill={200532} hint="early lead" /> is a snap take skill. The <i>only</i> time to sit on EL is when you happen to get
the first +1 hint the turn before inspiration. (Even then, I'd probably still take it, since there's still a race to run.)
Early Lead is one of the strongest skills in terms of lengths gained, it applies to all tracks and conditions, and
<Skill skill={skills.earlyLead} /> is a snap take skill. The <i>only</i> time to sit on EL is when you happen to get the first
+1 hint the turn before inspiration. (Even then, I'd probably still take it, since there's still a race to run.) Early Lead is
one of the strongest skills in terms of lengths gained, it applies to all tracks and conditions, and
<i>it saves late starts</i>, which are your only source of losses on most races after junior year. Moreover, it has a base
cost of only 120 SP; even if you do get Fast Learner after taking it, your opportunity cost was 12 SP. If you prune EL and a
hint lands on <Skill skill={200542} hint="fast-paced" mention /> or <Skill skill={201272} hint="leader's pride" mention /> instead,
you gave up that potential 12 SP to save 18. It's incredibly good to take early.
hint lands on <Skill skill={skills.fastPaced} mention /> or <Skill skill={skills.leadersPride} mention /> instead, you gave up that
potential 12 SP to save 18. It's incredibly good to take early.
</p>
<p>
On parent runs, or exactly one of your three CM horses, <Skill skill={201641} hint="lone wolf" /> is another snap take. Base cost
of 60 SP for +40 speed, which can secure a lot of races, especially early in career. Be extremely careful not to take it on multiple
horses on a team. Save and quit from the career if you need to check. It's technically better to have it on two horses than zero,
but it's tremendously better than that to have it on one.
On parent runs, or exactly one of your three CM horses, <Skill skill={skills.loneWolf} /> is another snap take. Base cost of 60
SP for +40 speed, which can secure a lot of races, especially early in career. Be extremely careful not to take it on multiple horses
on a team. Save and quit from the career if you need to check. It's technically better to have it on two horses than zero, but it's
tremendously better than that to have it on one.
</p>
<p>
<Skill skill={900201} hint="angling" /> is a strong consideration as a mid-career take. Inheritance events are more likely to activate
<Skill skill={skills.anglingInherit} /> is a strong consideration as a mid-career take. Inheritance events are more likely to activate
green sparks than white sparks, so the risk of missing out on SP by taking it early is higher. However, Angling is an almost automatic
win condition for career (outside of <a href="#3k">3Ks</a> and <a href="#niigata-1600">Niigata 1600</a>). Taking Angling early
can save a lot of clocks, and it can rescue runs that don't get what is normally the minimum speed to win races before summer.
</p>
<p>
I've had debate about this one, but I feel that <Skill skill={201522} hint="savvy" /> is a skill you will pretty much always want
at least the first level of. Wit is a strong stat for front runners, and Savvy is a guaranteed Groundwork trigger. It's also the
second cheapest front-specific skill, after Dodging Danger. On parent runs, it could arguably be worth sitting on it until the +2
or +3 hint, because taking the second level gives a slightly boosted chance to generate the spark, and hints save twice as much
SP on the double circle.
I've had debate about this one, but I feel that <Skill skill={skills.savvy} /> is a skill you will pretty much always want at least
the first level of. Wit is a strong stat for front runners, and Savvy is a guaranteed Groundwork trigger. It's also the second cheapest
front-specific skill, after Dodging Danger. On parent runs, it could arguably be worth sitting on it until the +2 or +3 hint, because
taking the second level gives a slightly boosted chance to generate the spark, and hints save twice as much SP on the double circle.
</p>
<p>
<Skill skill={201242} hint="front straights" /> and <Skill skill={201252} hint="front corners" /> are strong and cheap. If you've
taken Early Lead and Angling, they probably won't change the outcomes of any races, but it's still reasonable to take the first
level to prune. As a corollary, outside parent runs, you should have a specific distance in mind, so your distance straights/corners
should usually be even quicker takes.
<Skill skill={skills.straights} /> and <Skill skill={skills.corners} /> are strong and cheap. If you've taken Early Lead and Angling,
they probably won't change the outcomes of any races, but it's still reasonable to take the first level to prune. As a corollary,
outside parent runs, you should have a specific distance in mind, so your distance straights/corners should usually be even quicker
takes.
</p>
<Sec h={3} id="niigata-1600">Niigata Junior Stakes</Sec>
@@ -969,9 +1024,9 @@
tested much without them, because I don't like throwing away my runs.
</p>
<p>
<Skill skill={201282} hint="moxie" /> is the only front-specific recovery skill you can get from MANT rivals. It also is a guaranteed
option in Bourbon Wit's first chain event. That makes it pretty often available for the 3Ks. However, if you end up overstam at
the end of the run, buying Moxie can be as much as -162 SP, which is certainly not a trivial amount.
<Skill skill={skills.moxie} /> is the only front-specific recovery skill you can get from MANT rivals. It also is a guaranteed option
in Bourbon Wit's first chain event. That makes it pretty often available for the 3Ks. However, if you end up overstam at the end
of the run, buying Moxie can be as much as -162 SP, which is certainly not a trivial amount.
</p>
<p>
An alternative option to buying a recovery is to switch to Late Surger for those races. I've won Kikuka Sho with circa 300
@@ -1005,44 +1060,36 @@
<ul class="mb-4 list-disc pl-4">
<li>
Valentine's Mihono Bourbon (VBourbon) is the easiest font runner to train because she has <Skill
skill={201601}
hint="gw"
skill={skills.gw}
mention
/> built in, whereas most others have to get it from either inheritance or cards that aren't terribly strong. She is also the
strongest front runner, because <Skill skill={110261} hint="cacao" mention /> is full strength, mid race, extremely forgiving
in activation, and even has a heal. And she has <Skill skill={200431} hint="conc" mention /> and <Skill
skill={200541}
hint="escape artist"
mention
/> built in, both strong distance-agnostic front runner skills with awkward sources otherwise. And she's a great parent for all
the same reasons that her unique is strong (except that the heal becomes irrelevant).
strongest front runner, because <Skill skill={skills.cacao} mention /> is full strength, mid race, extremely forgiving in activation,
and even has a heal. And she has <Skill skill={skills.conc} mention /> and <Skill skill={skills.escapeArtist} mention /> built
in, both strong distance-agnostic front runner skills with awkward sources otherwise. And she's a great parent for all the same
reasons that her unique is strong (except that the heal becomes irrelevant).
</li>
<li>
Summer Maruzensky (SMaru or KFC) is just shy of VBourbon in strength with her unique, <Skill
skill={110041}
hint="kfc"
mention
/>. It uses a heal to trigger instead of having a heal built in, but that means it sometimes has carryover potential. Using
Summer Maruzensky (SMaru or KFC) is just shy of VBourbon in strength with her unique, <Skill skill={skills.kfc} mention />.
It uses a heal to trigger instead of having a heal built in, but that means it sometimes has carryover potential. Using
VBourbon as a parent for SMaru works as a trigger, too, which is especially good for shorter distances that don't want to
spend SP on pure recoveries.
</li>
<li>
Seiun Sky is the source of <Skill skill={900201} hint="angling" mention /> and therefore the best horse for front runner parenting
Seiun Sky is the source of <Skill skill={skills.anglingInherit} mention /> and therefore the best horse for front runner parenting
in the game, forever. As a runner, she is outshone by the former two and others who will come later, but she is an excellent choice
for a <a href="#double-front">second front runner</a> in a team comp.
</li>
<li>
Kitasan Black is the definitive front runner of long distance, both as a parent and as a competitor.
<Skill skill={201173} hint="blast" mention /> is the gold version of <Skill skill={201172} hint="long straights" mention />,
which is extremely strong to have built in (especially noting that hints on Long Straights take 27 SP off the price of
Blast).
<Skill skill={skills.blast} mention /> is the gold version of <Skill skill={skills.longStraights} mention />, which is
extremely strong to have built in (especially noting that hints on Long Straights take 27 SP off the price of Blast).
</li>
<li>
Silence Suzuka and Mejiro Palmer are currently the only runaways in the game. Both of them have uniques that are
inconsistent normally but very consistent as runaways:
<Skill skill={100021} hint="view" mention /> and <Skill skill={100641} hint="palmer" mention />. Outside of Team Trials,
runaways aren't very useful in the MANT era. (My Suzuka runaway remains my #1 top scorer in TT, though. Runaway and Conc are
both busted for points.)
<Skill skill={skills.view} mention /> and <Skill skill={skills.palmerUlt} mention />. Outside of Team Trials, runaways
aren't very useful in the MANT era. (My Suzuka runaway remains my #1 top scorer in TT, though. Runaway and Conc are both
busted for points.)
</li>
</ul>
<p>
@@ -1053,8 +1100,8 @@
<Sec h={3} id="coc">Christmas Oguri Cap</Sec>
<p>
As is perhaps expected, Christmas Oguri Cap (COC) is very strong as a front runner on specific tracks. The front-specific heal
is <Skill skill={201282} hint="moxie" mention />, which activates at the very start of the first uphill. When that first
uphill is at the start of late race, as in the case of Tokyo 1600 Dirt, COC is online as a front runner.
is <Skill skill={skills.moxie} mention />, which activates at the very start of the first uphill. When that first uphill is at
the start of late race, as in the case of Tokyo 1600 Dirt, COC is online as a front runner.
</p>
<p>
I've been told COC is very hard to train as a front runner. Something about aptitudes. I don't have any variety of Oguri, but
@@ -1062,8 +1109,7 @@
</p>
<p>
Another rare manifestation of Front COC is as a third place horse in a <a href="#triple-front">triple front</a> build where <Skill
skill={900321}
hint="u=ma2"
skill={skills.uma2Inherit}
mention
/> is strong. I convinced Werseter, the Umadump guy, to try this for CM12 after he accidentally made an 8★ front Tachyon parent.
He reported a 7% win rate for her. (But a much higher win rate overall &ndash; after all, he was using triple front.)
@@ -1111,37 +1157,36 @@
<p>Front runners are more reliant than other styles on getting certain skills from inspiration:</p>
<ul class="mb-4 list-disc pl-4">
<li>
Building a full <Skill skill={201601} hint="gw" /> legacy is the first step to front runner training. Fronts without it are non-competitive
Building a full <Skill skill={skills.gw} /> legacy is the first step to front runner training. Fronts without it are non-competitive
even as supports. The cards that give it aren't great for ace builds. There is no gold version of it yet, so getting it from inheritance
is truly ideal.
</li>
<li>
<Skill skill={200452} hint="pp" /> similarly doesn't come from good cards (since Sweep Tosho has fallen off). As a piece of
<Skill skill={skills.pp} /> similarly doesn't come from good cards (since Sweep Tosho has fallen off). As a piece of
<a href="#lane-combo">lane combo</a>, it isn't applicable to every race, but it's very strong when it is. The white skill is
better than the gold skill, so it is another ideal inherit.
</li>
<li>
<Skill skill={210052} hint="ignited wit" /> is the stronger lane combo piece. The only sources of it are inheritance and Unity
Cup; which is to say, the source of it is inheritance. When searching databases for borrows, looking for Ignited WIT is a shortcut
for listing good front runner legacies, since it's only valuable to fronts and somewhat hard to get even when you focus on it.
<Skill skill={skills.ignitedWIT} /> is the stronger lane combo piece. The only sources of it are inheritance and Unity Cup; which
is to say, the source of it is inheritance. When searching databases for borrows, looking for Ignited WIT is a shortcut for listing
good front runner legacies, since it's only valuable to fronts and somewhat hard to get even when you focus on it.
</li>
<li>
Almost all green skills are valuable to inherit at one point or another as GW triggers.
<Skill skill={200012} hint="right" /> and <Skill skill={200022} hint="left" /> are particularly good; one of the two is always
the best green available for a race.
<Skill skill={200152} hint="firm" /> is a bit less strong, and slightly superseded by the existence of Narita Top Road, but it
applies to the majority of CM races. Season greens are great, but a bit narrow; distance greens are good. Weather greens are acceptable,
<Skill skill={skills.right} /> and <Skill skill={skills.left} /> are particularly good; one of the two is always the best green
available for a race.
<Skill skill={skills.firm} /> is a bit less strong, and slightly superseded by the existence of Narita Top Road, but it applies
to the majority of CM races. Season greens are great, but a bit narrow; distance greens are good. Weather greens are acceptable,
but while guts is better on front runners than other styles, it isn't good.
<Skill skill={200282} hint="comp spirit" /> is good if you like to do <a href="#triple-front">triple front</a> builds,
because it activates when there are four of the runner's style in CM.
<Skill skill={201522} hint="savvy" /> is slightly less valuable as an inherit, since it can come from rivals.
<Skill skill={skills.compSpirit} /> is good if you like to do <a href="#triple-front">triple front</a> builds, because it
activates when there are four of the runner's style in CM.
<Skill skill={skills.savvy} /> is slightly less valuable as an inherit, since it can come from rivals.
</li>
<li>
All generic speed skills that aren't strictly late race are good inherits.
<Skill skill={202032} hint="risky" /> is the best one by ratio of strength to difficulty to acquire.
<Skill skill={201611} hint="thh" />, <Skill skill={201661} hint="pto" />, <Skill skill={200462} hint="ramp" />, and <Skill
skill={200332}
hint="corner adept"
<Skill skill={skills.risky} /> is the best one by ratio of strength to difficulty to acquire.
<Skill skill={skills.thh} />, <Skill skill={skills.pto} />, <Skill skill={skills.ramp} />, and <Skill
skill={skills.cornerAdept}
/> are also strong, but available as hints or chain skills from some usable-to-good cards.
</li>
<li>Obviously, getting front-runner-specific skills from inheritance makes them cheaper and more consistent to get.</li>
@@ -1300,7 +1345,7 @@
<Sec h={3} id="cm13">CM13 &ndash; Taurus Cup (Tokyo Derby)</Sec>
<p>
Maruzensky's unique, <Skill skill={900041} hint="redshift" mention />, is live for approximately everyone. Filling the ranks
Maruzensky's unique, <Skill skill={skills.redshiftInherit} mention />, is live for approximately everyone. Filling the ranks
with front runners should be a strong means to delay it for later positions, especially COC.
</p>
<p>
@@ -1425,8 +1470,8 @@
</p>
<p>As a sprint, this is also where spot struggle shines. Time for Unity Cup guts builds.</p>
<p>
I forgot that <Skill skill={200551} hint="unrestrained" mention /> requires being in first place, so I thought it would be reasonable
to base my team around gambling on it. That turned out not to be a great decision.
I forgot that <Skill skill={skills.unrestrained} mention /> requires being in first place, so I thought it would be reasonable to
base my team around gambling on it. That turned out not to be a great decision.
</p>
<ol class="mb-4 list-decimal pl-4">
<li>
@@ -1447,13 +1492,12 @@
</li>
</ol>
<p>
The plan worked exactly as I hoped, but what the plan lacked was <Skill skill={900141} hint="vpp" mention />. While I was
The plan worked exactly as I hoped, but what the plan lacked was <Skill skill={skills.pastaInherit} mention />. While I was
suppressing it on other teams' front runners with my outstanding mid race, they were also gambling on <Skill
skill={200651}
hint="gale"
skill={skills.turboSprint}
mention
/> and <Skill skill={200371} hint="turbo sprint" mention />, and I didn't have enough accel to beat them. I found a mention in
my chat history that, as of round 2 day 1, I had a 78% top two rate with a 32% win rate. Lessons learned. Still managed to get
2nd in the finals, and also my first ever group A round 2 sweep.
/> and <Skill skill={skills.rushingGale} mention />, and I didn't have enough accel to beat them. I found a mention in my chat
history that, as of round 2 day 1, I had a 78% top two rate with a 32% win rate. Lessons learned. Still managed to get 2nd in
the finals, and also my first ever group A round 2 sweep.
</p>
</Article>

View File

@@ -12,6 +12,9 @@ const config = {
return isExternalLibrary ? undefined : true;
},
experimental: {
async: true,
},
},
kit: {
adapter: adapter(),

View File

@@ -4,6 +4,7 @@ import { playwright } from '@vitest/browser-playwright';
import { sveltekit } from '@sveltejs/kit/vite';
export default defineConfig({
clearScreen: false,
plugins: [tailwindcss(), sveltekit()],
test: {
expect: { requireAssertions: true },
@@ -33,4 +34,11 @@ export default defineConfig({
},
],
},
server: {
proxy: {
'/api': {
target: 'http://localhost:13669',
},
},
},
});