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

forked from benjivers/val

workbenchthis machine
Files b6659f7ce5f631d7b5dda87f8af0bd7d2e0a5b4f
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
export const makeYaw = (angle = 0) => ({ angle, id: "", alive: false, ready: false, sent: [] });
28
29
/** The short way round from one angle to another, in (-π, π]. */
30
export const shortWay = (from, to) => ((to - from + Math.PI * 3) % (Math.PI * 2)) - Math.PI;
31
32
/** A mouse delta, or an arrow key's share of a second. Ours, always taken. */
33
export function turn(yaw, delta) {
34
  yaw.angle += delta;
35
  return yaw.angle;
36
}
37
38
/** Point it somewhere outright: the top-down view's pointer aim. */
39
export function aim(yaw, angle) {
40
  yaw.angle = angle;
41
  return yaw.angle;
42
}
43
44
/** Remember an angle we told the server about, at a time in seconds. */
45
export function told(yaw, angle, at) {
46
  yaw.sent.push({ at, angle });
47
  while (yaw.sent.length && yaw.sent[0].at < at - SENT_MEMORY) yaw.sent.shift();
48
  return yaw;
49
}
50
51
/** Is this angle one we sent recently? An echo, not a correction. */
52
const ours = (yaw, angle, at) =>
53
  yaw.sent.some((s) => s.at >= at - SENT_MEMORY && Math.abs(shortWay(s.angle, angle)) <= SENT_TOLERANCE);
54
55
/**
56
 * A snapshot landed. Returns the angle to look along, having decided whether
57
 * the server's word replaces ours.
58
 *
59
 * `me` is the snapshot's own body: `{ id, angle, alive }`. `at` is now, in
60
 * seconds. An empty sent log is not evidence of anything — a client that has
61
 * not spoken yet keeps what it has.
62
 */
63
export function settle(yaw, me, at) {
64
  const seatChanged = !yaw.ready || me.id !== yaw.id;
65
  const respawned = me.alive && !yaw.alive;
66
  const corrected = yaw.sent.length > 0 && !ours(yaw, me.angle, at);
67
  if (seatChanged || respawned || corrected) {
68
    yaw.angle = me.angle;
69
    yaw.sent.length = 0;
70
  }
71
  yaw.id = me.id;
72
  yaw.alive = me.alive;
73
  yaw.ready = true;
74
  return yaw.angle;
75
}
↑↓ navigate ↵ open esc close
↑↓ navigate ↵ open esc close

Keyboard shortcuts