Azgaar / Fantasy-Map-Generator

Web application generating interactive and highly customizable maps

Home Page:https://azgaar.github.io/Fantasy-Map-Generator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Population can go negative so displayed as too big

wish-t-learn opened this issue · comments

After modifying the height, it is found that the population does not meet the setting, and there will be a large population in the tundra, which is more than the tropical rainforest.

Can you share the .map file? It's not clear what the problem can be.

How to share files?I tried dragging the file directly to the reply bar, but it doesn't support that.

The tundra is surrounded by glaciers where large populations appear.

I have edited the map, but I have been using "Erase" mode modification.

Boulonvil 2022-11-26-20-42.zip
Sorry, just saw how other people share .map files.

zip is fine, I will check it out

I don't see the problem. Tundra takes 8% of land area while only 2% of population lives there.
Tropical rainforest occupies only 1% of area and contains 3% of population.
If you want the difference to be more significant, you can change the habitability.

image

图片
图片

The problem was around the South Pole of the map, where there were significantly more people spawning than in the surrounding more livable land.

Got it. Yes, it looks like a bug, will check

Found the root cause - for some reason these cells have very big area. Population is normalised for cell area, so it makes it bigger than expected. Will check what is wrong with are calculation

Ok, thanks for your answer. Although these cells look small, they are actually very large.

Was not able to find the bugged line so far. Will keep it open

Was not able to find the bugged line so far. Will keep it open

This bug still exists.

It looks like there are 100x as many people in the problem cells as there should be.
One with 1.5 million would fit in with 15k;
One with 518k that would fit in with 5k;
One with 1.8 million that would fit in with 18k;

However, some definitely didn't seem right—one with 6.2 million that should have had around 20k at most.

I tried playing around with the heightmap in that spot a little bit, and the exact same cells were overpopulated. I tried playing around with it a lot, completely changing that area, and the coastal squares that had weird populations were fixed.

Screen Shot 2023-11-01 at 9 23 26 PM
Munlin 2023-11-01-16-21.map.zip

Here's an older file with far fewer points showing the same problem, though incredibly concentrated in one spot.
Qiam 2023-02-05-17-24.map.zip

commented

Yes, I know it exists, I just don't know why

In main.js, in function rankCells(), the part where it normalizes population based on cell area is the issue. When I downloaded the program and changed the calculation from
cells.pop[i] = cells.s[i] > 0 ? (cells.s[i] * cells.area[i]) / areaMean : 0;
to
cells.pop[i] = cells.s[i] > 0 ? cells.s[i] : 0;
and regenerated the population, the problem went away entirely. I'm not good with javascript, but maybe there's another way to calculate the area of cells that won't cause this issue?

After regenerating the population, I also saw it increase massively—from 113 million to 148 million.

Hello @Eiszett,

We need to normalize the population to area, but yes, it can be bugged.

Hello @Eiszett,

We need to normalize the population to area, but yes, it can be bugged.

I'm aware that it's bugged. That's why, when I needed to actually get usable population data, I had to fix it myself.

Normalizing the population by area is useful, because of the variance in size between cells, but the current method is very clearly bugged, so surely it's worth scrapping it until the underlying issue (cell size caculation?) is solved?

The calculated average is about 75% of what it should be (113 / 148, as mentioned above, and 319 / 420, as shown below), as removing the normalization increases overall population by a third (so the mean cell size isn't actually the mean cell size—perhaps skewed from large water cells?), and the distribution is heavily skewed, with certain regions of the map having disproportionately massive populations due to these bugged cells. Like, several times higher. It's not just the population being displayed as absurdly high—it's counted that way everywhere.

Some tiny countries wind up having several times the population they should because they happen to be in an area with a lot of these cells. Eg: In the attached images, Palong goes from 14.8 million bugged people to 5.8 million non-bugged people (x0.75 to adjust for overall change = 4.4 million non-bugged people).
Screen Shot 2024-02-22 at 11 42 43 AM
Screen Shot 2024-02-22 at 11 43 09 AM
Screen Shot 2024-02-22 at 11 43 37 AM
Screen Shot 2024-02-22 at 11 45 52 AM

In the meantime of getting a normalization of size for the cells, I came up with the following console code for that purpose, hopefully it helps
`
const avg = pack.cells.area.reduce((sum,value) => sum + value, 0) / pack.cells.area.length;
//You can modulate the "2" to set your preferred threshold
pack.cells.area = pack.cells.area.map(function (entry) {
if (entry > (avg*2)) {
//You can modulate the "1.25" to your desired factor
return Math.random() * (avg * 1.25);;
} else {

return entry;

}
});;
`

After applying this console code, you can regenerate population and it should be normalized.
Sorry for the bad formatting for the code, I'm still fairly new to Github. Basically, what this does is identify cells that are over 2 times (modifiable threshold) the average size of a cell on the map and then apply a random normalization to about 1.25 times the average size (also modifiable).

If you're using ocean cells' area for your zones, there's this other version that only applies the change to cells with height over 20

const avg = pack.cells.area.reduce((sum, value) => sum + value, 0) / pack.cells.area.length;

const threshold = 20; // Define the threshold value

pack.cells.area = pack.cells.area.map(function (entry, index) {
if (pack.cells.h[index] > threshold) { // Check if pack.cells.h[index] is greater than the threshold
if (entry > (avg * 2)) {
//You can modulate the "1.25" to your desired factor
return Math.random() * (avg * 1.25);
} else {
return entry;
}
} else {
return entry;
}
});