zenno: section speed does not use base wit
Per analysis by Aya, only final wit is used for section speed. Fixes #40.
This commit is contained in:
+4
-10
@@ -504,14 +504,12 @@ export function baseTargetSpeed(
|
|||||||
/**
|
/**
|
||||||
* Calculate the range of section speed values for a horse in early or mid race.
|
* Calculate the range of section speed values for a horse in early or mid race.
|
||||||
* @param raceLen Length of the race in meters
|
* @param raceLen Length of the race in meters
|
||||||
* @param baseWit Base wit, after mood but before other modifiers
|
|
||||||
* @param witStat Final wit stat, including strategy proficiency and skills
|
* @param witStat Final wit stat, including strategy proficiency and skills
|
||||||
* @param style Horse's running style
|
* @param style Horse's running style
|
||||||
* @param phase Phase of the current section
|
* @param phase Phase of the current section
|
||||||
*/
|
*/
|
||||||
export function sectionSpeed(
|
export function sectionSpeed(
|
||||||
raceLen: number,
|
raceLen: number,
|
||||||
baseWit: number,
|
|
||||||
witStat: number,
|
witStat: number,
|
||||||
style: RunningStyle,
|
style: RunningStyle,
|
||||||
phase: Exclude<Phase, Phase.LateRace>,
|
phase: Exclude<Phase, Phase.LateRace>,
|
||||||
@@ -520,7 +518,6 @@ export function sectionSpeed(
|
|||||||
* Calculate the range of section speed values for a horse not spurting during late race.
|
* Calculate the range of section speed values for a horse not spurting during late race.
|
||||||
* @param raceLen Length of the race in meters
|
* @param raceLen Length of the race in meters
|
||||||
* @param speedStat Final speed stat
|
* @param speedStat Final speed stat
|
||||||
* @param baseWit Base wit, after mood but before other modifiers
|
|
||||||
* @param witStat Final wit stat, including strategy proficiency and skills
|
* @param witStat Final wit stat, including strategy proficiency and skills
|
||||||
* @param style Horse's running style
|
* @param style Horse's running style
|
||||||
* @param distance Hores's distance proficiency aptitude
|
* @param distance Hores's distance proficiency aptitude
|
||||||
@@ -529,7 +526,6 @@ export function sectionSpeed(
|
|||||||
export function sectionSpeed(
|
export function sectionSpeed(
|
||||||
raceLen: number,
|
raceLen: number,
|
||||||
speedStat: number,
|
speedStat: number,
|
||||||
baseWit: number,
|
|
||||||
witStat: number,
|
witStat: number,
|
||||||
style: RunningStyle,
|
style: RunningStyle,
|
||||||
distance: AptitudeLevel,
|
distance: AptitudeLevel,
|
||||||
@@ -537,16 +533,14 @@ export function sectionSpeed(
|
|||||||
): [number, number];
|
): [number, number];
|
||||||
export function sectionSpeed(
|
export function sectionSpeed(
|
||||||
raceLen: number,
|
raceLen: number,
|
||||||
speedStatOrBaseWit: number,
|
speedStatOrWitStat: number,
|
||||||
baseWitOrWitStat: number,
|
|
||||||
witStatOrStyle: number | RunningStyle,
|
witStatOrStyle: number | RunningStyle,
|
||||||
styleOrPhase: RunningStyle | Phase,
|
styleOrPhase: RunningStyle | Phase,
|
||||||
distance?: AptitudeLevel,
|
distance?: AptitudeLevel,
|
||||||
lateRace?: Phase.LateRace,
|
lateRace?: Phase.LateRace,
|
||||||
): [number, number] {
|
): [number, number] {
|
||||||
const speedStat = lateRace !== undefined ? speedStatOrBaseWit : 0;
|
const speedStat = lateRace !== undefined ? speedStatOrWitStat : 0;
|
||||||
const baseWit = lateRace !== undefined ? baseWitOrWitStat : speedStatOrBaseWit;
|
const witStat = lateRace !== undefined ? witStatOrStyle : speedStatOrWitStat;
|
||||||
const witStat = lateRace !== undefined ? witStatOrStyle : baseWitOrWitStat;
|
|
||||||
const style = lateRace !== undefined ? (styleOrPhase as RunningStyle) : (witStatOrStyle as RunningStyle);
|
const style = lateRace !== undefined ? (styleOrPhase as RunningStyle) : (witStatOrStyle as RunningStyle);
|
||||||
const phase = lateRace !== undefined ? lateRace : (styleOrPhase as Phase);
|
const phase = lateRace !== undefined ? lateRace : (styleOrPhase as Phase);
|
||||||
const base = baseSpeed(raceLen);
|
const base = baseSpeed(raceLen);
|
||||||
@@ -555,7 +549,7 @@ export function sectionSpeed(
|
|||||||
phase === Phase.LateRace
|
phase === Phase.LateRace
|
||||||
? (math.sqrt(500 * speedStat) as number) * distanceProficiencyMod[distance ?? AptitudeLevel.A] * 0.002
|
? (math.sqrt(500 * speedStat) as number) * distanceProficiencyMod[distance ?? AptitudeLevel.A] * 0.002
|
||||||
: 0;
|
: 0;
|
||||||
const u = (witStat / 550000) * math.log10(baseWit * 0.1);
|
const u = (witStat / 550000) * math.log10(witStat * 0.1);
|
||||||
const l = u - 0.0065;
|
const l = u - 0.0065;
|
||||||
return [baseTarget + late + base * l, baseTarget + late + base * u];
|
return [baseTarget + late + base * l, baseTarget + late + base * u];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@
|
|||||||
|
|
||||||
const uphillSlowPow = 800;
|
const uphillSlowPow = 800;
|
||||||
const uphillFastPow = 1200;
|
const uphillFastPow = 1200;
|
||||||
const uphillBaseSpeed = mean2(sectionSpeed(2500, 1200, 1200, RunningStyle.FrontRunner, Phase.MidRace));
|
const uphillBaseSpeed = mean2(sectionSpeed(2500, 1200, RunningStyle.FrontRunner, Phase.MidRace));
|
||||||
const uphillSlopes = [
|
const uphillSlopes = [
|
||||||
{ per: 2, len: 110 },
|
{ per: 2, len: 110 },
|
||||||
{ per: 1.5, len: 200 },
|
{ per: 1.5, len: 200 },
|
||||||
@@ -137,13 +137,13 @@
|
|||||||
|
|
||||||
const secSpeedS = 1200;
|
const secSpeedS = 1200;
|
||||||
const secSpeedA = 1000;
|
const secSpeedA = 1000;
|
||||||
const secSpeedExample = $derived(sectionSpeed(raceLen, secSpeedS, secSpeedS * 1.1, RunningStyle.FrontRunner, Phase.EarlyRace));
|
const secSpeedExample = $derived(sectionSpeed(raceLen, secSpeedS * 1.1, RunningStyle.FrontRunner, Phase.EarlyRace));
|
||||||
const secSpeedInfo = $derived(secSpeedExample.map((x) => x.toFixed(2)).join(' to '));
|
const secSpeedInfo = $derived(secSpeedExample.map((x) => x.toFixed(2)).join(' to '));
|
||||||
const secSpeedPassTime = $derived.by(() => {
|
const secSpeedPassTime = $derived.by(() => {
|
||||||
const sSecSpeed = mean2(sectionSpeed(raceLen, secSpeedS, secSpeedS * 1.1, RunningStyle.FrontRunner, Phase.MidRace));
|
const sSecSpeed = mean2(sectionSpeed(raceLen, secSpeedS * 1.1, RunningStyle.FrontRunner, Phase.MidRace));
|
||||||
const sMode = frontModeEnterChance(secSpeedS * 1.1);
|
const sMode = frontModeEnterChance(secSpeedS * 1.1);
|
||||||
const sOvertakeSpeed = modemean(sSecSpeed, 1.05, sMode);
|
const sOvertakeSpeed = modemean(sSecSpeed, 1.05, sMode);
|
||||||
const aSecSpeed = mean2(sectionSpeed(raceLen, secSpeedA, secSpeedA, RunningStyle.FrontRunner, Phase.MidRace));
|
const aSecSpeed = mean2(sectionSpeed(raceLen, secSpeedA, RunningStyle.FrontRunner, Phase.MidRace));
|
||||||
const aMode = frontModeEnterChance(secSpeedA);
|
const aMode = frontModeEnterChance(secSpeedA);
|
||||||
const aSpeedupSpeed = modemean(aSecSpeed, 1.04, aMode);
|
const aSpeedupSpeed = modemean(aSecSpeed, 1.04, aMode);
|
||||||
const r = 2 / (sOvertakeSpeed - aSpeedupSpeed);
|
const r = 2 / (sOvertakeSpeed - aSpeedupSpeed);
|
||||||
@@ -183,35 +183,35 @@
|
|||||||
const secSpeedSeries: Array<ComputedAreas | null> = $derived([
|
const secSpeedSeries: Array<ComputedAreas | null> = $derived([
|
||||||
{
|
{
|
||||||
label: 'Early Race',
|
label: 'Early Race',
|
||||||
y1: (x) => sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.EarlyRace)[0],
|
y1: (x) => sectionSpeed(raceLen, x, secSpeedStyle, Phase.EarlyRace)[0],
|
||||||
y2: (x) => sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.EarlyRace)[1],
|
y2: (x) => sectionSpeed(raceLen, x, secSpeedStyle, Phase.EarlyRace)[1],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Mid Race',
|
label: 'Mid Race',
|
||||||
y1: (x) => sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.MidRace)[0],
|
y1: (x) => sectionSpeed(raceLen, x, secSpeedStyle, Phase.MidRace)[0],
|
||||||
y2: (x) => sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.MidRace)[1],
|
y2: (x) => sectionSpeed(raceLen, x, secSpeedStyle, Phase.MidRace)[1],
|
||||||
},
|
},
|
||||||
secIsFront
|
secIsFront
|
||||||
? {
|
? {
|
||||||
label: 'Early Race + Mean Speed-Up Mode',
|
label: 'Early Race + Mean Speed-Up Mode',
|
||||||
y1: (x) => modemean(sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.EarlyRace)[0], 1.04, frontModeEnterChance(x)),
|
y1: (x) => modemean(sectionSpeed(raceLen, x, secSpeedStyle, Phase.EarlyRace)[0], 1.04, frontModeEnterChance(x)),
|
||||||
y2: (x) => modemean(sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.EarlyRace)[1], 1.04, frontModeEnterChance(x)),
|
y2: (x) => modemean(sectionSpeed(raceLen, x, secSpeedStyle, Phase.EarlyRace)[1], 1.04, frontModeEnterChance(x)),
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
label: 'Early Race + Mean Pace-Up Mode',
|
label: 'Early Race + Mean Pace-Up Mode',
|
||||||
y1: (x) => modemean(sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.EarlyRace)[0], 1.04, paceUpEnterChance(x)),
|
y1: (x) => modemean(sectionSpeed(raceLen, x, secSpeedStyle, Phase.EarlyRace)[0], 1.04, paceUpEnterChance(x)),
|
||||||
y2: (x) => modemean(sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.EarlyRace)[1], 1.04, paceUpEnterChance(x)),
|
y2: (x) => modemean(sectionSpeed(raceLen, x, secSpeedStyle, Phase.EarlyRace)[1], 1.04, paceUpEnterChance(x)),
|
||||||
},
|
},
|
||||||
secIsFront
|
secIsFront
|
||||||
? {
|
? {
|
||||||
label: 'Mid Race + Mean Speed-Up Mode',
|
label: 'Mid Race + Mean Speed-Up Mode',
|
||||||
y1: (x) => modemean(sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.MidRace)[0], 1.04, frontModeEnterChance(x)),
|
y1: (x) => modemean(sectionSpeed(raceLen, x, secSpeedStyle, Phase.MidRace)[0], 1.04, frontModeEnterChance(x)),
|
||||||
y2: (x) => modemean(sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.MidRace)[1], 1.04, frontModeEnterChance(x)),
|
y2: (x) => modemean(sectionSpeed(raceLen, x, secSpeedStyle, Phase.MidRace)[1], 1.04, frontModeEnterChance(x)),
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
label: 'Mid Race + Mean Pace-Up Mode',
|
label: 'Mid Race + Mean Pace-Up Mode',
|
||||||
y1: (x) => modemean(sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.MidRace)[0], 1.04, paceUpEnterChance(x)),
|
y1: (x) => modemean(sectionSpeed(raceLen, x, secSpeedStyle, Phase.MidRace)[0], 1.04, paceUpEnterChance(x)),
|
||||||
y2: (x) => modemean(sectionSpeed(raceLen, x, x, secSpeedStyle, Phase.MidRace)[1], 1.04, paceUpEnterChance(x)),
|
y2: (x) => modemean(sectionSpeed(raceLen, x, secSpeedStyle, Phase.MidRace)[1], 1.04, paceUpEnterChance(x)),
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
const fcSeries: ComputedSeries[] = $derived([
|
const fcSeries: ComputedSeries[] = $derived([
|
||||||
@@ -649,10 +649,7 @@
|
|||||||
ref="https://docs.google.com/document/d/15VzW9W2tXBBTibBRbZ8IVpW6HaMX8H0RP03kq6Az7Xg/edit?tab=t.0#heading=h.xdha40q2176g"
|
ref="https://docs.google.com/document/d/15VzW9W2tXBBTibBRbZ8IVpW6HaMX8H0RP03kq6Az7Xg/edit?tab=t.0#heading=h.xdha40q2176g"
|
||||||
>Section Speed</Sec
|
>Section Speed</Sec
|
||||||
>
|
>
|
||||||
<p>
|
<p>Each section, each horse gets a random modifier to target speed. The modifier's range is determined by the wit stat.</p>
|
||||||
Each section, each horse gets a random modifier to target speed. The modifier's range is determined by the wit stat.
|
|
||||||
(Curiously, the calculation uses both wit as modified by style proficiency and green skills as well as base wit.)
|
|
||||||
</p>
|
|
||||||
<div class="mb-24 h-60 w-full md:mb-20 md:h-96">
|
<div class="mb-24 h-60 w-full md:mb-20 md:h-96">
|
||||||
<StatChart
|
<StatChart
|
||||||
class="mx-auto mb-12 h-full w-full max-w-3xl md:mb-10"
|
class="mx-auto mb-12 h-full w-full max-w-3xl md:mb-10"
|
||||||
|
|||||||
@@ -86,37 +86,35 @@
|
|||||||
const secSpeed: Array<ComputedAreas | null> = $derived([
|
const secSpeed: Array<ComputedAreas | null> = $derived([
|
||||||
{
|
{
|
||||||
label: 'Early Race',
|
label: 'Early Race',
|
||||||
y1: (x) => race.sectionSpeed(raceLen, x, x, style, race.Phase.EarlyRace)[0],
|
y1: (x) => race.sectionSpeed(raceLen, x, style, race.Phase.EarlyRace)[0],
|
||||||
y2: (x) => race.sectionSpeed(raceLen, x, x, style, race.Phase.EarlyRace)[1],
|
y2: (x) => race.sectionSpeed(raceLen, x, style, race.Phase.EarlyRace)[1],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Mid Race',
|
label: 'Mid Race',
|
||||||
y1: (x) => race.sectionSpeed(raceLen, x, x, style, race.Phase.MidRace)[0],
|
y1: (x) => race.sectionSpeed(raceLen, x, style, race.Phase.MidRace)[0],
|
||||||
y2: (x) => race.sectionSpeed(raceLen, x, x, style, race.Phase.MidRace)[1],
|
y2: (x) => race.sectionSpeed(raceLen, x, style, race.Phase.MidRace)[1],
|
||||||
},
|
},
|
||||||
styleIsFront
|
styleIsFront
|
||||||
? {
|
? {
|
||||||
label: 'Early Race + Mean Speed-Up Mode',
|
label: 'Early Race + Mean Speed-Up Mode',
|
||||||
y1: (x) =>
|
y1: (x) => modemean(race.sectionSpeed(raceLen, x, style, race.Phase.EarlyRace)[0], 1.04, race.frontModeEnterChance(x)),
|
||||||
modemean(race.sectionSpeed(raceLen, x, x, style, race.Phase.EarlyRace)[0], 1.04, race.frontModeEnterChance(x)),
|
y2: (x) => modemean(race.sectionSpeed(raceLen, x, style, race.Phase.EarlyRace)[1], 1.04, race.frontModeEnterChance(x)),
|
||||||
y2: (x) =>
|
|
||||||
modemean(race.sectionSpeed(raceLen, x, x, style, race.Phase.EarlyRace)[1], 1.04, race.frontModeEnterChance(x)),
|
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
label: 'Early Race + Mean Pace-Up Mode',
|
label: 'Early Race + Mean Pace-Up Mode',
|
||||||
y1: (x) => modemean(race.sectionSpeed(raceLen, x, x, style, race.Phase.EarlyRace)[0], 1.04, race.paceUpEnterChance(x)),
|
y1: (x) => modemean(race.sectionSpeed(raceLen, x, style, race.Phase.EarlyRace)[0], 1.04, race.paceUpEnterChance(x)),
|
||||||
y2: (x) => modemean(race.sectionSpeed(raceLen, x, x, style, race.Phase.EarlyRace)[1], 1.04, race.paceUpEnterChance(x)),
|
y2: (x) => modemean(race.sectionSpeed(raceLen, x, style, race.Phase.EarlyRace)[1], 1.04, race.paceUpEnterChance(x)),
|
||||||
},
|
},
|
||||||
styleIsFront
|
styleIsFront
|
||||||
? {
|
? {
|
||||||
label: 'Mid Race + Mean Speed-Up Mode',
|
label: 'Mid Race + Mean Speed-Up Mode',
|
||||||
y1: (x) => modemean(race.sectionSpeed(raceLen, x, x, style, race.Phase.MidRace)[0], 1.04, race.frontModeEnterChance(x)),
|
y1: (x) => modemean(race.sectionSpeed(raceLen, x, style, race.Phase.MidRace)[0], 1.04, race.frontModeEnterChance(x)),
|
||||||
y2: (x) => modemean(race.sectionSpeed(raceLen, x, x, style, race.Phase.MidRace)[1], 1.04, race.frontModeEnterChance(x)),
|
y2: (x) => modemean(race.sectionSpeed(raceLen, x, style, race.Phase.MidRace)[1], 1.04, race.frontModeEnterChance(x)),
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
label: 'Mid Race + Mean Pace-Up Mode',
|
label: 'Mid Race + Mean Pace-Up Mode',
|
||||||
y1: (x) => modemean(race.sectionSpeed(raceLen, x, x, style, race.Phase.MidRace)[0], 1.04, race.paceUpEnterChance(x)),
|
y1: (x) => modemean(race.sectionSpeed(raceLen, x, style, race.Phase.MidRace)[0], 1.04, race.paceUpEnterChance(x)),
|
||||||
y2: (x) => modemean(race.sectionSpeed(raceLen, x, x, style, race.Phase.MidRace)[1], 1.04, race.paceUpEnterChance(x)),
|
y2: (x) => modemean(race.sectionSpeed(raceLen, x, style, race.Phase.MidRace)[1], 1.04, race.paceUpEnterChance(x)),
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
const downhill: ComputedSeries[] = [
|
const downhill: ComputedSeries[] = [
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
const damCarry = $derived(allowDAM && slope < 0 ? race.downhillAccelMod(slope) : 0);
|
const damCarry = $derived(allowDAM && slope < 0 ? race.downhillAccelMod(slope) : 0);
|
||||||
const carry = $derived(skillCarry + damCarry);
|
const carry = $derived(skillCarry + damCarry);
|
||||||
const midSpeed = $derived.by(() => {
|
const midSpeed = $derived.by(() => {
|
||||||
const s = race.sectionSpeed(raceLen, baseWit, wit, style, race.Phase.MidRace) satisfies [number, number];
|
const s = race.sectionSpeed(raceLen, wit, style, race.Phase.MidRace) satisfies [number, number];
|
||||||
const u = slope > 0 ? race.uphillMod(power, slope) : 0;
|
const u = slope > 0 ? race.uphillMod(power, slope) : 0;
|
||||||
return [s[0] + u, s[1] + u] as const;
|
return [s[0] + u, s[1] + u] as const;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
}
|
}
|
||||||
return [0, 0];
|
return [0, 0];
|
||||||
});
|
});
|
||||||
const earlyTarget = $derived(race.sectionSpeed(raceLen, baseWit, wit, style, race.Phase.EarlyRace));
|
const earlyTarget = $derived(race.sectionSpeed(raceLen, wit, style, race.Phase.EarlyRace));
|
||||||
const speeds: [number, number] = $derived([earlyTarget[0] + hillMod[0], earlyTarget[1] + hillMod[1]]);
|
const speeds: [number, number] = $derived([earlyTarget[0] + hillMod[0], earlyTarget[1] + hillMod[1]]);
|
||||||
|
|
||||||
const startInstant: accel.Instant = { t: 0, x: 0, v: 3 };
|
const startInstant: accel.Instant = { t: 0, x: 0, v: 3 };
|
||||||
|
|||||||
@@ -96,14 +96,8 @@
|
|||||||
|
|
||||||
const distType = $derived(race.distance(raceLen));
|
const distType = $derived(race.distance(raceLen));
|
||||||
const phaseSpeed = $derived({
|
const phaseSpeed = $derived({
|
||||||
[race.Phase.EarlyRace]: race.sectionSpeed(
|
[race.Phase.EarlyRace]: race.sectionSpeed(raceLen, stats[race.Stat.Wit], style, race.Phase.EarlyRace),
|
||||||
raceLen,
|
[race.Phase.MidRace]: race.sectionSpeed(raceLen, stats[race.Stat.Wit], style, race.Phase.MidRace),
|
||||||
baseStats[race.Stat.Wit],
|
|
||||||
stats[race.Stat.Wit],
|
|
||||||
style,
|
|
||||||
race.Phase.EarlyRace,
|
|
||||||
),
|
|
||||||
[race.Phase.MidRace]: race.sectionSpeed(raceLen, baseStats[race.Stat.Wit], stats[race.Stat.Wit], style, race.Phase.MidRace),
|
|
||||||
[race.Phase.LateRace]: [
|
[race.Phase.LateRace]: [
|
||||||
race.spurtSpeed(stats[race.Stat.Speed], stats[race.Stat.Guts], style, distanceApt, raceLen),
|
race.spurtSpeed(stats[race.Stat.Speed], stats[race.Stat.Guts], style, distanceApt, raceLen),
|
||||||
race.spurtSpeed(stats[race.Stat.Speed], stats[race.Stat.Guts], style, distanceApt, raceLen),
|
race.spurtSpeed(stats[race.Stat.Speed], stats[race.Stat.Guts], style, distanceApt, raceLen),
|
||||||
|
|||||||
Reference in New Issue
Block a user