/**
* Сценарий shadows — тени мира (блобы актёров + направленные тени tall-объектов).
* Математика sunShadow чистая и покрыта юнит-тестами; здесь проверяем, что
* тени в игре ползут за солнцем и гаснут ночью — визуально, по скриншотам
* в ключевые часы (утро/полдень/вечер/ночь).
* 1) новая игра (8:00): baseline — утренние тени влево;
* 2) setTime 13: полдень — короткие тени под объектами;
* 3) setTime 19: вечер — тени вправо;
* 4) setTime 23: ночь — теней нет;
* 5) setTime 8 обратно + шаг: сцена жива, время применилось.
* Запуск: node tools/agent.mjs run tools/checks/shadows.mjs
*/
import { withChecks } from '../lib.mjs';
export default async function ({ pretty }) {
return withChecks(
'shadows',
async (t) => {
const { c } = t;
const setTime = async (hours) => {
const ok = await t.ctx.agent.command('scene:setTime', { hours });
c.expect(ok === true, `scene:setTime ${hours}h не применился`, ok);
return ok;
};
await c.run('новая игра 8:00: baseline, утренние тени влево', async () => {
await t.boot();
// пережидаем fade-переход меню→локация (скриншот в fade тёмен)
await t.ctx.agent.waitFor('!s.transitioning', { timeoutTicks: 600 });
// ручные шаги без рендера не обновляют канвас: рисуем кадры явно
await t.ctx.agent.step(10, { render: true });
const s = await t.ctx.agent.snapshot();
c.expect(s.scene === 'location', 'не в локации после boot', s.scene);
await t.ctx.page.screenshot({ path: '/tmp/rpg_shadow_morning.png' });
return null;
});
await c.run('13:00: полдень, короткие тени', async () => {
await setTime(13);
await t.ctx.agent.step(2);
await t.ctx.page.screenshot({ path: '/tmp/rpg_shadow_noon.png' });
return null;
});
await c.run('19:00: вечер, тени вправо', async () => {
await setTime(19);
await t.ctx.agent.step(2);
await t.ctx.page.screenshot({ path: '/tmp/rpg_shadow_evening.png' });
return null;
});
await c.run('23:00: ночь, теней нет', async () => {
await setTime(23);
await t.ctx.agent.step(2);
await t.ctx.page.screenshot({ path: '/tmp/rpg_shadow_night.png' });
return null;
});
await c.run('возврат к 8:00: время применилось, сцена жива', async () => {
await setTime(8);
await t.ctx.agent.step(5);
const s = await t.ctx.agent.snapshot();
c.expect(s.scene === 'location', 'сцена не жива после setTime', s.scene);
return null;
});
},
{ pretty }
);
}