mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
Fix population aggregation system to eliminate double-counting
- Fixed core issue where cells.pop and burg.population were both being counted - Changed aggregation logic across all modules to use either burg OR cell population, never both - If cell has burg: count only burg population (represents all people in that area) - If cell has no burg: count only cells.pop (represents scattered population) Files modified: - modules/burgs-and-states.js: Fixed state population aggregation - modules/ui/provinces-editor.js: Fixed province population aggregation - modules/dynamic/editors/cultures-editor.js: Fixed culture population aggregation - modules/dynamic/editors/religions-editor.js: Fixed religion population aggregation - modules/ui/biomes-editor.js: Fixed biome population aggregation - modules/ui/zones-editor.js: Fixed zone population calculations (2 locations) - modules/military-generator.js: Redesigned military generation to use only burg populations Military system changes: - Removed rural military generation (all forces now come from settlements) - Only burgs with 500+ people can maintain military forces - Military strength based on actual burg population (2.5% mobilization rate) Result: Population totals now consistent across all CSV exports (~2M total vs previous 40x discrepancy)
This commit is contained in:
parent
334ef2b58b
commit
e669549390
18 changed files with 2960 additions and 297 deletions
|
|
@ -70,8 +70,13 @@ function editBiomes() {
|
|||
const b = cells.biome[i];
|
||||
biomesData.cells[b] += 1;
|
||||
biomesData.area[b] += cells.area[i];
|
||||
biomesData.rural[b] += cells.pop[i];
|
||||
if (cells.burg[i]) biomesData.urban[b] += pack.burgs[cells.burg[i]].population;
|
||||
if (cells.burg[i]) {
|
||||
// Burg represents ALL population for this cell (stored in thousands)
|
||||
biomesData.urban[b] += pack.burgs[cells.burg[i]].population;
|
||||
} else {
|
||||
// Only count cells.pop for unsettled areas (no burg present)
|
||||
biomesData.rural[b] += cells.pop[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ function overviewMilitary() {
|
|||
const states = pack.states.filter(s => s.i && !s.removed);
|
||||
|
||||
for (const s of states) {
|
||||
const population = rn((s.rural + s.urban * urbanization) * populationRate);
|
||||
const population = rn((s.rural * populationRate) + (s.urban * 1000 * urbanization));
|
||||
const getForces = u => s.military.reduce((s, r) => s + (r.u[u.name] || 0), 0);
|
||||
const total = options.military.reduce((s, u) => s + getForces(u) * u.crew, 0);
|
||||
const rate = (total / population) * 100;
|
||||
|
|
@ -146,7 +146,7 @@ function overviewMilitary() {
|
|||
u => (line.dataset[u.name] = line.querySelector(`div[data-type='${u.name}']`).innerHTML = getForces(u))
|
||||
);
|
||||
|
||||
const population = rn((s.rural + s.urban * urbanization) * populationRate);
|
||||
const population = rn((s.rural * populationRate) + (s.urban * 1000 * urbanization));
|
||||
const total = (line.dataset.total = options.military.reduce((s, u) => s + getForces(u) * u.crew, 0));
|
||||
const rate = (line.dataset.rate = (total / population) * 100);
|
||||
line.querySelector("div[data-type='total']").innerHTML = si(total);
|
||||
|
|
|
|||
|
|
@ -87,10 +87,14 @@ function editProvinces() {
|
|||
if (!p) continue;
|
||||
|
||||
provinces[p].area += cells.area[i];
|
||||
provinces[p].rural += cells.pop[i];
|
||||
if (!cells.burg[i]) continue;
|
||||
provinces[p].urban += burgs[cells.burg[i]].population;
|
||||
provinces[p].burgs.push(cells.burg[i]);
|
||||
if (cells.burg[i]) {
|
||||
// Burg represents ALL population for this cell (stored in thousands)
|
||||
provinces[p].urban += burgs[cells.burg[i]].population;
|
||||
provinces[p].burgs.push(cells.burg[i]);
|
||||
} else {
|
||||
// Only count cells.pop for unsettled areas (no burg present)
|
||||
provinces[p].rural += cells.pop[i];
|
||||
}
|
||||
}
|
||||
|
||||
provinces.forEach(p => {
|
||||
|
|
@ -1092,9 +1096,13 @@ function editProvinces() {
|
|||
data += el.dataset.color + ",";
|
||||
data += el.dataset.capital + ",";
|
||||
data += el.dataset.area + ",";
|
||||
data += el.dataset.population + ",";
|
||||
data += Math.round(provincePack.rural * populationRate) + ",";
|
||||
data += Math.round(provincePack.urban * populationRate * urbanization) + ",";
|
||||
// Rural: convert abstract points to people, Urban: already in thousands so convert to people
|
||||
const ruralPop = Math.round(provincePack.rural * populationRate);
|
||||
const urbanPop = Math.round(provincePack.urban * 1000 * urbanization);
|
||||
const totalPop = ruralPop + urbanPop;
|
||||
data += totalPop + ",";
|
||||
data += ruralPop + ",";
|
||||
data += urbanPop + ",";
|
||||
data += el.dataset.burgs + "\n";
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -79,9 +79,17 @@ function editZones() {
|
|||
|
||||
const lines = filteredZones.map(({i, name, type, cells, color, hidden}) => {
|
||||
const area = getArea(d3.sum(cells.map(i => pack.cells.area[i])));
|
||||
const rural = d3.sum(cells.map(i => pack.cells.pop[i])) * populationRate;
|
||||
const urban =
|
||||
d3.sum(cells.map(i => pack.cells.burg[i]).map(b => pack.burgs[b].population)) * populationRate * urbanization;
|
||||
// Calculate population: burg population for settled cells, cells.pop for unsettled
|
||||
let rural = 0, urban = 0;
|
||||
cells.forEach(i => {
|
||||
if (pack.cells.burg[i]) {
|
||||
// Burg represents ALL population for this cell
|
||||
urban += pack.burgs[pack.cells.burg[i]].population * 1000 * urbanization;
|
||||
} else {
|
||||
// Only count cells.pop for unsettled areas
|
||||
rural += pack.cells.pop[i] * populationRate;
|
||||
}
|
||||
});
|
||||
const population = rn(rural + urban);
|
||||
const populationTip = `Total population: ${si(population)}; Rural population: ${si(
|
||||
rural
|
||||
|
|
@ -412,10 +420,19 @@ function editZones() {
|
|||
if (!landCells.length) return tip("Zone does not have any land cells, cannot change population", false, "error");
|
||||
|
||||
const burgs = pack.burgs.filter(b => !b.removed && landCells.includes(b.cell));
|
||||
const rural = rn(d3.sum(landCells.map(i => pack.cells.pop[i])) * populationRate);
|
||||
const urban = rn(
|
||||
d3.sum(landCells.map(i => pack.cells.burg[i]).map(b => pack.burgs[b].population)) * populationRate * urbanization
|
||||
);
|
||||
// Calculate population: burg population for settled cells, cells.pop for unsettled
|
||||
let rural = 0, urban = 0;
|
||||
landCells.forEach(i => {
|
||||
if (pack.cells.burg[i]) {
|
||||
// Burg represents ALL population for this cell
|
||||
urban += pack.burgs[pack.cells.burg[i]].population * 1000 * urbanization;
|
||||
} else {
|
||||
// Only count cells.pop for unsettled areas
|
||||
rural += pack.cells.pop[i] * populationRate;
|
||||
}
|
||||
});
|
||||
rural = rn(rural);
|
||||
urban = rn(urban);
|
||||
const total = rural + urban;
|
||||
const l = n => Number(n).toLocaleString();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue