Files
deepseek 8fbe70d0b0 Repterra Web — full game: base building, power grid, taming & breeding, aquatic raiders, day/night, save/load
- 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
2026-08-23 07:00:23 +00:00

214 lines
9.5 KiB
JavaScript

/* =========================================================
* 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;
})();