/* ========================================================= * REPRTERRA WEB — config.js * Balance data: resources, buildings, dinosaurs, waves. * Plain script (no modules) so the game runs from file:// too. * ========================================================= */ 'use strict'; window.RTS = window.RTS || {}; RTS.CONFIG = (function () { const CFG = {}; // ---------- World ---------- CFG.WORLD = { W: 76, H: 76, TILE_W: 64, TILE_H: 32, // iso tile pixel size at zoom 1 DAY_LENGTH: 40, // seconds per day }; // ---------- Resources ---------- // gold, wood, stone, food, energy(cap-based) CFG.START_RES = { easy: { gold: 700, wood: 350, stone: 250, food: 250 }, normal: { gold: 550, wood: 280, stone: 190, food: 180 }, hard: { gold: 450, wood: 230, stone: 150, food: 140 }, }; CFG.COLONIST = { ARRIVE_EVERY: 7, // seconds, if housing available FOOD_USE: 0.045, // food/sec each }; // ---------- Buildings ---------- // kind: 'hq','house','farm','forester','quarry','generator','barracks', // 'watchtower','cannon','wall','gate' // size: footprint in tiles (square) const B = {}; B.hq = { id: 'hq', name: 'Command Center', size: 3, hp: 1600, cost: { gold: 0 }, energyProd: 10, radius: 8, workers: 0, desc: 'The heart of the colony. Protect it at all costs. Provides power radius and shelters new colonists.', }; B.house = { id: 'house', name: 'House', size: 1, hp: 240, cost: { wood: 25, gold: 30 }, energyUse: 1, workers: 0, popCap: 5, goldRate: 0.07, desc: '+5 population capacity, +tax income. Colonists arrive at the Command Center.', }; B.farm = { id: 'farm', name: 'Farm', size: 2, hp: 260, cost: { wood: 55, gold: 35 }, energyUse: 3, workers: 5, foodRate: 1.15, desc: 'Produces food. Your colonists eat every day — keep them fed.', }; B.forester = { id: 'forester', name: "Forester's Hut", size: 2, hp: 240, cost: { wood: 45, gold: 20 }, energyUse: 4, workers: 6, woodRate: 0.52, range: 4.5, needRes: 16, desc: 'Harvests nearby forest. Place next to trees; the woods slowly run out.', }; B.quarry = { id: 'quarry', name: 'Quarry', size: 2, hp: 300, cost: { wood: 60, gold: 50 }, energyUse: 5, workers: 7, stoneRate: 0.44, range: 4.5, needRes: 10, desc: 'Cuts stone from rock outcrops. Needs rocks within its work area.', }; B.generator = { id: 'generator', name: 'Generator', size: 1, hp: 260, cost: { wood: 45, gold: 25 }, energyProd: 10, radius: 6.5, workers: 0, desc: '+10 energy and extends the power grid — buildings must touch your grid. Overuse the grid and your newest buildings go dark!', }; B.barracks = { id: 'barracks', name: 'Barracks', size: 2, hp: 380, cost: { wood: 75, stone: 60, gold: 50 }, energyUse: 6, workers: 4, desc: 'Trains Rangers. Set a rally point; they hold position and engage anything hostile.', }; B.primalpen = { id: 'primalpen', name: 'Primal Pen', size: 2, hp: 340, cost: { wood: 80, stone: 40, gold: 80 }, energyUse: 6, workers: 3, desc: 'Trains Tamers and shelters tamed dinos (+2 tame slots). Slowly heals your pets nearby.', }; B.watchtower = { id: 'watchtower', name: 'Watchtower', size: 1, hp: 300, cost: { wood: 35, stone: 45, gold: 25 }, energyUse: 4, workers: 0, range: 6.5, dmg: 13, rof: 0.9, air: true, desc: 'Fast rifle fire. Hits GROUND and AIR targets. Pteranodons ignore walls — you need these.', }; B.cannon = { id: 'cannon', name: 'Cannon Tower', size: 1, hp: 420, cost: { wood: 60, stone: 110, gold: 60 }, energyUse: 8, workers: 0, range: 7.5, dmg: 48, rof: 2.6, aoe: 1.35, air: false, desc: 'Devastating explosive shells with splash. GROUND ONLY — cannot hit flying dinos.', }; B.wall = { id: 'wall', name: 'Wall', size: 1, hp: 380, cost: { stone: 8 }, energyUse: 0, workers: 0, desc: 'Stone wall. Blocks ground dinos. They WILL smash it — flying dinos fly over.', }; B.gate = { id: 'gate', name: 'Gate', size: 1, hp: 330, cost: { stone: 20 }, energyUse: 0, workers: 0, desc: 'Lets your troops through, blocks dinos (until they break it).', }; CFG.BUILDINGS = B; // Build order in UI palette (grouped) CFG.PALETTE = [ ['house', 'farm', 'forester', 'quarry'], ['generator', 'wall', 'gate'], ['watchtower', 'cannon', 'barracks', 'primalpen'], ]; // ---------- Taming ---------- CFG.TAMING = { hpThreshold: 0.32, // dino must be below this HP fraction channelTime: 2.6, // seconds adjacent to capture range: 1.7, // capture reach from tamer baseLimit: 2, // tames allowed with no pen perPen: 2, // extra slots per Primal Pen }; // ---------- Breeding ---------- CFG.BREED = { foodPerEgg: 60, // food cost to incubate an egg eggTime: 40, // seconds to hatch growTime: 50, // seconds from hatchling to adult size maxPerPen: 2, // simultaneous eggs per pen parentRadius: 5, // tamed parents must linger near the pen minParents: 2, // need a pair before eggs appear }; // ---------- Research (at Command Center) ---------- CFG.UPGRADES = [ { id: 'weapon', name: 'High-Caliber Rounds', tiers: 3, base: { gold: 220, stone: 90 }, mult: 1.7, desc: '+25% Ranger & tower damage per tier.' }, { id: 'armor', name: 'Kevlar Vests', tiers: 3, base: { gold: 180, wood: 80 }, mult: 1.7, desc: '+25% Ranger health per tier (new recruits).' }, { id: 'range', name: 'Scoped Rifles', tiers: 2, base: { gold: 260, stone: 120 }, mult: 1.8, desc: '+12% Ranger & Watchtower range per tier.' }, ]; // ---------- Units (human) ---------- CFG.UNITS = { colonist: { id: 'colonist', name: 'Colonist', hp: 40, speed: 1.5, dmg: 0 }, ranger: { id: 'ranger', name: 'Ranger', hp: 135, speed: 1.7, dmg: 11, rof: 0.8, range: 4.2, air: true, cost: { gold: 45, food: 15 }, trainTime: 12, desc: 'Rifle infantry. Engages ground AND air targets.', }, tamer: { id: 'tamer', name: 'Tamer', hp: 95, speed: 1.8, dmg: 7, rof: 1.1, range: 3.4, air: false, cost: { gold: 90, food: 20 }, trainTime: 16, desc: 'Tranq-dart support who slips a collar on weakened dinos (<32% HP). Right-click a dino to prioritize the capture.', }, }; CFG.TRAIN_AT = { ranger: 'barracks', tamer: 'primalpen' }; // ---------- Dinosaurs ---------- // flying:true -> ignores walls & terrain, beelines targets const D = {}; D.compy = { id: 'compy', name: 'Compsognathus', hp: 24, dmg: 4, rof: 0.7, speed: 2.3, r: 0.32, bounty: 1, flying: false, scale: 0.55, color: '#7da05a' }; D.raptor = { id: 'raptor', name: 'Velociraptor', hp: 88, dmg: 11, rof: 0.8, speed: 2.0, r: 0.42, bounty: 3, flying: false, scale: 0.9, color: '#a5713f' }; D.dilo = { id: 'dilo', name: 'Dilophosaurus', hp: 115, dmg: 9, rof: 1.4, speed: 1.55, r: 0.46, bounty: 5, flying: false, ranged: 3.5, scale: 1.0, color: '#5e8f5a' }; D.trike = { id: 'trike', name: 'Triceratops', hp: 560, dmg: 26, rof: 1.1, speed: 0.95, r: 0.75, bounty: 10, flying: false, bldMult: 2.5, scale: 1.5, color: '#8d7f66' }; D.ptera = { id: 'ptera', name: 'Pteranodon', hp: 68, dmg: 8, rof: 0.7, speed: 2.6, r: 0.45, bounty: 4, flying: true, scale: 1.0, color: '#9c86b8' }; D.sucho = { id: 'sucho', name: 'Suchomimus', hp: 300, dmg: 22, rof: 1.05, speed: 1.15, r: 0.7, bounty: 14, flying: false, amphibious: true, bldMult: 1.5, scale: 1.45, color: '#4f7d6b' }; D.rex = { id: 'rex', name: 'Tyrannosaurus Rex', hp: 3400, dmg: 72, rof: 1.3, speed: 1.05, r: 1.05, bounty: 45, flying: false, bldMult: 2.0, scale: 2.2, color: '#6f4f34' }; CFG.DINOS = D; CFG.UNTAMEABLE = { rex: true }; // ---------- Attack waves (per difficulty): day -> composition ---------- // sucho = aquatic raiders, they emerge from the lakes (see spawnWave) CFG.WAVES = { easy: [ { day: 3, comp: { compy: 10 } }, { day: 5, comp: { compy: 12, raptor: 4 } }, { day: 7, comp: { raptor: 6, ptera: 4 } }, { day: 9, comp: { trike: 2, raptor: 6, compy: 10, sucho: 1 } }, { day: 11, comp: { dilo: 5, ptera: 6, raptor: 5, sucho: 1 } }, { day: 13, comp: { rex: 1, raptor: 8, ptera: 5, sucho: 2 } }, { day: 17, final: true, comp: { rex: 2, trike: 3, dilo: 7, raptor: 12, ptera: 10, compy: 20, sucho: 3 } }, ], normal: [ { day: 2, comp: { compy: 14 } }, { day: 4, comp: { compy: 16, raptor: 6 } }, { day: 6, comp: { raptor: 8, ptera: 6 } }, { day: 8, comp: { trike: 2, raptor: 8, compy: 12, sucho: 1 } }, { day: 10, comp: { dilo: 6, ptera: 8, raptor: 6, sucho: 2 } }, { day: 12, comp: { rex: 1, raptor: 10, ptera: 6, sucho: 2 } }, { day: 15, final: true, comp: { rex: 2, trike: 3, dilo: 8, raptor: 16, ptera: 14, compy: 24, sucho: 4 } }, ], hard: [ { day: 2, comp: { compy: 20, raptor: 3 } }, { day: 4, comp: { compy: 22, raptor: 9 } }, { day: 6, comp: { raptor: 12, ptera: 9, dilo: 4, sucho: 1 } }, { day: 8, comp: { trike: 3, raptor: 12, compy: 16, sucho: 2 } }, { day: 10, comp: { dilo: 9, ptera: 12, raptor: 9, sucho: 3 } }, { day: 12, comp: { rex: 2, raptor: 14, ptera: 9, sucho: 3 } }, { day: 13, final: true, comp: { rex: 3, trike: 4, dilo: 10, raptor: 22, ptera: 18, compy: 30, sucho: 5 } }, ], }; CFG.WARN_TIME = 45; // seconds of warning before a wave CFG.ROAMER_PACKS = { easy: 8, normal: 10, hard: 12 }; return CFG; })();