The friend across the net is no shambler: he just bleeds, and then he bursts
Two retest findings, one root: the death match borrowed the roster's body. Gone — nothing spawns, no walk-on card, the living opponent is the whole picture. His damage reads as blood (bleedO: an anchor per point taken this game, love to game point, thin drops as ever), the game point bursts him where he stands, and IT RISES AGAIN brings him back clean. The heal beat became a card in netplay — a modal freezes this world while the other phone's keeps moving. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c0b59eee90
commit
4c47295a73
6 files changed
+95
-68
No files matched your search
+8
-22
@@ -79,10 +79,6 @@ export function netApplyShot(m) {
|
||||
G.phase = 'rally'; G.swung = false; G.rallyNear = null;
|
||||
O.x = s.x; O.z = s.z; // the strike happened where the ball says it did
|
||||
O.pose = m.serve ? 'serve' : 'swing'; O.poseT = 0;
|
||||
if (G.net.death) { // ...and in a death match the PICTURE is the zombie, not O
|
||||
const rz = zombies.find(z => z.variant === 'r');
|
||||
if (rz) { rz.x = s.x; rz.z = s.z; if (m.serve) rz.serveHold = 0.4; }
|
||||
}
|
||||
}
|
||||
|
||||
function netApplyPoint(m) {
|
||||
@@ -117,7 +113,14 @@ function netStart(side, death) {
|
||||
G.classic = false;
|
||||
startMatch();
|
||||
G.net = n;
|
||||
G.modal = null; G.modalQ.length = 0; // the DEATH MATCH explainer must not eat the first serve
|
||||
// THE OPPONENT IS THE FRIEND, NOT A ROSTER BODY: startMatch walked THE SHAMBLER on (spawn +
|
||||
// name card) because it could not see the swap — take both back. The living O is the whole
|
||||
// picture (render draws him whenever hideO is false, splatter included — the bench proved it),
|
||||
// and the score reads on him as blood (bleedO), not as wound skins he does not have.
|
||||
zombies.length = 0;
|
||||
G.hideO = false;
|
||||
G.card = null;
|
||||
G.modal = null; G.modalQ.length = 0; // ...and the DEATH MATCH explainer must not eat the first serve
|
||||
}
|
||||
score.server = side === 'A' ? 'P' : 'O'; // the host serves first, on both scoreboards
|
||||
score.pts = [0, 0];
|
||||
@@ -169,23 +172,6 @@ export function netTick(dt) {
|
||||
O.x += (tx - O.x) * k; O.z += (tz - O.z) * k;
|
||||
if (O.pose !== 'swing' && O.pose !== 'serve') O.pose = o.m ? 'run' : 'idle';
|
||||
if (o.m) O.runT += dt;
|
||||
// DEATH MATCH: the body on screen is the racket zombie; O is only the serve-machinery ghost it
|
||||
// always is in a match. The zombie shadows O's driven position — stride bookkeeping like the
|
||||
// bench's walk, so the frames step off ground covered — except while the fall or a named serve
|
||||
// frame owns the picture. vx is recorded so a fall inherits the run, clamped against snaps.
|
||||
if (n.death && !G.matchFall) {
|
||||
const rz = zombies.find(z => z.variant === 'r');
|
||||
if (rz && !rz.showFrame) {
|
||||
const dx = O.x - rz.x, step = Math.hypot(dx, O.z - rz.z);
|
||||
if (step > 0.03) {
|
||||
rz.dist = (rz.dist || 0) + step;
|
||||
rz.vx = Math.max(-3, Math.min(3, dx / Math.max(dt, 1e-3)));
|
||||
if (Math.abs(dx) > 0.02) rz.face = dx > 0 ? 1 : -1;
|
||||
rz.pose = rz.pose === 'swing' ? 'swing' : 'run';
|
||||
} else { rz.pose = rz.pose === 'swing' ? 'swing' : 'idle'; rz.vx = 0; }
|
||||
rz.x = O.x; rz.z = O.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user