The match plays fair: deeper pool, no regicide, serves from the line
"the player is too weak in this mode. also the killing by smashing occurs too often. i cant really control it. maybe obsolete? also the serving after the first serve does not happen from behind the groundline". matchPlayerHp 8 — the match brings its own pool. The gore mode's 4 was an inheritance, not a decision, and a real game has rallies you deserve to lose without the run ending. Regicide is out of the match (kept in the duel, where any-weapon-counts is the point of sudden death). In a full game every hard serve that happened to meet the body was a free kill nobody aimed. A match ball never damages the opponent — it passes through like a soft ball and racketAI plays it — so the wound stages are exactly the scoreboard. That also made hp-per-opponent meaningless, so the ladder escalates in racketAI instead: +12% speed per body felled, whiff chance x0.82 per rung. And serving resets to behind the baseline with real deuce/ad mirroring: setupPoint's "serve from wherever you're standing" branch now excludes the match, which falls through to the tennis positioning. Verified live: second serve from z 24.3, x mirrored to the ad side, opponent unwounded by anything but the score. 38 tests, 15 seeds clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0620e97d6c
commit
ea6e50f8f8
8 files changed
+73
-17
No files matched your search
+6
-2
@@ -949,7 +949,10 @@ function racketAI(rz, dt) {
|
||||
const tz = Math.max(1.5, Math.min(COURT.svcFar, ball.z)); // chase laterally, hold deep on the far court
|
||||
const dx = ball.x - rz.x, dz = tz - rz.z, d = Math.hypot(dx, dz);
|
||||
if (d > 0.15) {
|
||||
const step = Math.min(TUNE.racketSpeed * dt, d);
|
||||
// THE MATCH LADDER ESCALATES HERE, not in hp: with regicide gone the pool is pure scoreboard,
|
||||
// so a harder opponent is a FASTER one that flubs less — the same knobs, scaled per body felled.
|
||||
const spd = TUNE.racketSpeed * (G.match ? 1 + (G.match.opp - 1) * TUNE.matchSpeedPer : 1);
|
||||
const step = Math.min(spd * dt, d);
|
||||
rz.dist = (rz.dist || 0) + step; // ground covered — his walk cycle steps off this, not the clock
|
||||
rz.x += dx / d * step; rz.z += dz / d * step; rz.runT += dt;
|
||||
if (rz.pose !== 'swing') rz.pose = 'run';
|
||||
@@ -958,7 +961,8 @@ function racketAI(rz, dt) {
|
||||
if (rz.swingCool <= 0 && rz.swingT < 0
|
||||
&& Math.hypot(ball.x - rz.x, (ball.z - rz.z) * 0.8) < TUNE.aiReach
|
||||
&& ball.y < CONTACT.maxY && ball.y > CONTACT.minY) {
|
||||
if (Math.random() < TUNE.racketFlub) rz.swingCool = 0.5; // whiff — it hesitates
|
||||
const flub = TUNE.racketFlub * (G.match ? Math.pow(TUNE.matchFlubKeep, G.match.opp - 1) : 1);
|
||||
if (Math.random() < flub) rz.swingCool = 0.5; // whiff — it hesitates (rarer per rung of the ladder)
|
||||
else { rz.swingT = TUNE.swingWindup + TUNE.swingWindow / 2; trySwing(rz, true, TUNE.racketQMax); rz.swingT = -1; rz.swingCool = 0.3; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user