Fantasy-Map-Generator/population_alteration.md
barrulus 334ef2b58b Add comprehensive population scaling documentation
This commit introduces detailed documentation for modifying the Fantasy Map Generator's population system to create more realistic settlement sizes suitable for medieval fantasy settings.

Key features of the documentation:
- Complete analysis of current population calculation system in burgs-and-states.js
- Detailed code modifications to reduce city populations from ~250k to ~30k
- Hierarchical scaling that maintains realistic population gradients
- Military impact analysis showing proportional army size reductions
- Step-by-step implementation guide with exact line numbers
- Testing procedures and validation methods
- Troubleshooting section for common issues
- Rollback instructions for safe implementation

The proposed changes will create settlement populations of:
- Capitals: 25-35k (down from 200-300k)
- Large ports: 20-30k (down from 150-250k)
- Regional centers: 10-20k (down from 100-150k)
- Towns: 2-8k (down from 20-50k)
- Villages: 0.5-3k (down from 1-5k)

Military forces will scale proportionally, creating more historically accurate medieval army sizes where capitals field 60-120 troops instead of 500-1000.

The documentation preserves all existing functionality while providing a complete reference for population system modifications.
2025-08-13 08:05:19 +01:00

9 KiB
Raw Blame History

Population Alteration Guide

Overview

This guide explains how to modify the Fantasy Map Generator to reduce settlement population sizes from their default large values (cities ~250k) to more realistic medieval fantasy scales (cities ~30k, towns 1-5k, villages ≤1k).

Problem Statement

  • Default cities are too large (~250k population)
  • Towns are oversized for medieval fantasy settings
  • Military forces are proportionally too large
  • Need more realistic population distribution

Goals

  • Cities: ~25-35k population
  • Large ports: ~20-30k population
  • Regional centers: ~10-20k population
  • Towns: ~2-8k population
  • Villages: ~0.5-3k population

Current Population System

The population system operates through hierarchical settlement placement and calculation in modules/burgs-and-states.js:

Settlement Hierarchy

  1. Primary Centers: Capitals and large ports (placed first)
  2. Regional Centers: Intermediate hubs between primary centers
  3. Towns: Secondary settlements with hierarchical scoring
  4. Villages: Smallest settlements

Population Formula

Base population calculation (line 394):

let basePopulation = Math.max(cells.s[i] / 8 + b.i / 1000 + (i % 100) / 1000, 0.1);

Hierarchical multipliers (lines 397-410):

  • Capitals: ×1.8
  • Large ports: ×1.6
  • Regional centers: ×1.3
  • Regular settlements: Variable based on hierarchical score

Additional modifiers:

  • Port bonus: ×1.2 (line 416)
  • Random variation: Gaussian distribution (1.8, 2.5, 0.7, 15, 2.5) (line 424)

Proposed Changes

1. Base Population Reduction (Line 394)

Current:

let basePopulation = Math.max(cells.s[i] / 8 + b.i / 1000 + (i % 100) / 1000, 0.1);

Change to:

let basePopulation = Math.max(cells.s[i] / 80 + b.i / 10000 + (i % 1000) / 10000, 0.01);

Explanation:

  • /8/80: Reduces cell score impact by 10x
  • /1000/10000: Reduces burg index impact by 10x
  • (i % 100)(i % 1000): Increases modulo range for more variation
  • /1000/10000: Reduces modulo impact by 10x
  • 0.10.01: Reduces minimum population by 10x

2. Hierarchical Multiplier Reduction (Lines 397-410)

Current:

if (b.capital) {
  basePopulation *= 1.8;
} else if (b.isLargePort) {
  basePopulation *= 1.6;
} else if (b.isRegionalCenter) {
  basePopulation *= 1.3;
}

Change to:

if (b.capital) {
  basePopulation *= 1.4;
} else if (b.isLargePort) {
  basePopulation *= 1.3;
} else if (b.isRegionalCenter) {
  basePopulation *= 1.2;
}

3. Hierarchical Score Adjustment (Lines 407-408)

Current:

const hierarchicalMultiplier = 0.7 + (b.hierarchicalScore / maxHierarchicalScore) * 0.6;

Change to:

const hierarchicalMultiplier = 0.8 + (b.hierarchicalScore / maxHierarchicalScore) * 0.4;

4. Port Bonus Reduction (Line 416)

Current:

b.population = b.population * 1.2;

Change to:

b.population = b.population * 1.05;

5. Random Variation Reduction (Line 424)

Current:

b.population = rn(b.population * gauss(1.8, 2.5, 0.7, 15, 2.5), 3);

Change to:

b.population = rn(b.population * gauss(1.2, 1.5, 0.5, 5, 1.5), 3);

Explanation:

  • Mean: 1.8 → 1.2 (lower average multiplier)
  • Standard deviation: 2.5 → 1.5 (less variation)
  • Min: 0.7 → 0.5 (lower minimum)
  • Max: 15 → 5 (much lower maximum)
  • Sigma: 2.5 → 1.5 (tighter distribution)

Complete Code Replacement

Replace lines 394-424 in modules/burgs-and-states.js with:

// Calculate base population (reduced scale)
let basePopulation = Math.max(cells.s[i] / 80 + b.i / 10000 + (i % 1000) / 10000, 0.01);

