- 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
214 lines
9.5 KiB
JavaScript
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;
|
|
})();
|