Newer
Older
rpg / v1 / apps / game / tools / checks / postfx.mjs
/**
 * Сценарий postfx — пост-эффекты мира (PostFx: блюр/аберрация/марево).
 * На слух/глаз в headless не проверить силу эффекта — проверяем, что
 * команды моста применяются (pulse/set/clear), и снимаем скриншоты в пике
 * эффекта для визуальной сверки агентом.
 * 1) новая игра: baseline без эффектов;
 * 2) blur: точечный импульс вокруг героя — скриншот в пике;
 * 3) aberration: импульс сдвига каналов — скриншот в пике;
 * 4) shimmer: зона марева у героя — скриншот (держится до clear);
 * 5) clear: после сброса и шага — команда отвечает, сцена жива.
 * Запуск: node tools/agent.mjs run tools/checks/postfx.mjs
 */
import { withChecks } from '../lib.mjs';

export default async function ({ pretty }) {
    return withChecks(
        'postfx',
        async (t) => {
            const { c } = t;
            await c.run('новая игра: baseline без эффектов', async () => {
                await t.boot();
                await t.ctx.agent.screenshot('/tmp/rpg_postfx_baseline.png');
                return null;
            });
            await c.run('blur: точечный импульс вокруг героя', async () => {
                const s = await t.ctx.agent.snapshot();
                const ok = await t.ctx.agent.command('scene:postfx', {
                    effect: 'blur',
                    x: s.hero.tile.x,
                    y: s.hero.tile.y,
                    level: 3,
                    value: 10
                });
                c.expect(ok === true, 'scene:postfx blur не применился', ok);
                await t.ctx.agent.step(12); // пик огибающей (attack 0.05 + hold 0.1)
                await t.ctx.page.screenshot({ path: '/tmp/rpg_postfx_blur.png' });
                return null;
            });
            await c.run('aberration: импульс сдвига каналов', async () => {
                const ok = await t.ctx.agent.command('scene:postfx', {
                    effect: 'aberration',
                    value: 5
                });
                c.expect(ok === true, 'scene:postfx aberration не применился', ok);
                await t.ctx.agent.step(10);
                await t.ctx.page.screenshot({ path: '/tmp/rpg_postfx_aberration.png' });
                return null;
            });
            await c.run('shimmer: зона марева у героя', async () => {
                const s = await t.ctx.agent.snapshot();
                const ok = await t.ctx.agent.command('scene:postfx', {
                    effect: 'shimmer',
                    x: s.hero.tile.x,
                    y: s.hero.tile.y,
                    level: 3,
                    value: 2.5
                });
                c.expect(ok === true, 'scene:postfx shimmer не применился', ok);
                await t.ctx.agent.step(6);
                await t.ctx.page.screenshot({ path: '/tmp/rpg_postfx_shimmer.png' });
                return null;
            });
            await c.run('clear: сброс эффектов, сцена жива', async () => {
                const ok = await t.ctx.agent.command('scene:postfx', { effect: 'clear' });
                c.expect(ok === true, 'scene:postfx clear не сработал', ok);
                await t.ctx.agent.step(30);
                await t.ctx.page.screenshot({ path: '/tmp/rpg_postfx_clear.png' });
                // Сцена отвечает на мост после сброса.
                const s = await t.ctx.agent.snapshot();
                c.expect(s.scene === 'location', 'сцена не жива после clear', s.scene);
                return null;
            });
        },
        { pretty }
    );
}