// Apply reduced hierarchical multipliers
if (b.capital) {
  basePopulation *= 1.4; // Capitals ~30k
} else if (b.isLargePort) {
  basePopulation *= 1.3; // Large ports ~20-25k
} else if (b.isRegionalCenter) {
  basePopulation *= 1.2; // Regional centers ~10-15k
} else if (b.hierarchicalScore) {
  const maxHierarchicalScore = Math.max(...pack.burgs.filter(burg => burg.hierarchicalScore).map(burg => burg.hierarchicalScore));
  if (maxHierarchicalScore > 0) {
    const hierarchicalMultiplier = 0.8 + (b.hierarchicalScore / maxHierarchicalScore) * 0.4;
    basePopulation *= hierarchicalMultiplier;
  }
}

b.population = rn(basePopulation, 3);

if (b.port && !b.isLargePort) {
  b.population = b.population * 1.05; // Minimal port bonus
}

// Reduced random variation
b.population = rn(b.population * gauss(1.2, 1.5, 0.5, 5, 1.5), 3);

Expected Results

Population Ranges

Settlement Type Current Range New Range Reduction Factor
Capitals 200k-300k+ 25k-35k ~8-10x
Large Ports 150k-250k 20k-30k ~7-8x
Regional Centers 100k-150k 10k-20k ~8-10x
Major Towns 20k-50k 3k-8k ~6-8x
Towns 5k-20k 1k-5k ~5-6x
Villages 1k-5k 0.5k-3k ~2-3x

Population Distribution

  • More realistic medieval fantasy scale
  • Maintains hierarchical relationships
  • Preserves population density gradients around major centers
  • Keeps relative differences between settlement types

Military Impact

Military forces scale directly with population, so expect proportional reductions:

Army Size Changes

Settlement Type Current Military New Military
Capitals 500-1000 troops 60-120 troops
Large Ports 300-500 troops 40-70 troops
Regional Centers 200-300 troops 25-40 troops
Major Towns 40-100 troops 6-15 troops
Towns 10-40 troops 2-8 troops
Villages 2-10 troops 1-3 troops

Military Realism

  • More historically accurate army sizes
  • Medieval-scale battles (hundreds vs thousands)
  • Realistic garrison sizes for settlements
  • Proportional naval forces for ports

Implementation Steps

  1. Backup Original File

    cp modules/burgs-and-states.js modules/burgs-and-states.js.backup
    
  2. Locate Target Code

    • Open modules/burgs-and-states.js
    • Find the specifyBurgs function (starts around line 375)
    • Locate the population calculation section (lines 394-424)
  3. Make Changes

    • Replace the code block as specified above
    • Verify syntax and formatting
    • Save the file
  4. Test Changes

    • Generate a new map
    • Check settlement populations in the editor
    • Verify hierarchical relationships are maintained
    • Check military generation results
  5. Fine-Tune if Needed

    • Adjust division factors if populations are still too high/low
    • Modify multipliers if hierarchy isn't balanced
    • Tweak random variation parameters if needed

Testing & Validation

Population Validation

  1. Generate a new map with default settings
  2. Check capital cities are in 25k-35k range
  3. Verify towns are in 1k-8k range
  4. Confirm villages are under 3k
  5. Ensure hierarchical relationships are preserved

Military Validation

  1. Enable military generation
  2. Check that regiment sizes are proportional
  3. Verify capitals have reasonable garrison sizes (60-120 troops)
  4. Confirm naval units are only in appropriate ports

Edge Case Testing

  • Very small maps (few settlements)
  • Very large maps (many settlements)
  • Different culture/biome combinations
  • Various state types (Naval, Highland, etc.)

Troubleshooting

Common Issues

Populations Still Too High

  • Increase division factors further (e.g., /80 → /120)
  • Reduce multipliers more (e.g., 1.4 → 1.3 for capitals)

Populations Too Low

  • Reduce division factors (e.g., /80 → /60)
  • Increase minimum population (e.g., 0.01 → 0.02)

Hierarchy Not Preserved

  • Adjust multiplier ratios between settlement types
  • Check that hierarchical score calculation is working

Military Too Small

  • Military scales automatically with population
  • Consider adjusting populationRate in military settings if needed

Rollback Instructions

If changes cause issues:

  1. Restore Backup

    cp modules/burgs-and-states.js.backup modules/burgs-and-states.js
    
  2. Verify Restoration

    • Generate a test map
    • Check populations are back to original scale
    • Confirm military generation works normally

Advanced Customization

Further Adjustments

Ultra-Small Scale (cities ~10k):

  • Use division factor of /200 instead of /80
  • Reduce multipliers to 1.2, 1.15, 1.1
  • Set minimum to 0.005

Moderate Scale (cities ~50k):

  • Use division factor of /40 instead of /80
  • Keep multipliers at 1.6, 1.4, 1.25
  • Adjust random variation accordingly

Custom Settlement Types

Consider adding new settlement categories:

  • Metropolis (very rare, 50k+)
  • Hamlet (very common, <500)
  • Outpost (frontier settlements, <200)

Conclusion

These changes will create a more realistic population distribution suitable for medieval fantasy settings while maintaining the hierarchical settlement system and all existing functionality. Military forces will scale appropriately, creating more believable army sizes for the generated world.