zenno: categorize tools

This commit is contained in:
2026-06-10 14:03:42 -04:00
parent dc78d51def
commit 75024c7c11
18 changed files with 119 additions and 42 deletions

View File

@@ -1,6 +1,3 @@
import { affinity, lookup } from './data/affinity';
import { uma, type Uma } from './data/uma';
/**
* A legacy, or parents and grandparents.
* Defined as an applicative over generic types to reduce the API surface.
@@ -41,9 +38,9 @@ export interface Veteran {
saddles: number[];
}
function findUma(umas: Uma[], u: number): Uma | null {
return umas.find((v) => v.chara_card_id === u) ?? null;
}
// function findUma(umas: Uma[], u: number): Uma | null {
// return umas.find((v) => v.chara_card_id === u) ?? null;
// }
/**
* Compute individual affinities for a legacy using the global region ruleset.
@@ -51,6 +48,7 @@ function findUma(umas: Uma[], u: number): Uma | null {
* @param legacy Legacy veterans
* @returns Individual affinities
*/
/*
export function globalAffinity(trainee: number, legacy: Legacy<Veteran>): Legacy<number> {
const t = findUma(uma.global, trainee)?.chara_id ?? 0;
const charas = mapLegacy(legacy, (u) => findUma(uma.global, u.uma)?.chara_id ?? 0);
@@ -70,3 +68,4 @@ export function globalAffinity(trainee: number, legacy: Legacy<Veteran>): Legacy
s22,
};
}
*/

View File

@@ -0,0 +1,14 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { resolve } from '$app/paths';
import { onMount } from 'svelte';
onMount(() => {
goto(resolve('/chara/affinity'), { replaceState: true });
});
</script>
<p class="mt-8 block w-full text-center text-4xl">
<a href={resolve('/chara/affinity')}>This page has moved.</a>
</p>
<p class="mt-8 block w-full text-center">You should be redirected momentarily.</p>

View File

@@ -0,0 +1,14 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { resolve } from '$app/paths';
import { onMount } from 'svelte';
onMount(() => {
goto(resolve('/chara/convo'), { replaceState: true });
});
</script>
<p class="mt-8 block w-full text-center text-4xl">
<a href={resolve('/chara/convo')}>This page has moved.</a>
</p>
<p class="mt-8 block w-full text-center">You should be redirected momentarily.</p>

View File

@@ -0,0 +1,14 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { resolve } from '$app/paths';
import { onMount } from 'svelte';
onMount(() => {
goto(resolve('/race/mspeed'), { replaceState: true });
});
</script>
<p class="mt-8 block w-full text-center text-4xl">
<a href={resolve('/race/mspeed')}>This page has moved.</a>
</p>
<p class="mt-8 block w-full text-center">You should be redirected momentarily.</p>

View File

@@ -0,0 +1,14 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { resolve } from '$app/paths';
import { onMount } from 'svelte';
onMount(() => {
goto(resolve('/race/spurt'), { replaceState: true });
});
</script>
<p class="mt-8 block w-full text-center text-4xl">
<a href={resolve('/race/spurt')}>This page has moved.</a>
</p>
<p class="mt-8 block w-full text-center">You should be redirected momentarily.</p>

View File

@@ -2,7 +2,6 @@
import './layout.css';
import favicon from '$lib/assets/favicon.png';
import { resolve } from '$app/paths';
import { affinity } from '$lib/data/affinity';
let { children } = $props();
</script>
@@ -19,10 +18,8 @@
</span>
<span class="flex-1 text-center">
<a href={resolve('/')} class="mx-8 my-1 block font-semibold md:hidden">Zenno Rob Roy</a>
<a href={resolve('/spurt')} class="mx-8 my-1 inline-block">Spurt Speed</a>
<a href={resolve('/mspeed')} class="mx-8 my-1 inline-block">Mechanical Speed</a>
<a href={resolve('/affinity')} class="mx-8 my-1 inline-block">Affinity Details</a>
<a href={resolve('/convo')} class="mx-8 my-1 inline-block">Lobby Conversations</a>
<a href={resolve('/race')} class="mx-8 my-1 inline-block">Race Tools</a>
<a href={resolve('/chara')} class="mx-8 my-1 inline-block">Character Tools</a>
<a href={resolve('/doc')} class="mx-8 my-1 inline-block">Documents</a>
</span>
</nav>

View File

@@ -5,22 +5,26 @@
<h1 class="m-8 text-center text-7xl">Zenno Rob Roy</h1>
<p>She's read all about Umamusume, and she's always happy to share her knowledge and give recommendations!</p>
<h2 class="mt-8 mb-4 text-4xl">Tools</h2>
<h2 class="mt-8 mb-4 text-4xl">Race Mechanics Tools</h2>
<ul class="mb-4 list-disc pl-4">
<li>
<a href={resolve('/spurt')}>Spurt Speed</a> &mdash; Calculate a horse's target speed in the last spurt and compare to other distance aptitudes
and running styles.
<a href={resolve('/race/spurt')}>Spurt Speed</a> &mdash; Calculate a horse's target speed in the last spurt and compare to other
distance aptitudes and running styles.
</li>
<li>
<a href={resolve('/mspeed')}>Front Runner Mechanical Speed Comparator</a> &mdash; Compare spot struggle and lane combo to the effects
of individual skills.
<a href={resolve('/race/mspeed')}>Front Runner Mechanical Speed Comparator</a> &mdash; Compare spot struggle and lane combo to the
effects of individual skills.
</li>
</ul>
<h2 class="mt-8 mb-4 text-4xl">Character Tools</h2>
<ul>
<li>
<a href={resolve('/chara/affinity')}>Affinity Details</a> &mdash; Details of why characters have the base compatibility numbers
they have.
</li>
<li>
<a href={resolve('/affinity')}>Affinity Details</a> &mdash; Details of why characters have the base compatibility numbers they have.
</li>
<li>
<a href={resolve('/convo')}>Lobby Conversations</a> &mdash; Check participants in lobby conversations and get recommendations on unlocking
them quickly.
<a href={resolve('/chara/convo')}>Lobby Conversations</a> &mdash; Check participants in lobby conversations and get recommendations
on unlocking them quickly.
</li>
<li>
<a href="https://discord.com/oauth2/authorize?client_id=1461931240264568994" target="_blank" rel="noopener noreferrer"

