The match walks back to centre — "unreachable" was the player, not the CPU
"every second ball is basically unreachable by an auto-run player.. are there some hidden gestures I don't know about or is it just a very strong cpu?" Neither. The match inherited gore-splatter's depth-only recovery — the sidestep-protection rule — by being G.mode 'splatter'. One wide return pulled you off centre and you stayed there, so the next ball to the opposite corner was lost before it was struck. A player who never walks back experiences every rally as unreachable, and it reads as CPU strength because the balls keep landing where he isn't. The match recovers to centre now, like tennis: real footwork, and in a rally there is no artillery lane to protect. Gore splatter keeps depth-only — the sidestep it protects has no role inside a rally. matchSpeedBase 1.4 -> 1.25: it was calibrated against a player who couldn't move. The full attacking vocabulary is recorded in PROJECT.md — nothing else is hidden. The placement flick (aim during the swing) is taught nowhere on touch; flagged as a ghost-hand lesson if the mode ships. 42 tests, 12 seeds clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
24be613c61
commit
d6df582cd4
5 files changed
+55
-11
No files matched your search
+4
-3
@@ -386,9 +386,10 @@ export const TUNE = {
|
||||
matchPlayerHp: 8, // your pool for the MATCH — richer than the gore mode's 4, because a real game
|
||||
// has rallies you deserve to lose without the run ending ("the player is too
|
||||
// weak in this mode"). Their point still costs 1; matchHeal is how you last
|
||||
matchSpeedBase: 1.4, // racketAI speed multiplier for opponent ONE — the duel's 2.8 m/s lumber was
|
||||
// tuned for a single sudden-death point and read as "very weak and slow"
|
||||
// across a whole game (~3.9 m/s now, rising per rung)
|
||||
matchSpeedBase: 1.25, // racketAI speed multiplier for opponent ONE. 1.4 was calibrated against
|
||||
// the broken recovery (the player never walked back to centre, so every
|
||||
// wide return looked like opponent strength) — with real footwork restored
|
||||
// it starts gentler and the ladder still climbs
|
||||
matchSpeedPer: 0.12, // ...growing this much per opponent felled
|
||||
matchFlub: 0.08, // the match's own whiff base — the duel's 0.2 gives away a fifth of all
|
||||
// returns, which across a game is an opponent that beats itself
|
||||
|
||||
+12
-7
@@ -1296,14 +1296,19 @@ export function update(dt) {
|
||||
const chasing = ball.lastHit === 'O' || (G.mode === 'splatter' && !G.interlude && ball.vz > 0);
|
||||
// no `slow` here: tapping must not freeze your legs, or anticipating a shot loses it
|
||||
const rate = TUNE.playerSpeed * TUNE.autoAssist * dt * (chasing ? 1 : 0.55);
|
||||
// Run to the ball — then recover in DEPTH ONLY, holding whatever lane you are standing in.
|
||||
// Recovering to HOME.P's x undid the sidestep: measured, a step to 1.94 m was dragged back to
|
||||
// 0.77 m over one ball's flight, so firing gave back most of a dodge you had spent a cooldown
|
||||
// on. That is the "welded in place" complaint the sidestep exists to answer, arriving slowly
|
||||
// instead of all at once. TENNIS keeps the full recovery — recovering to centre is the real
|
||||
// sport's footwork and there is no sidestep there to protect.
|
||||
// Run to the ball — then recover. WHERE you recover to is mode-specific and each rule exists
|
||||
// for a reason:
|
||||
// GORE SPLATTER recovers in DEPTH ONLY, holding your lane — recovering to HOME.P's x undid
|
||||
// the sidestep (measured: a step to 1.94 m dragged back to 0.77 m over one ball's flight),
|
||||
// which is the "welded in place" complaint the sidestep answers, arriving slowly.
|
||||
// TENNIS and THE MATCH recover to CENTRE — that is the real sport's footwork, and in a
|
||||
// rally there is no artillery lane to protect. The match inherited the gore rule by being
|
||||
// G.mode 'splatter', and the cost was exactly Oliver's "every second ball is basically
|
||||
// unreachable": one wide return pulled you off centre and you STAYED there, so the next
|
||||
// ball to the opposite corner was lost before it was struck. Not a strong CPU — a player
|
||||
// who never walked back.
|
||||
const tgt = chasing ? intercept('P')
|
||||
: G.mode === 'splatter' ? { x: P.x, z: HOME.P.z }
|
||||
: G.mode === 'splatter' && !G.match ? { x: P.x, z: HOME.P.z }
|
||||
: HOME.P;
|
||||
const dx = tgt.x - P.x, dz = tgt.z - P.z, d = Math.hypot(dx, dz);
|
||||
if (d > 0.35) { // deadzone: stand ready near the spot instead of dithering over it
|
||||
|
||||
Reference in new issue
Block a user