civ/config.js

179 lines
4.2 KiB
JavaScript
Raw Normal View History

2026-05-14 20:15:23 +09:00
const Terrain = Object.freeze({
PLAINS: 0,
FOREST: 1,
MOUNTAIN: 2,
WATER: 3,
DESERT: 4
});
const terrainInfo = [
{ name: "Plains", color: [82, 102, 74], move: 1.0, fertility: 0.55, mineral: 0.05, regen: 0.025 },
{ name: "Forest", color: [58, 91, 68], move: 1.3, fertility: 0.62, mineral: 0.08, regen: 0.038 },
{ name: "Mountains", color: [104, 105, 101], move: 2.6, fertility: 0.18, mineral: 0.78, regen: 0.012 },
{ name: "Water", color: [52, 78, 103], move: 7.0, fertility: 0.04, mineral: 0.02, regen: 0.004 },
{ name: "Desert", color: [139, 123, 86], move: 1.55, fertility: 0.16, mineral: 0.16, regen: 0.014 }
];
const WEEKS_PER_MONTH = 4;
const MONTHS_PER_YEAR = 12;
const WEEKS_PER_YEAR = MONTHS_PER_YEAR * WEEKS_PER_MONTH;
const SimConfig = Object.freeze({
population: Object.freeze({
softCapStart: 0.85,
hardCapScale: 1.35,
carryingCapacityBase: 2.4,
carryingCapacityFertility: 7.8,
carryingCapacityMineral: 1.8,
carryingCapacityFarmland: 5.5,
pressurePenaltyBase: 0.2,
pressureReproductionPenalty: 0.16
}),
city: Object.freeze({
2026-05-16 13:48:08 +09:00
maxCities: 300,
agingStartYears: 180,
agingDecayPerYear: 0.002,
agingOverCapAttrition: 0.035,
2026-05-17 21:08:03 +09:00
agingRestoreMinWear: 0.08,
2026-05-16 13:48:08 +09:00
agingRestoreCostPerWear: 70,
2026-05-17 21:08:03 +09:00
agingRestoreBudgetShare: 0.18
2026-05-14 20:15:23 +09:00
}),
render: Object.freeze({
graphThrottleMs: 1400,
statsThrottleMs: 900,
historyWindowYears: 2000,
historySamplePaddingYears: 240
}),
technology: Object.freeze({
cityDiffusion: 0.0022,
tradeDiffusion: 0.0032,
cityInnovation: 0.00045
}),
polity: Object.freeze({
minimumPerCapitaFood: 0.06,
2026-05-16 13:48:08 +09:00
logisticsDistance: 34,
charismaMin: 0.5,
2026-05-17 21:08:03 +09:00
charismaMax: 1.5,
charismaAverage: 1.0,
leaderTenureMinYears: 22,
leaderTenureMaxYears: 72
}),
campaign: Object.freeze({
checkIntervalYears: 3,
baseChance: 0.18,
minCooldownYears: 12,
maxCooldownYears: 45,
maxActiveCampaigns: 12,
frontierTargetChance: 0.35,
nonStateTargetChance: 0.30,
independentCityTargetChance: 0.20,
polityTargetChance: 0.15,
baseDurationYears: 8,
maxDurationYears: 25,
claimRadius: 8,
maxTargetDistance: 48
2026-05-14 20:15:23 +09:00
}),
2026-09-16 13:51:43 +09:00
nomad: Object.freeze({
enabled: true,
maxBands: 24,
enabledAfterYears: 120,
spawnCheckIntervalYears: 25,
baseSpawnChance: 0.28,
minPopulation: 80,
maxPopulation: 420,
minRadius: 5,
maxRadius: 14,
movementIntervalYears: 2,
maxMoveDistance: 9,
grazingGain: 0.035,
overgrazingDamage: 0.018,
resourceConsumption: 0.012,
herdSoftCapPerPop: 2.4,
herdHardCapPerPop: 4.0,
resourceSoftCapPerPop: 1.2,
resourceHardCapPerPop: 2.5,
grazingDiminishingPower: 1.35,
urbanAbsorptionControl: 0.55,
cityInteractionRadius: 8,
tradeChance: 0.22,
raidChance: 0.14,
invasionChance: 0.025,
confederationPopulation: 900,
confederationPrestige: 1.8,
splitPopulation: 1200,
sedentarizationChance: 0.035,
collapseCohesion: 0.12,
influenceCulturalTrace: 0.006,
influenceMobilePopulationTrace: 0.004,
visualDurationYears: 20
}),
2026-05-14 20:15:23 +09:00
polityAccess: Object.freeze({
enabled: true,
2026-05-17 21:08:03 +09:00
maxSearchDepth: 8,
indirectPenalty: 0.012,
perHopPenalty: 0.006,
noAccessPenalty: 0.045,
lowLoyaltyTransitPenalty: 0.012,
foreignTransitPenalty: 0.008
2026-05-14 20:15:23 +09:00
}),
culture: Object.freeze({
spreadRadius: 3,
cityWeight: 0.035,
routeWeight: 1.35,
minimumInfluence: 0.18
}),
route: Object.freeze({
maxRouteLength: 42,
2026-09-16 13:51:43 +09:00
adaptiveMaxRouteLength: 72,
isolatedCityBootstrap: true,
isolatedRouteSearchLimit: 8,
isolatedRouteRadius: 4,
newRoutePheromoneSeed: 2.5,
newRouteGraceBoost: 18,
isolatedRouteMinStrength: 0.12,
2026-05-14 20:15:23 +09:00
pheromoneDecay: 0.996,
pheromoneDiffusion: 0.045,
maxPheromone: 18,
routePheromoneBuild: 0.18,
routePheromoneMaintain: 0.12,
routeUpkeepPerTile: 0.018,
routeWeakThreshold: 8,
2026-09-16 13:51:43 +09:00
routeUnsupportedDecay: 3,
2026-05-14 20:15:23 +09:00
routeMaintainedBoost: 10
}),
2026-09-16 13:51:43 +09:00
war: Object.freeze({
pressureMemoryDecay: 0.88,
cityDamageMinRate: 0.003,
cityDamageMaxRate: 0.08,
captureLossBase: 0.08,
captureLossMax: 0.32,
exhaustionPopulationLossBase: 0.0007,
exhaustionPopulationLossMax: 0.012,
warZoneTileLossRate: 0.006,
majorSettlementThreshold: 1.25
}),
2026-05-14 20:15:23 +09:00
disaster: Object.freeze({
damageScale: 1.5,
majorLossRate: 0.05,
checkIntervalYears: 8,
baseChance: 0.76,
minRadius: 6,
maxRadius: 34,
rareLargeChance: 0.10,
largeRadiusMin: 28,
largeRadiusMax: 54,
minIntensity: 0.25,
maxIntensity: 0.95,
visualDurationYears: 18,
maxActiveVisuals: 12,
maxHistory: 160
}),
frontierWave: Object.freeze({
enabledAfterYears: 300,
intervalYears: 80,
chance: 0.45,
2026-09-16 13:51:43 +09:00
minPopulation: 60,
maxPopulation: 140,
edgeBand: 4
2026-05-14 20:15:23 +09:00
})
});
function years(value) {
return value * WEEKS_PER_YEAR;
}