quill/val Public Public: anyone can read this; nobody can change it.

forked from benjivers/val

workbenchthis machine
Files b02c1ef0dc92246d3da3567c343126686c5677c3
77 lines · 3.1 KB · ~896 tok Raw History
1
/**
2
 * Where this person is looking.
3
 *
4
 * The view angle is the browser's to move: the mouse arrives at frame rate,
5
 * and a snapshot is a description of a moment already gone. The client used
6
 * to take `snap.me.angle` on every snapshot, which dragged the camera back
7
 * to a stale angle thirty times a second — worst exactly when you turned
8
 * fastest, because that is when the stale angle is furthest away.
9
 *
10
 * So the local angle is the camera's, and the server's angle is taken only
11
 * when it is telling us something we did not say: there is no view yet, the
12
 * body under us changed, we respawned, or the angle that came back is one we
13
 * never sent. That last one is what the sent log is for — the server echoes
14
 * our own angle back, rounded, so an angle matching nothing we sent in the
15
 * last second came from the match (a round start recentring everybody at the
16
 * site) rather than from us, and is worth taking.
17
 *
18
 * Nothing here is sent anywhere: the angle still leaves through the input
19
 * timer exactly as it always did.
20
 */
21
22
/** How long a sent angle is remembered, in seconds. */
23
export const SENT_MEMORY = 1.2;
24
/** How close an echo must be to count as ours. The server rounds to 0.1. */
25
export const SENT_TOLERANCE = 0.08;
26
27
/** `corrected` counts the times the server's angle replaced ours: every one is a jump of the view. */
28
export const makeYaw = (angle = 0) => ({ angle, id: "", alive: false, ready: false, sent: [], corrected: 0 });
29
30
/** The short way round from one angle to another, in (-π, π]. */
31
export const shortWay = (from, to) => ((to - from + Math.PI * 3) % (Math.PI * 2)) - Math.PI;
32
33
/** A mouse delta, or an arrow key's share of a second. Ours, always taken. */
34
export function turn(yaw, delta) {
35
  yaw.angle += delta;
36
  return yaw.angle;
37
}
38
39
/** Point it somewhere outright: the top-down view's pointer aim. */
40
export function aim(yaw, angle) {
41
  yaw.angle = angle;
42
  return yaw.angle;
43
}
44
45
/** Remember an angle we told the server about, at a time in seconds. */
46
export function told(yaw, angle, at) {
47
  yaw.sent.push({ at, angle });
48
  while (yaw.sent.length && yaw.sent[0].at < at - SENT_MEMORY) yaw.sent.shift();
49
  return yaw;
50
}
51
52
/** Is this angle one we sent recently? An echo, not a correction. */
53
const ours = (yaw, angle, at) =>
54
  yaw.sent.some((s) => s.at >= at - SENT_MEMORY && Math.abs(shortWay(s.angle, angle)) <= SENT_TOLERANCE);
55
56
/**
57
 * A snapshot landed. Returns the angle to look along, having decided whether
58
 * the server's word replaces ours.
59
 *
60
 * `me` is the snapshot's own body: `{ id, angle, alive }`. `at` is now, in
61
 * seconds. An empty sent log is not evidence of anything — a client that has
62
 * not spoken yet keeps what it has.
63
 */
64
export function settle(yaw, me, at) {
65
  const seatChanged = !yaw.ready || me.id !== yaw.id;
66
  const respawned = me.alive && !yaw.alive;
67
  const corrected = yaw.sent.length > 0 && !ours(yaw, me.angle, at);
68
  if (seatChanged || respawned || corrected) {
69
    if (yaw.ready) yaw.corrected += 1;
70
    yaw.angle = me.angle;
71
    yaw.sent.length = 0;
72
  }
73
  yaw.id = me.id;
74
  yaw.alive = me.alive;
75
  yaw.ready = true;
76
  return yaw.angle;
77
}
↑↓ navigate ↵ open esc close
↑↓ navigate ↵ open esc close

Keyboard shortcuts