not baad
This commit is contained in:
parent
4a8aff90b2
commit
6cef9a3abe
11 changed files with 1184 additions and 235 deletions
|
|
@ -17,8 +17,10 @@ import { buildCoarseCostGraph, refineCoarsePath, routeCoarsePath } from "./mapTr
|
|||
// 3. make sparse approximate transport paths without full-resolution A*
|
||||
// 4. synthesize population and land-use fields in one raster pass
|
||||
|
||||
export function generateMapFeatures(seed, terrain) {
|
||||
export function generateMapFeatures(seed, terrain, options = {}) {
|
||||
const SPEED_TOLERANCE = 0.90;
|
||||
const patchMode = options?.patchMode === true || options?.generationContext?.hasBoundaryWorld === true;
|
||||
const topCenterSuppression = clamp(Number.isFinite(options?.topCenterSuppression) ? options.topCenterSuppression : (patchMode ? 0.68 : 0), 0, 0.95);
|
||||
const featureTimings = [];
|
||||
const nowMs = () => typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
|
||||
let timingMark = nowMs();
|
||||
|
|
@ -502,7 +504,11 @@ export function generateMapFeatures(seed, terrain) {
|
|||
// regional pass.
|
||||
|
||||
modernCities.sort((a, b) => b.capacity - a.capacity || b.score - a.score);
|
||||
const regionalCapitalSlots = Math.max(1, Math.min(2, Math.floor(Math.sqrt(Math.max(1, modernCities.length)) / 2)));
|
||||
const baseRegionalCapitalSlots = Math.max(1, Math.min(2, Math.floor(Math.sqrt(Math.max(1, modernCities.length)) / 2)));
|
||||
const regionalCapitalSlots = patchMode
|
||||
? Math.max(0, Math.min(1, Math.round(baseRegionalCapitalSlots * (1 - topCenterSuppression))))
|
||||
: baseRegionalCapitalSlots;
|
||||
const topCenterGeoThreshold = 0.80 + topCenterSuppression * 0.16;
|
||||
for (const [rank, city] of modernCities.entries()) {
|
||||
const i = indexOf(city.x, city.y);
|
||||
const st = regionStats.get(city.regionId);
|
||||
|
|
@ -514,8 +520,12 @@ export function generateMapFeatures(seed, terrain) {
|
|||
fieldValue(geoAccessibility, i, 0) * 0.18 +
|
||||
Math.log10((city.capacity || 26000) + 1) / 7 * 0.26
|
||||
);
|
||||
const isTopCenter = rank < regionalCapitalSlots || geoTierScore > 0.8;
|
||||
const isRegionalCapital = isFirstInRegion && (isTopCenter || (city.capacity || 0) > 210000 || (st?.highCentralityCells || 0) > 220);
|
||||
const slotTopCenter = regionalCapitalSlots > 0 && rank < regionalCapitalSlots;
|
||||
const exceptionalPatchCenter = patchMode && geoTierScore > topCenterGeoThreshold && (city.capacity || 0) > 360000;
|
||||
const isTopCenter = (!patchMode && slotTopCenter) || exceptionalPatchCenter || (!patchMode && geoTierScore > topCenterGeoThreshold);
|
||||
const regionalCapacityThreshold = patchMode ? 300000 : 210000;
|
||||
const regionalCentralityThreshold = patchMode ? 340 : 220;
|
||||
const isRegionalCapital = isFirstInRegion && (isTopCenter || (city.capacity || 0) > regionalCapacityThreshold || (st?.highCentralityCells || 0) > regionalCentralityThreshold);
|
||||
const u = rand(st.seed, city.x, city.y, 9101);
|
||||
const v = rand(st.seed, city.x, city.y, 9102);
|
||||
const w = rand(st.seed, city.x, city.y, 9103);
|
||||
|
|
@ -524,17 +534,20 @@ let rawPop;
|
|||
|
||||
if (isRegionalCapital) {
|
||||
if (isTopCenter) {
|
||||
// largest 3M - 11M
|
||||
// largest 3M - 11M in full generation; patch candidates are suppressed
|
||||
// unless they are exceptionally strong geographic centers.
|
||||
rawPop =
|
||||
3000000 +
|
||||
Math.pow(u, 0.42) * 5200000 +
|
||||
Math.pow(v, 3.2) * 2800000;
|
||||
if (patchMode) rawPop *= (0.42 + (1 - topCenterSuppression) * 0.28);
|
||||
} else {
|
||||
// larger 0.25M - 2.5M
|
||||
rawPop =
|
||||
250000 +
|
||||
Math.pow(u, 0.55) * 1450000 +
|
||||
Math.pow(v, 2.4) * 900000;
|
||||
if (patchMode) rawPop *= 0.72;
|
||||
}
|
||||
} else {
|
||||
// normal 5k - 0.75k
|
||||
|
|
@ -543,9 +556,9 @@ if (isRegionalCapital) {
|
|||
Math.pow(u, 0.72) * 520000 +
|
||||
Math.pow(v, 3.0) * 320000;
|
||||
}
|
||||
const capMultiplier = isRegionalCapital ? (isTopCenter ? 1.66 : 1.42) : 1.20;
|
||||
const capMultiplier = isRegionalCapital ? (isTopCenter ? (patchMode ? 1.22 : 1.66) : (patchMode ? 1.08 : 1.42)) : 1.20;
|
||||
const population = Math.round(Math.min(rawPop, city.capacity * capMultiplier) / 1000) * 1000;
|
||||
const floor = isRegionalCapital ? (isTopCenter ? 210000 : 120000) : 42000;
|
||||
const floor = isRegionalCapital ? (isTopCenter ? (patchMode ? 150000 : 210000) : (patchMode ? 90000 : 120000)) : 42000;
|
||||
city.population = Math.max(floor, population);
|
||||
city.isPrefecturalCapital = isPrefecturalCapital;
|
||||
city.isRegionalCapital = isRegionalCapital;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue