feat(excitebike): add cool-zone speed boost and cooldown feedback
- Allow bikes to exceed normal turbo speed when holding through cool zones with turbo engaged, rewarding track knowledge - Emit 'cooldown' event when entering cool zones to clear center msg - Add coolZoneBoostSpeed tune constant (240) with design documentation - Update physics invariant checks to use new speed cap
This commit is contained in:
parent
b42a71bf2f
commit
d5f5e8981a
|
|
@ -707,6 +707,9 @@ export default class ExcitebikeGame extends Phaser.Scene {
|
|||
this.crt.pulse(0.6, 240);
|
||||
}
|
||||
break;
|
||||
case 'cooldown':
|
||||
if (ev.isPlayer) this.setCenterMsg('');
|
||||
break;
|
||||
case 'lap':
|
||||
if (ev.isPlayer) playSound(this, SFX.EIGHTBIT_ACTIVATE);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ export const TUNE = {
|
|||
heatRiseRate: 1 / 7,
|
||||
heatFallRate: 1 / 5,
|
||||
coolZoneRate: 1 / 1.2,
|
||||
// Holding turbo through a cool zone also kicks the bike past its normal
|
||||
// ceiling — a real reward for finding the chevrons, not just a way to
|
||||
// dodge heat. Coasting through one gets no speed bonus, only the cooling.
|
||||
coolZoneBoostSpeed: 240,
|
||||
overheatMs: 4000,
|
||||
|
||||
// Lanes.
|
||||
|
|
@ -437,6 +441,7 @@ function stepBike(state, b, input) {
|
|||
b.state = STATE.RIDING;
|
||||
b.stateMs = 0;
|
||||
b.temp = 0;
|
||||
emit(state, { type: 'cooldown', bike: b.index, isPlayer: b.isPlayer });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -462,6 +467,7 @@ function stepBike(state, b, input) {
|
|||
else if (input.a) target = TUNE.speedAccel;
|
||||
|
||||
if (surf === SURFACE.MUD && grounded(b)) target = Math.min(target, TUNE.mudSpeedCap);
|
||||
else if (surf === SURFACE.COOL && grounded(b) && turbo) target = TUNE.coolZoneBoostSpeed;
|
||||
|
||||
if (b.vx < target) {
|
||||
b.vx = Math.min(target, b.vx + TUNE.accelRate * DT);
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ section('4. Physics invariants');
|
|||
for (const b of state.bikes) {
|
||||
seenStates.add(b.state);
|
||||
if (![b.x, b.vx, b.y, b.vy, b.lane, b.pitch, b.temp].every(Number.isFinite)) nan += 1;
|
||||
if (b.vx > TUNE.speedTurbo + 1 || b.vx < -0.001) overSpeed += 1;
|
||||
if (b.vx > TUNE.coolZoneBoostSpeed + 1 || b.vx < -0.001) overSpeed += 1;
|
||||
if (b.temp < -0.001 || b.temp > 1.001) badTemp += 1;
|
||||
if (b.lane < -0.001 || b.lane > LANE_COUNT - 1 + 0.001) badLane += 1;
|
||||
if (b.state === STATE.RIDING && b.y < -0.5) sunk += 1;
|
||||
|
|
@ -431,7 +431,7 @@ section('4. Physics invariants');
|
|||
}
|
||||
|
||||
check('nothing ever goes NaN', nan === 0, `${nan} samples`);
|
||||
check('speed never exceeds the turbo cap', overSpeed === 0, `${overSpeed} samples`);
|
||||
check('speed never exceeds the cool-zone boost cap', overSpeed === 0, `${overSpeed} samples`);
|
||||
check('temperature stays in 0..1', badTemp === 0, `${badTemp} samples`);
|
||||
check('bikes stay on the four lanes', badLane === 0, `${badLane} samples`);
|
||||
check('a riding bike never sinks below the ground', sunk === 0, `${sunk} samples`);
|
||||
|
|
|
|||
Loading…
Reference in New Issue