Files
iron-requiem/scripts/generate-tilesets.js
Kay Kayyali 4bef8e66df
Some checks failed
Iron Requiem CI/CD / test (push) Failing after 11s
Iron Requiem CI/CD / deploy (push) Has been skipped
Build & Deploy / build-and-deploy (push) Has been cancelled
Fix Recovery Phase 4: Single bundle script, correct Traefik network
- build.sh: Remove old bundle tag before injecting hashed version
- index.html: Remove duplicate script tag from template
- docker-compose.yml: Fix network name (hermes-net, not litellm_hermes-net)
- Deployment verified: HTTPS 200 via Cloudflare + Traefik
2026-05-24 04:30:06 +00:00

106 lines
4.8 KiB
JavaScript

#!/usr/bin/env node
/**
* Generate tileset assets using Google Imagen 4.0
* Run from iron-requiem root: node scripts/generate-tilesets.js
*/
import { googleImageGeneration } from 'hermes-tools';
import fs from 'fs';
import path from 'path';
const OUTPUT_BASE = './assets/maps';
const TILESETS = {
tundra: {
zone: 'Frozen Tundra',
palette: 'Winter Whites, Steel Blues, Deep Greys',
tiles: [
{ name: 'snow_ground', prompt: '64x64 seamless game tile, snow-covered ground with subtle wind-swept drift patterns, top-down view, gritty pixel art, 10-color bleak winter palette, high contrast for visibility' },
{ name: 'ice_patch', prompt: '64x64 seamless game tile, translucent ice overlay with crystalline cracks over snow, top-down view, gritty pixel art, winter palette with icy blues' },
{ name: 'snowdrift', prompt: '64x64 game asset, medium snowdrift obstacle for tank cover, transparent background, gritty pixel art, winter palette' },
{ name: 'tree_stump', prompt: '64x64 game asset, frozen tree stump small cover obstacle, transparent background, gritty pixel art, dead wood in winter setting' },
{ name: 'ice_formation', prompt: '64x64 game asset, jagged ice formation large cover obstacle, transparent background, gritty pixel art, sharp crystalline structures' }
]
},
industrial: {
zone: 'Soviet Industrial',
palette: 'Concrete Grey, Rust Orange, Oil Black, Steel Blue',
tiles: [
{ name: 'ground_concrete', prompt: '64x64 seamless game tile, cracked concrete ground with oil stains, top-down view, gritty pixel art, 10-color industrial palette' },
{ name: 'rust_patch', prompt: '64x64 seamless game tile, corroded rust patch overlay on concrete, top-down view, gritty pixel art, rust orange and brown tones' },
{ name: 'steel_drum', prompt: '64x64 game asset, steel drum small cover obstacle, transparent background, gritty pixel art, rusty industrial barrel' },
{ name: 'concrete_barrier', prompt: '64x64 game asset, concrete barrier medium cover obstacle (jersey barrier style), transparent background, gritty pixel art' },
{ name: 'crate_stack', prompt: '64x64 game asset, rusty metal crate stack large cover obstacle, transparent background, gritty pixel art, industrial storage crates' }
]
},
city: {
zone: 'European City Ruins',
palette: 'Stone Grey, Brick Red, Mortar White, Soot Black',
tiles: [
{ name: 'cobblestone', prompt: '64x64 seamless game tile, cracked cobblestone street, top-down view, gritty pixel art, 10-color urban decay palette' },
{ name: 'rubble_patch', prompt: '64x64 seamless game tile, debris and broken masonry rubble, top-down view, gritty pixel art, war-torn city ruins' },
{ name: 'arch_fragment', prompt: '64x64 game asset, gothic stone arch fragment small cover obstacle, transparent background, gritty pixel art, medieval architecture ruin' },
{ name: 'wall_section', prompt: '64x64 game asset, collapsed brick wall section medium cover obstacle, transparent background, gritty pixel art, bombed building debris' },
{ name: 'rubble_pile', prompt: '64x64 game asset, large pile of rubble and broken stone, transparent background, gritty pixel art, urban warfare cover' }
]
}
};
async function generateTileset(zoneName, config) {
console.log(`\n=== Generating ${config.zone} tileset ===`);
const zoneDir = path.join(OUTPUT_BASE, zoneName);
if (!fs.existsSync(zoneDir)) {
fs.mkdirSync(zoneDir, { recursive: true });
}
for (const tile of config.tiles) {
const outputPath = path.join(zoneDir, `${tile.name}.png`);
// Skip if already exists
if (fs.existsSync(outputPath)) {
console.log(`${tile.name}.png (exists)`);
continue;
}
console.log(` Generating ${tile.name}...`);
try {
// Use google-image-generation tool
const result = await googleImageGeneration({
prompt: tile.prompt,
aspect_ratio: 'square'
});
// result.image should be URL or path
const imageUrl = result.image;
console.log(` Generated: ${imageUrl}`);
// If it's a local path, copy it
if (imageUrl.startsWith('/')) {
fs.copyFileSync(imageUrl, outputPath);
console.log(` Saved: ${outputPath}`);
} else {
// It's a URL - would need to download
console.log(` URL returned (manual download needed): ${imageUrl}`);
}
} catch (err) {
console.error(` ERROR: ${err.message}`);
}
}
}
async function main() {
console.log('Iron Requiem Tileset Generator');
console.log('Using Google Imagen 4.0 via google-image-generation skill\n');
for (const [zoneName, config] of Object.entries(TILESETS)) {
await generateTileset(zoneName, config);
}
console.log('\n=== Done ===');
console.log(`Assets saved to ${OUTPUT_BASE}/`);
}
main().catch(console.error);