- Isometric canvas RTS vs dinosaur waves (fan demake of Repterra) - Economy: houses/taxes, farms, foresters, quarries; colonist staffing - Power grid: generators extend build range; brownout + recovery - Defense: walls/gates, watchtowers (AA), cannon towers (ground-only) - Taming: Primal Pen + Tamers collar weakened dinos; pets obey commands - Breeding: tamed pairs incubate eggs at the pen; hatchlings grow up - 7 dino species incl. flying Pteranodons and lake-raiding Suchomimus - Telegraphed waves with direction arrows; day-15 final horde; 3 difficulties - Day/night cycle, fog of war, minimap, synth audio, 1x-3x speeds - Save/Load/Continue + dawn autosave (full JSON state snapshots) - Tests: 80-assertion headless suite, browser boot + E2E, balance harness
80 lines
3.2 KiB
JavaScript
80 lines
3.2 KiB
JavaScript
/* Capture polished screenshots: base building + a mid-game battle. */
|
|
'use strict';
|
|
const { chromium } = require('/tmp/node_modules/playwright-core');
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({
|
|
executablePath: '/root/.cache/ms-playwright/chromium_headless_shell-1148/chrome-linux/headless_shell',
|
|
args: ['--no-sandbox', '--disable-gpu'],
|
|
});
|
|
const page = await browser.newPage({ viewport: { width: 1440, height: 860 } });
|
|
page.on('pageerror', e => console.error('PAGEERROR:', e.message));
|
|
|
|
await page.goto('http://127.0.0.1:8933/', { waitUntil: 'load' });
|
|
await page.waitForTimeout(600);
|
|
await page.screenshot({ path: '/root/dinorts/shots/menu.png' });
|
|
|
|
await page.click('[data-diff="normal"]');
|
|
await page.waitForTimeout(1500);
|
|
|
|
// build a believable starter base near the HQ via the sim API
|
|
await page.evaluate(() => {
|
|
const s = RTS.sim.state();
|
|
s.res.gold += 2000; s.res.wood += 2000; s.res.stone += 2000;
|
|
const hq = RTS.sim.hq();
|
|
const put = (defId, r0, r1, tries) => {
|
|
const rng = RTS.util.makeRng(defId.length * 77 + r0);
|
|
for (let i = 0; i < (tries || 400); i++) {
|
|
const a = rng() * Math.PI * 2, r = r0 + rng() * (r1 - r0);
|
|
const x = Math.round(hq.x + Math.cos(a) * r), y = Math.round(hq.y + Math.sin(a) * r);
|
|
if (RTS.sim.canPlace(defId, x, y).ok && RTS.sim.place(defId, x, y).ok) return true;
|
|
}
|
|
return false;
|
|
};
|
|
put('house', 2.2, 4); put('house', 2.2, 4); put('house', 3, 5);
|
|
put('generator', 5, 7);
|
|
put('farm', 2.5, 5); put('forester', 4, 9, 900); put('quarry', 4, 9, 900);
|
|
// defensive ring
|
|
for (let k = 0; k < 8; k++) {
|
|
const a = (k / 8) * Math.PI * 2;
|
|
const x = Math.round(hq.x + Math.cos(a) * 6.5), y = Math.round(hq.y + Math.sin(a) * 6.5);
|
|
RTS.sim.place(k % 2 ? 'watchtower' : 'wall', x, y);
|
|
}
|
|
// wall arc facing south-east
|
|
for (let d = -3; d <= 3; d++) RTS.sim.place('wall', hq.x + d, hq.y + 5);
|
|
RTS.sim.place('gate', hq.x, hq.y + 5);
|
|
put('barracks', 3, 6);
|
|
return true;
|
|
});
|
|
await page.waitForTimeout(2500);
|
|
await page.screenshot({ path: '/root/dinorts/shots/base.png' });
|
|
console.log('base shot saved');
|
|
|
|
// jump to just before wave day and let the horde arrive at the walls
|
|
await page.evaluate(() => {
|
|
const s = RTS.sim.state();
|
|
s.day = 5; s.dayT = 30;
|
|
s.waves.forEach(w => { if (!w.final && w.day <= 6 && !w.spawned) { /* leave schedule intact */ } });
|
|
});
|
|
await page.click('#topbtns .tbtn:nth-child(4)'); // 3x
|
|
let shots = 0;
|
|
let lastKills = -1;
|
|
for (let i = 0; i < 45; i++) {
|
|
await page.waitForTimeout(1000);
|
|
const stt = await page.evaluate(() => {
|
|
const s = RTS.sim.state();
|
|
return { kills: s.stats.kills, dinos: s.dinos.length, day: s.day };
|
|
});
|
|
// snap when combat is hot
|
|
if (stt.dinos > 10 && stt.dinos < 90 && shots < 2 && stt.kills !== lastKills) {
|
|
lastKills = stt.kills;
|
|
shots++;
|
|
await page.screenshot({ path: '/root/dinorts/shots/battle' + shots + '.png' });
|
|
console.log('battle shot', shots, JSON.stringify(stt));
|
|
}
|
|
if (stt.day >= 8 || shots >= 2) break;
|
|
}
|
|
await browser.close();
|
|
console.log('done');
|
|
})().catch(e => { console.error('CRASH:', e); process.exit(1); });
|