View File

@@ -0,0 +1,17 @@
<script lang="ts">
import { resolve } from '$app/paths';
</script>
<h1 class="m-8 text-center text-7xl">Zenno Rob Roy &mdash; Character Tools</h1>
<p>Tools related to understanding Umamusume characters.</p>
<ul class="mb-4 list-disc pl-4">
<li>
<a href={resolve('/chara/affinity')}>Affinity Details</a> &mdash; Details of why characters have the base compatibility numbers
they have.
</li>
<li>
<a href={resolve('/chara/convo')}>Lobby Conversations</a> &mdash; Check participants in lobby conversations and get recommendations
on unlocking them quickly.
</li>
</ul>

View File

@@ -416,8 +416,8 @@
<p>
In medium+ races, the extra HP consumption is a serious consideration; front runners need more stamina and recoveries than
other styles. At 1600m and shorter, the fact that Spot Struggle doesn't scale with race distance means that it can be worth
multiple gold speed skills in total distance gained. See the <a href={resolve('/mspeed')}>mechanical speed calculator</a> for precise
analysis.
multiple gold speed skills in total distance gained. See the <a href={resolve('/race/mspeed')}>mechanical speed calculator</a> for
precise analysis.
</p>
<Sec h={3} id="lane-combo">Lane Combo</Sec>
@@ -471,8 +471,8 @@
consistency at the cost of lowering the maximum gain.
</p>
<p>
The <a href={resolve('/mspeed')}>mechanical speed calculator</a> has an approximation of lane combo's benefit. A more precise
lane combo simulator exists at
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
<a href="https://lanecalc.hf-uma.net/" target="_blank" rel="noopener noreferrer">危険回避シミュ</a>, but I am not sufficiently
confident in my Japanese to try to guide readers through it.
<!-- TODO(zeph): i could totally annotate a picture though, or find someone else's explanation -->
@@ -682,7 +682,7 @@
Angling, they are almost certainly a different running style.
</p>
<p>
The <a href={resolve('/spurt')}>spurt speed calculator</a> analyzes this situation. A 1200 speed front runner with a 0.25 speed
The <a href={resolve('/race/spurt')}>spurt speed calculator</a> analyzes this situation. A 1200 speed front runner with a 0.25 speed
skill active has speed equivalent to an 1187 speed pace chaser. In other words, as long as that pace chaser is built the way Global
players tend to build, Pulse does not allow the front runner to pass back. So, if you happen to inherit it off a grandparent, it
is not worth taking.
@@ -868,7 +868,7 @@
<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
sprints. However, spot struggle is the only mechanic in the game that scales superlinearly with stats, so even the difference
between 1200 and 1000 guts can matter. See the <a href={resolve('/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>
<Sec h={3} id="chariot">Chariot</Sec>
@@ -996,8 +996,8 @@
</p>
<p>
As a corollary, you also cannot win this race with B mile. A miraculous start can get to 350 speed for this race; a B mile
runner with 350 speed is equivalent to an A mile runner with only 207 speed in career. See the <a href={resolve('/spurt')}
>spurt calculator</a
runner with 350 speed is equivalent to an A mile runner with only 207 speed in career. See the <a
href={resolve('/race/spurt')}>spurt calculator</a
>. (This race is why I made it.)
</p>

View File

@@ -1,3 +0,0 @@
<h1>Inheritance Chance</h1>
<p>Given a legacy, calculate the probability distribution of activation counts for each spark.</p>
<p>TODO</p>

View File

@@ -0,0 +1,17 @@
<script lang="ts">
import { resolve } from '$app/paths';
</script>
<h1 class="m-8 text-center text-7xl">Zenno Rob Roy &mdash; Character Tools</h1>
<p>Tools related to understanding Umamusume characters.</p>
<ul class="mb-4 list-disc pl-4">
<li>
<a href={resolve('/race/spurt')}>Spurt Speed</a> &mdash; Calculate a horse's target speed in the last spurt and compare to other
distance aptitudes and running styles.
</li>
<li>
<a href={resolve('/race/mspeed')}>Front Runner Mechanical Speed Comparator</a> &mdash; Compare spot struggle and lane combo to the
effects of individual skills.
</li>
</ul>

View File

@@ -1,6 +0,0 @@
<h1>Spark Generation Chance</h1>
<p>
Given a legacy, calculate the chance of generating each spark if you fulfill the conditions to do so, and the distribution of
total spark counts.
</p>
<p>TODO</p>

View File

@@ -1,4 +0,0 @@
<h1>My Veterans</h1>
<p>Set up and track your veterans for Zenno Rob Roy's inspiration and spark calculators.</p>
<p>All data is saved on your own machine, not transmitted or shared unless you explicitly choose to do so.</p>
<p>TODO</p>