zenno/doc/lanecalc: english manual for lanecalc

For #14.
This commit is contained in:
2026-06-13 21:58:38 -04:00
parent bc9d722ee0
commit c66d969c82
8 changed files with 273 additions and 0 deletions
+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