Watch a held body for a time, not for a count of frames
game-maker / gate (push) Successful in 2m52s
game-maker / suite (push) Successful in 14m21s

The suite to 46c620a (#294) was red by one check: e2e 41, "a body
dragged while playing hangs where the pointer holds it and is let
go at rest". The body hung where it should, on -3490 in every
frame, and fell from rest. The check failed on its own bound of 30
frames while held: that run drew 21 in the second of holding, the
green runs of the day drew 37 to 54.

- The bound is now the time the hold was watched: 800 ms between
  the first and the last sample before the release, and five
  samples at least.
- The detail of the check names that time next to the frames.
- Nothing in src/ changes.

This is not the wobble of 9cff528 and 543b052 (#282) once more.
Those were about when the samples are taken, this one about how
many a runner manages. Why that run was so slow is not known.

Tests:
- e2e 41 on melektaus-atx: 21 checks, all pass, 66 frames in 1114
  ms while held.
- No counter-probe: a run as slow as the red one was not
  reproduced.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-10-02 20:33:21 +02:00
1 parent e933fad446
commit e066613583
1 file changed
+8 -3
+8 -3
View File
@@ -328,7 +328,11 @@ export async function physics(t) {
const letGo = await evaluate('window.__dragLetGo');
const log = (await json('__gm.world()'))?.log ?? [];
await stop();
const held = dragSamples.filter((s) => s.t < letGo).map((s) => s.y);
const heldSamples = dragSamples.filter((s) => s.t < letGo);
const held = heldSamples.map((s) => s.y);
// How long the hold was watched, not how many frames that took: a busy runner drew 21 frames
// in the second a quiet one draws 50 in, and a count of 30 called that a failure.
const heldFor = held.length > 1 ? heldSamples.at(-1).t - heldSamples[0].t : 0;
const released = dragSamples.filter((s) => s.t >= letGo);
// 200 ms of free fall from rest is about 25 below the hold, a body let go at speed is not.
const falling = released.filter((s) => s.t - letGo <= 200).map((s) => s.y);
@@ -336,7 +340,8 @@ export async function physics(t) {
check(
'a body dragged while playing hangs where the pointer holds it and is let go at rest',
arrived &&
held.length >= 30 &&
held.length >= 5 &&
heldFor >= 800 &&
held.every((y) => Math.abs(y - target) < 1.5) &&
// Let go it only falls: no jump above the hold, no kick up. How far the first frame after
// the release has already fallen follows the frame time, so that is not a bound here.
@@ -347,7 +352,7 @@ export async function physics(t) {
JSON.stringify({
target,
arrived,
held: { frames: held.length, first: held[0], last: held.at(-1) },
held: { frames: held.length, ms: Math.round(heldFor), first: held[0], last: held.at(-1) },
stamped: typeof letGo === 'number',
released: released.slice(0, 3).map((s) => [Math.round(s.t - letGo), s.y]),
fell,