Make the actor smoke reach every sub pixel edge position again
Since #225 the game view opens at 100 % instead of fit. The actor walks 150 px/s, so its top edge only lands on .0 or .5 of a pixel. The check for the frame top edge needs 0.6 to 0.9 and gave up in 6 of 7 CI runs. The picture itself was fine: the pixels above and at the edge were the same in every red run. - While nudging the actor into place the smoke slows time to 0.08 with __gm.setTimeScale. The actor then moves 0.2 px per frame and can reach any position inside a pixel. - Time scale goes back to 1 before the edge is measured. Tests: - Old smoke on the same seeded project fails locally like CI (fraction 0.08). - New smoke passed three times in a row (fraction 0.80, 21 checks). - The actor project file was saved first and restored byte exact. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f4cc681df4
commit
8f29b88cc9
1 file changed
+19
-1
+19
-1
@@ -38,7 +38,21 @@ const walkOf = (e) =>
|
|||||||
const rowOfFrame = (texture) => Number(String(texture).split('-')[1]);
|
const rowOfFrame = (texture) => Number(String(texture).split('-')[1]);
|
||||||
|
|
||||||
await runChecks({ projectId, baseUrl, port: 9341, shotPrefix: 'gm-actor' }, async (t) => {
|
await runChecks({ projectId, baseUrl, port: 9341, shotPrefix: 'gm-actor' }, async (t) => {
|
||||||
const { check, sleep, json, shot, entity, play, stop, navigate, exceptions, holdKey, keyDown, keyUp } = t;
|
const {
|
||||||
|
check,
|
||||||
|
sleep,
|
||||||
|
json,
|
||||||
|
evaluate,
|
||||||
|
shot,
|
||||||
|
entity,
|
||||||
|
play,
|
||||||
|
stop,
|
||||||
|
navigate,
|
||||||
|
exceptions,
|
||||||
|
holdKey,
|
||||||
|
keyDown,
|
||||||
|
keyUp,
|
||||||
|
} = t;
|
||||||
|
|
||||||
await navigate();
|
await navigate();
|
||||||
|
|
||||||
@@ -257,10 +271,13 @@ await runChecks({ projectId, baseUrl, port: 9341, shotPrefix: 'gm-actor' }, asyn
|
|||||||
// 12. A frame's top edge shows nothing of the cell above it, wherever the edge lands inside a
|
// 12. A frame's top edge shows nothing of the cell above it, wherever the edge lands inside a
|
||||||
// pixel. Drawn from the sheet, a partly covered edge pixel read the boots of the cell above –
|
// pixel. Drawn from the sheet, a partly covered edge pixel read the boots of the cell above –
|
||||||
// the hairline over the head. Nudged upwards until the edge sits in the lower half of a pixel.
|
// the hairline over the head. Nudged upwards until the edge sits in the lower half of a pixel.
|
||||||
|
// At the game view's 100% a frame at full speed moves 2.5 px, so the edge only ever lands on
|
||||||
|
// .0 or .5. Slowed to 0.2 px a frame, it walks through every part of a pixel.
|
||||||
const topEdge = async () => {
|
const topEdge = async () => {
|
||||||
const r = await json(`__gm.gameRect('oplayer')`);
|
const r = await json(`__gm.gameRect('oplayer')`);
|
||||||
return { cx: Math.round(r.x), y0: r.y - r.h / 2 };
|
return { cx: Math.round(r.x), y0: r.y - r.h / 2 };
|
||||||
};
|
};
|
||||||
|
await evaluate('__gm.setTimeScale(0.08)');
|
||||||
let edge;
|
let edge;
|
||||||
let nudges = 0;
|
let nudges = 0;
|
||||||
do {
|
do {
|
||||||
@@ -269,6 +286,7 @@ await runChecks({ projectId, baseUrl, port: 9341, shotPrefix: 'gm-actor' }, asyn
|
|||||||
edge = await topEdge();
|
edge = await topEdge();
|
||||||
nudges += 1;
|
nudges += 1;
|
||||||
} while (nudges < 40 && !(edge.y0 % 1 > 0.6 && edge.y0 % 1 < 0.9));
|
} while (nudges < 40 && !(edge.y0 % 1 > 0.6 && edge.y0 % 1 < 0.9));
|
||||||
|
await evaluate('__gm.setTimeScale(1)');
|
||||||
const facingUp = await entity('oplayer');
|
const facingUp = await entity('oplayer');
|
||||||
const rowAt = async (y) =>
|
const rowAt = async (y) =>
|
||||||
json(`[-8,-6,-4,-2,0,2,4,6,8].map((dx) => __gm.pixelAt(${edge.cx} + dx, ${y}))`).then((p) => p.join(' '));
|
json(`[-8,-6,-4,-2,0,2,4,6,8].map((dx) => __gm.pixelAt(${edge.cx} + dx, ${y}))`).then((p) => p.join(' '));
|
||||||
|
|||||||
Reference in new issue
Block a user