Compare commits

..

5 Commits

Author SHA1 Message Date
zephyr 51f942ee18 zenno: mention doc/lanecalc as appropriate
Fixes #14.
2026-06-13 22:09:09 -04:00
zephyr 2c773391f0 zenno: link up doc/lanecalc 2026-06-13 22:04:49 -04:00
zephyr c66d969c82 zenno/doc/lanecalc: english manual for lanecalc
For #14.
2026-06-13 22:02:16 -04:00
zephyr bc9d722ee0 zenno/doc/frbm: cm14 results and cm15 plans 2026-06-13 13:20:54 -04:00
zephyr 6482f11620 zenno/doc/frbm: rename chariot -> rabbit
jern on the Hakuraku discord informs me that chariot is a different
style of build.

Fixes #19.
2026-06-13 12:35:07 -04:00
12 changed files with 332 additions and 8 deletions
+5
View File
@@ -38,6 +38,11 @@
<li> <li>
<a href={resolve('/doc/frbm')}>Front Runner Black Magic</a> &mdash; Detailed analysis of how front runners interact with race mechanics. <a href={resolve('/doc/frbm')}>Front Runner Black Magic</a> &mdash; Detailed analysis of how front runners interact with race mechanics.
</li> </li>
<li>
<a href={resolve('/doc/lanecalc')}>Gaikokujin's Guide to Lanecalc</a> &mdash; English language manual for
<a href="https://lanecalc.hf-uma.net/" target="_blank" rel="noopener noreferrer">危険回避シミュ</a>, or Lanecalc, for precise
lane combo simulation.
</li>
</ul> </ul>
<h2 class="my-4 text-4xl">About</h2> <h2 class="my-4 text-4xl">About</h2>
+5
View File
@@ -9,4 +9,9 @@
<li> <li>
<a href={resolve('/doc/frbm')}>Front Runner Black Magic</a> &mdash; Detailed analysis of how front runners interact with race mechanics. <a href={resolve('/doc/frbm')}>Front Runner Black Magic</a> &mdash; Detailed analysis of how front runners interact with race mechanics.
</li> </li>
<li>
<a href={resolve('/doc/lanecalc')}>Gaikokujin's Guide to Lanecalc</a> &mdash; English language manual for
<a href="https://lanecalc.hf-uma.net/" target="_blank" rel="noopener noreferrer">危険回避シミュ</a>, or Lanecalc, for precise
lane combo simulation.
</li>
</ul> </ul>
+47 -7
View File
@@ -473,9 +473,8 @@
<p> <p>
The <a href={resolve('/race/mspeed')}>mechanical speed calculator</a> has an approximation of lane combo's benefit. A more The <a href={resolve('/race/mspeed')}>mechanical speed calculator</a> has an approximation of lane combo's benefit. A more
precise lane combo simulator exists at precise lane combo simulator exists at
<a href="https://lanecalc.hf-uma.net/" target="_blank" rel="noopener noreferrer">危険回避シミュ</a>, but I am not sufficiently <a href="https://lanecalc.hf-uma.net/" target="_blank" rel="noopener noreferrer">危険回避シミュ</a>. See
confident in my Japanese to try to guide readers through it. <a href={resolve('/doc/lanecalc')}>my guide</a> for English instructions on how to use it.
<!-- TODO(zeph): i could totally annotate a picture though, or find someone else's explanation -->
</p> </p>
<Sec h={3} id="uphills">Uphills</Sec> <Sec h={3} id="uphills">Uphills</Sec>
@@ -871,16 +870,25 @@
between 1200 and 1000 guts can matter. See the <a href={resolve('/race/mspeed')}>mechanical speed calculator</a> for details. between 1200 and 1000 guts can matter. See the <a href={resolve('/race/mspeed')}>mechanical speed calculator</a> for details.
</p> </p>
<Sec h={3} id="chariot">Chariot</Sec> <div class="hidden" id="chariot"></div>
<Sec h={3} id="rabbit">Rabbit</Sec>
<p> <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 A front runner build that I have seen but not attempted is the rabbit: a runaway with a strong early race but insufficient HP
to spurt stays in front of one or two other front runners who have <Skill skill={skills.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>
<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 I saw a team using a rabbit in CM13 round 2 day 2; that team had an overall eleven wins at the time. Maybe their horses just
weren't strong enough. I'm not sure. My opinion is that this build gives up the consistency of front runners to pursue a game weren't strong enough. I'm not sure. My opinion is that this build gives up the consistency of front runners to pursue a game
plan that is hardly stronger when it does work. plan that is hardly stronger when it does work.
</p> </p>
<p>
About two weeks ahead of CM15, Hakuraku's replay data is showing teams using a rabbit build, or even double runaways, with
high win rates. I've watched a few dozen of those races and have found that the runaways are not functionally doing anything
specific to runaways: they're being built without <Skill skill={skills.gw} mention /> and <Skill
skill={skills.earlyLead}
mention
/>, so the normal fronts (typically UG1 or better) pass them during early race.
</p>
<p> <p>
If this build ever had an era, it was during Unity Cup, when NSM was essentially free and there was no VC. I don't think it's If this build ever had an era, it was during Unity Cup, when NSM was essentially free and there was no VC. I don't think it's
viable now. viable now.
@@ -1059,7 +1067,7 @@
<Sec h={2} id="umas">Front Runners</Sec> <Sec h={2} id="umas">Front Runners</Sec>
<ul class="mb-4 list-disc pl-4"> <ul class="mb-4 list-disc pl-4">
<li> <li>
Valentine's Mihono Bourbon (VBourbon) is the easiest font runner to train because she has <Skill Valentine's Mihono Bourbon (VBourbon or Chocobon) is the easiest font runner to train because she has <Skill
skill={skills.gw} skill={skills.gw}
mention mention
/> built in, whereas most others have to get it from either inheritance or cards that aren't terribly strong. She is also the /> built in, whereas most others have to get it from either inheritance or cards that aren't terribly strong. She is also the
@@ -1320,6 +1328,30 @@
<Sec h={2} id="cm">My CM Teams</Sec> <Sec h={2} id="cm">My CM Teams</Sec>
<Sec h={3} id="cm15">CM15 &ndash; Cancer Cup (Takarazuka Kinen)</Sec>
<p>
Kitasan's unique ends about a sixth of a second before late race starts, which means massive carryover potential (although
being just a 0.25 skill is sad). I see on Hakuraku that runaways are unusually prevalent, and as much as I think it's a bad
build, I kind of want to try rabbiting this time.
</p>
<ol class="mb-4 list-decimal pl-4">
<li>
Suzuka. I'll try building her as a runaway with TTL, GW, Conc, lane combo, and no other skills except debuffs, and see
whether I can make two aces that can consistently pass in mid race. If that doesn't work out, I'll do a spot struggle
support instead.
</li>
<li>
Kitasan Black. She won't get to run often, so I'm going to run her while I have the opportunity. She's pretty difficult to
build a deck for, though. No Professor, and only one of Tunes and Escape Artist, since I have neither Pasta nor Helios SSR.
(The latter is proving non-functional anyway. Five runs with agemasen every time.)
</li>
<li>
Chocobon. Part of me wants to do Seiun Sky here, but if Kitasan has carryover potential on her unique, then so does Bourbon
if she whiffs on the first half corners. Since Kitasan won't have as good of a mid race, I really need a proper front runner
ace, and that's what Chocobon does best.
</li>
</ol>
<Sec h={3} id="cm14">CM14 &ndash; Gemini Cup (Yasuda Kinen, NHK Mile Cup, Victoria Mile)</Sec> <Sec h={3} id="cm14">CM14 &ndash; Gemini Cup (Yasuda Kinen, NHK Mile Cup, Victoria Mile)</Sec>
<p> <p>
The ultimate lane combo map, and also the ultimate <a href="#no-zone">no-overtake zone</a> map, and also the ultimate dueling map. The ultimate lane combo map, and also the ultimate <a href="#no-zone">no-overtake zone</a> map, and also the ultimate dueling map.
@@ -1346,6 +1378,14 @@
Win rates after 40: Falco 47.5%, Bourbon 27.5%, Suzuka 5%. While this is my best round 1 by a substantial margin, I'm pretty Win rates after 40: Falco 47.5%, Bourbon 27.5%, Suzuka 5%. While this is my best round 1 by a substantial margin, I'm pretty
sure I'm going to get torn up in round 2; my stats aren't good enough to beat correctly built end closers. sure I'm going to get torn up in round 2; my stats aren't good enough to beat correctly built end closers.
</p> </p>
<p>
Win rates after 80: Falco 36.25%, Bourbon 22.5%, Suzuka 6.25%. Not as bad as I expected; most round 2 entries finished with
three wins. I'll take it.
</p>
<p>
Unfortunately lost to a bad mid race and a Taishin getting a perfect Radiant. At least it was only one this time. Second
place.
</p>
<Sec h={3} id="cm13">CM13 &ndash; Taurus Cup (Tokyo Derby)</Sec> <Sec h={3} id="cm13">CM13 &ndash; Taurus Cup (Tokyo Derby)</Sec>
<p> <p>
+273
View File
@@ -0,0 +1,273 @@
<script lang="ts">
import { resolve } from '$app/paths';
import Skill from '$lib/Skill.svelte';
import Sec from '../Sec.svelte';
import * as skill from '$lib/data/skill';
import { onMount } from 'svelte';
import type { ClassValue } from 'svelte/elements';
import courseSetupHoriz from './course-setup.horiz.png';
import courseSetupVert from './course-setup.vert.png';
import umaSetupHoriz from './uma-setup.horiz.png';
import umaSetupVert from './uma-setup.vert.png';
import resultsChart from './results-chart.png';
import resultsHoriz from './results.horiz.png';
import resultsVert from './results.vert.png';
import Article from '../Article.svelte';
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({
goldpp: allSkills.get(200451),
pp: allSkills.get(200452),
ttl: allSkills.get(200531),
earlyLead: allSkills.get(200532),
dd: allSkills.get(201262),
gw: allSkills.get(201601),
ignitedWIT: allSkills.get(210052),
});
const locations = [
['札幌', 'Sapporo'],
['函館', 'Hakodate'],
['新潟', 'Niigata'],
['福島', 'Fukushima'],
['中山', 'Nakayama'],
['東京', 'Tokyo'],
['中京', 'Chukyo'],
['京都', 'Kyoto'],
['阪神', 'Hanshin'],
['小倉', 'Kokura'],
['大井', 'Ooi'],
['川崎', 'Kawasaki'],
['船橋', 'Funabashi'],
['盛岡', 'Morioka'],
] as const;
const courseinfos = [
['芝', 'Turf'],
['ダート', 'Dirt'],
['内', 'Inner'],
['外', 'Outer'],
] as const;
const conditionses = [
['良', 'Firm'],
['稍重', 'Good'],
['重', 'Soft'],
['不良', 'Heavy'],
] as const;
const styles = [
['大逃げ', 'Runaway'],
['逃げ', 'Front Runner'],
] as const;
const moods = [
['絶好調', 'Great'],
['好調', 'Good'],
['普通', 'Normal'],
['不調', 'Bad'],
['絶不調', 'Awful'],
] as const;
const accels = [
['地固め', 'Groundwork'],
['盤石', 'Unshakable Stance'],
['先駆け', 'Early Lead'],
['先手', 'Taking the Lead'],
['進化先手', 'Evolved Taking the Lead'],
] as const;
const arinashi = [
['あり', 'Enabled'],
['なし', 'Disabled'],
] as const;
const hills = [
['上り坂 (Red)', 'Uphill'],
['下り坂 (Blue)', 'Downhill'],
] as const;
const times = [
['危険回避', 'Dodging Danger'],
['スキル', 'Lane Skill Activation'],
['中盤', 'Mid Race'],
] as const;
const straco = [
['直線 (Yellow)', 'Straight'],
['コーナー (Pink)', 'Corner'],
] as const;
const laneskills = [
['スキルなし', 'No Skills'],
['危険回避のみ', 'Dodging Danger'],
['+注目の踊り子', 'DD + Center Stage'],
['+ポジションセンス', 'DD + Prudent Positioning'],
['+アオハル点火・賢', 'DD + Ignited Spirit WIT'],
] as const;
const tooltip = [
['時間', 'Time (s)'],
['レーン', 'Lane (CW)'],
['走行距離', 'Distance (m)'],
['距離ロス', 'Distance Loss (m)'],
] as const;
const summaryText = [
['バ身', 'Lengths'],
['アド', 'Add'],
['ロス', 'Loss'],
] as const;
</script>
{#snippet transbody(heads: string | [string, string], cells: ReadonlyArray<readonly [string, string]>, cls?: ClassValue | null)}
<table class={['mx-1 mt-4 table-fixed border md:mb-auto', cls]}>
{#if typeof heads === 'string'}
<caption class="border border-b-0">{heads}</caption>
{:else}
<thead class="border-b">
<tr>
<th class="w-1/2 px-2" scope="col">{heads[0]}</th>
<th class="w-1/2 px-2" scope="col">{heads[1]}</th>
</tr>
</thead>
{/if}
<tbody>
{#each cells as [jp, en] (jp)}
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
<td>{jp}</td>
<td>{en}</td>
</tr>
{/each}
</tbody>
</table>
{/snippet}
<Article>
{#snippet head()}
<Sec h={1} id="top" class="text-center pointer-coarse:mb-8">Gaikokujin's Guide to Lanecalc</Sec>
<p>
This is an English usage manual for <a href="https://lanecalc.hf-uma.net/" target="_blank" rel="noopener noreferrer"
>危険回避シミュ</a
>, or Lanecalc.
</p>
<p>
Lanecalc is a precise calculator for the effect of <a href={resolve('/doc/frbm#lane-combo')}>lane combo</a>, the use of <Skill
skill={skills.dd}
/> along with some combination of <Skill skill={skills.pp} />, <Skill skill={skills.goldpp} />, and <Skill
skill={skills.ignitedWIT}
/>
for a substantial speed boost in early race. Lanecalc helps with deciding whether lane combo (and DD alone) is applicable to a
given track.
</p>
<p>
The translations presented in this manual are contextualized to an English speaker using Lanecalc, rather than being direct
translations. E.g., スキル literally means "skill," but I am translating it as "lane skill activation time" where that is
what スキル signifies.
</p>
{/snippet}
<Sec h={2} id="course">Course Setup</Sec>
<p>
The top section of lane calc is the course setup section. Set the race location, course at the location, and ground condition
here.
</p>
<a href={courseSetupHoriz}>
<picture>
<source srcset={courseSetupHoriz} media="(orientation: landscape)" width="882" height="111" />
<img
class="mx-auto"
src={courseSetupVert}
width="412"
height="214"
alt="Lanecalc's course setup section with English labels"
/>
</picture>
</a>
<div class="mb-4 grid grid-cols-1 text-center text-xl md:grid-cols-3">
{@render transbody(['レース場', 'Location'], locations)}
{@render transbody(['コース', 'Race Course'], courseinfos)}
{@render transbody(['バ場状態', 'Conditions'], conditionses)}
</div>
<p>
The race course menu shows only courses available at the selected race location. Changing the location will reset the course.
</p>
<Sec h={2} id="uma">Uma Setup</Sec>
<p>The next section is the setup for the Uma.</p>
<a href={umaSetupHoriz}>
<picture>
<source srcset={umaSetupHoriz} media="(orientation: landscape)" width="878" height="218" />
<img class="mx-auto" src={umaSetupVert} width="412" height="456" alt="Lanecalc's Uma setup section with English labels" />
</picture>
</a>
<div class="mb-4 grid grid-cols-1 text-center text-xl md:grid-cols-3">
{@render transbody(['脚質', 'Running Style'], styles)}
{@render transbody(['ポワー', 'Power'], [])}
{@render transbody(['調子', 'Mood'], moods)}
{@render transbody(['ウマ番', 'Gate'], [])}
{@render transbody(['危険回避発動', 'Dodging Danger'], arinashi)}
{@render transbody(['横ブロック', 'Side Block'], arinashi)}
{@render transbody(['レーンスキル発動位置', 'Lane Skill Activation Time'], [['秒', 'seconds']])}
{@render transbody(['加速スキル', 'Acceleration Skills'], accels, 'md:col-span-2')}
</div>
<p>
Power should be entered as the raw power stat, i.e. the number shown on your Uma's stat screen. (There doesn't appear to be a
way to apply power passives.)
</p>
<p>
Unshakable Stance is the gold version of <Skill skill={skills.gw} mention /> and is not yet available in Global. "Evolved Taking
the Lead" means any of the evolutions of <Skill skill={skills.ttl} mention /> that turn it into a 0.5 accel skill. (Aston Machan
will have a TTL evolution that instead turns it into a 4s 0.4 accel. There doesn't appear to be a way to apply it in the calculator.)
</p>
<p>
Selecting another skill in the same group as a selected one will remove the existing skill. Selecting an already selected
skill will disable it entirely in the simulator.
</p>
<Sec h={2} id="chart">Results Chart</Sec>
<p>Once the course and Uma are configured, click the green 計算 button. After a moment, the results appear.</p>
<a href={resultsChart}>
<picture>
<img class="mx-auto" src={resultsChart} width="800" height="600" alt="Lanecalc results chart" />
</picture>
</a>
<p class="mt-4">
The chart shows the Uma's simulated lane (horizontal distance from the rail) and forward velocity under the effects of various
lane combo skills.
</p>
<p>
The example above is Hanshin 2200, firm, with a front runner with 1200 power in great condition from gate 6. She has <Skill
skill={skills.gw}
mention
/> and <Skill skill={skills.earlyLead} mention />, and the lane change speed skills are set to activate at 7 seconds.
</p>
<div class="-mt-4 mb-4 grid grid-cols-1 text-center text-xl md:grid-cols-6">
{@render transbody('Hill Indicators', hills, 'md:col-span-2')}
{@render transbody('Time Indicators', times, 'md:col-span-2')}
{@render transbody('Straights/Corners', straco, 'md:col-span-2')}
{@render transbody('Lane Speed Skills', laneskills, 'md:col-span-4 md:col-start-2')}
</div>
<p>
You can click the labels underneath the chart to hide the corresponding line. The top row is for lane position lines, and the
bottom row is for velocity lines.
</p>
<p>
You can also hover the mouse over the lines for details. The first portion of the details are the skills that produce the
exact corresponding point, with a color square for each. Underneath is the simulation state.
</p>
<div class="-mt-4 mb-4 grid grid-cols-1 text-center text-xl md:grid-cols-3">
{@render transbody('Hover Info', tooltip, 'md:col-start-2')}
</div>
<Sec h={2} id="summary">Results Summary</Sec>
<p>
Last is the summary, shown as circles showing the gain from each combination of skills:
<Skill skill={skills.dd} /> alone, DD plus <Skill skill={skills.goldpp} />, DD plus <Skill skill={skills.pp} />, and DD plus <Skill
skill={skills.ignitedWIT}
/>.
</p>
<a href={resultsHoriz}>
<picture>
<source srcset={resultsHoriz} media="(orientation: landscape)" width="700" height="176" />
<img class="mx-auto" src={resultsVert} width="380" height="703" alt="Lanecalc results summary" />
</picture>
</a>
<div class="mb-4 grid grid-cols-1 text-center text-xl md:grid-cols-3">
{@render transbody('Lane Speed Skills', laneskills.slice(1), 'md:col-span-2')}
{@render transbody('Labels', summaryText)}
</div>
</Article>
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

+2 -1
View File
@@ -16,6 +16,7 @@
Stat, Stat,
} from '$lib/race'; } from '$lib/race';
import StatChart from '$lib/StatChart.svelte'; import StatChart from '$lib/StatChart.svelte';
import { resolve } from '$app/paths';
import SpeedDur from './SpeedDur.svelte'; import SpeedDur from './SpeedDur.svelte';
let rawPower = $state(1200); let rawPower = $state(1200);
@@ -212,7 +213,7 @@
href="https://lanecalc.hf-uma.net/" href="https://lanecalc.hf-uma.net/"
target="_blank" target="_blank"
rel="noopener noreferrer">危険回避シミュ</a rel="noopener noreferrer">危険回避シミュ</a
>. >, or <a href={resolve('/doc/lanecalc')}>Gaikokujin's Guide to Lanecalc</a> for English instructions on how to use it.
</li> </li>
</ul> </ul>
</li> </li>