The International Simutrans Forum

 

Author Topic: Better density for small cities on map generation  (Read 10008 times)

0 Members and 1 Guest are viewing this topic.

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Better density for small cities on map generation
« on: February 28, 2010, 01:08:31 PM »
I find that, when cities are generated at the start of the game with a high median population set, many cities will be generated that contain a small number of high density buildings and not a great deal else. This is somewhat undesirable and also unrealistic. Might I suggest that code be added to prefer lower density buildings for smaller cities, so that generated cities have the same characteristics as grown cities?

Offline wlindley us

  • Devotee
  • *
  • Posts: 978
    • Hacking for fun and profit since 1977
  • Languages: EN, DE
Re: Better density for small cities on map generation
« Reply #1 on: February 28, 2010, 02:22:05 PM »
Ideally, cities would be grown organically starting with the (generally smaller) oldest building sets and then accumulating growth to the start-time of the game.  In other words, a city generation process that mimics the way cities grow once the game actually starts.

This would solve both "why don't my villages look like villages?" issue (I entirely agree) and "why does my 1860 game not include any older houses at all?"

Offline colonyan

  • Devotee
  • *
  • Posts: 526
  • Full and Warm
Re: Better density for small cities on map generation
« Reply #2 on: February 28, 2010, 03:39:05 PM »
Simcity4 works as this.
Each building is classified in development stage.
It requires appropriate population to high stage buildings to appear.

In ST, city buildings are already attributed with class(density), james idea should be not hard to do I imagine.
such as building over class X requires Y population in that city.

I'm not saying doing realistic all around is absolutely necessary but where we can afford to have, why not?

Offline The Hood

  • Devotee
  • *
  • Posts: 2889
  • pak128.Britain developer
Re: Better density for small cities on map generation
« Reply #3 on: February 28, 2010, 03:46:37 PM »
such as building over class X requires Y population in that city.

I'd support this idea.

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Better density for small cities on map generation
« Reply #4 on: February 28, 2010, 03:50:08 PM »
I'd support this idea.

Seconded - this is an intelligent and easy way to implement it. I'd add only the suggestion that the population level thresholds be set as proportions of the median starting population, not hard-coded figures.

Offline The Hood

  • Devotee
  • *
  • Posts: 2889
  • pak128.Britain developer
Re: Better density for small cities on map generation
« Reply #5 on: February 28, 2010, 04:00:11 PM »
Connected to this, I also remember some time ago about differentiating between towns, cities and metropolises - there may even have been a patch for it.  Did this ever get implemented or did it get forgotten about?  If possible you could define certain population ranges on game start up for villages, towns, cities, and metropolises, and then certain buildings would only apear in some of these, in a similar way to how climates work?

Offline Dwachs

  • DevTeam, Coder/patcher
  • Administrator
  • *
  • Posts: 4602
  • Languages: EN, DE, AT
Re: Better density for small cities on map generation
« Reply #6 on: February 28, 2010, 06:43:07 PM »
Might I suggest that code be added to prefer lower density buildings for smaller cities, so that generated cities have the same characteristics as grown cities?
This is how the city generation works already! At first the population is calculated, then the city grows until this population is reached. So a generated city should look similar to a grown city.

Offline colonyan

  • Devotee
  • *
  • Posts: 526
  • Full and Warm
Re: Better density for small cities on map generation
« Reply #7 on: February 28, 2010, 07:03:46 PM »
Dwachs, are there any file we can modify so that smaller cities prefer lower density buildings ever further?
Is this defined in city rule file?

Word prefer is ambiguous that for my taste, there still is too many of high rise observed in small town/cities.

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Better density for small cities on map generation
« Reply #8 on: February 28, 2010, 07:55:29 PM »
This is how the city generation works already! At first the population is calculated, then the city grows until this population is reached. So a generated city should look similar to a grown city.

Hmm, that's odd. It doesn't seem to work properly, in that case, in that there are lots of small cities with a few high density buildings generated. Can this be looked into? Might there be a bug?

Offline prissi

  • Developer
  • Administrator
  • *
  • Posts: 9566
  • Languages: De,EN,JP
Re: Better density for small cities on map generation
« Reply #9 on: February 28, 2010, 10:03:35 PM »
That depends entirely on the cityrules you are using. In pak64, I have not noticed this.

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Better density for small cities on map generation
« Reply #10 on: March 01, 2010, 12:52:24 AM »
Prissi,

ahh, so it's a setting in the city rules file? What needs to be changed to have the desired effect?

Offline The Hood

  • Devotee
  • *
  • Posts: 2889
  • pak128.Britain developer
Re: Better density for small cities on map generation
« Reply #11 on: March 01, 2010, 08:37:04 AM »
In pak128.Britain it may also be that the building levels are fairly arbitrary.  It could be that I need to increase the level of the larger buildings, as in currently it may be that the tallest buildings actually have a relatively low level, low enough to get built in small towns.  I intend to investigate this further once I've done planes, ships and complete snow images for everything, using VS's citybuilding level tool.  But anyone that can do some investigation on this would be most welcome to do so.

Offline Dwachs

  • DevTeam, Coder/patcher
  • Administrator
  • *
  • Posts: 4602
  • Languages: EN, DE, AT
Re: Better density for small cities on map generation
« Reply #12 on: March 01, 2010, 10:04:12 AM »
Imho the city generation works as intended. I think the observation of non-organic city growth is biased by the following: intercity roads (and player roads as well) are built after city generation, so cities cannot make use of them.

Create a map without intercity roads (intercityroad length=0). Then grow a city with the map editor tools.

Now do this with another city, but supply some roads first to the city, then use the growth tool.

You will notice that in the latter case the city builds much more buildings than in the former case, where mostly buildings are upgraded.

Offline mobo

  • Devotees (Inactive)
  • *
  • Posts: 199
Re: Better density for small cities on map generation
« Reply #13 on: March 01, 2010, 11:08:13 AM »
there is this entry in the cityrules.tab:
Code: [Select]
# chance for renovation versus new building
(bigger number => less sprawling)
renovation_percentage = 5

Was introduced to decrease sprawling.

It also depends on the level-structure of the pakset, if new buildings always have a higher level than old ones there will be many new high level buildings. Or the other way: if some old building has lvl 30 (e.g) then it will only be replaced by a building with higher level (if there is none it'll stay).

One approach to deal with this is to have high level buildings in all ages and to have gaps between the levels (like lvl 5, 10, 15). The gaps shall create zones of different levels (center ->...->outskirt).

However, i have the same obervations/problems in p32c too. Generated cities consist mostly of buildings with max level (especially obvious with small cities). because i started with a pretty linear distribution of levels with proceeding time levels get higher and higher. Changing this is on the todo-list.
« Last Edit: March 01, 2010, 11:18:40 AM by mobo »

knightly

  • Guest
Re: Better density for small cities on map generation
« Reply #14 on: March 01, 2010, 03:09:02 PM »
I looked into stadt_t::baue() and suspected that there is something wrong with the logic flow of the code. I then set up hit-counting breakpoints at the calls to
:bulletblue: baue_strasse()
:bulletblue: baue_gebaeude(), and
:bulletblue: renoviere_gebaeude()
respectively, and create a new 512 x 512 map with 8 cities and 3200 median population size. The results confirm my hypothesis :

Quote
Pak128.Britain
:bulletpurple: Total calls = 12394
:bulletpurple: Build new road = 171
:bulletpurple: Build new building = 120
:bulletpurple: Renovate old building = 1255
:bulletpink: %Renovation in cityrules.tab = 12%
:bulletpink: Actual %Renovation = 1255/(120+1255) = 91.27%

Pak64
:bulletpurple: Total calls = 22319
:bulletpurple: Build new road = 203
:bulletpurple: Build new building = 131
:bulletpurple: Renovate old building = 2653
:bulletpink: %Renovation in cityrules.tab = 12%
:bulletpink: Actual %Renovation = 2653/(131+2653) = 95.29%

As you can see, the %renovation is well over 12% (although renovation/total calls is quite close to 12%). 9 out of 10 times, we have renovation of an old building instead of construction of a new one.

The problem is that, only one random coordinate within the city limits is tested in each call to stadt_t::baue(), and the likeliness of that coordinate being suitable for building either new roads or new buildings is rather low (actually, almost negligible). So, in most cases, we end up checking for renovation only.

The end result is more or less like checking at each call whether we should renovate an exisiting building based on probability, until we have satisfied the housing needs. Put it simply, we really get 12% of renovation out of total calls to stadt_t::baue(), but that doesn't mean that we get 88% new buildings.
« Last Edit: March 01, 2010, 04:28:45 PM by Knightly »

Offline Spike

  • *
  • Posts: 1361
  • First Simutrans Developer and Graphics Artist
Re: Better density for small cities on map generation
« Reply #15 on: March 01, 2010, 03:13:48 PM »
But this doesn't explain why people say the initial cities are less spread out and have higher level buildings than comparably populated cities that grow during the game later.


Offline wlindley us

  • Devotee
  • *
  • Posts: 978
    • Hacking for fun and profit since 1977
  • Languages: EN, DE
Re: Better density for small cities on map generation
« Reply #16 on: March 01, 2010, 03:25:58 PM »
Hajo, After reading the analysis by Knightly, some experimentation with city generation and growth seems to suggest the "initial vs. later" bias may be more to do with perception of what a small town "should" look like versus what larger cities "should" look like.

knightly

  • Guest
Re: Better density for small cities on map generation
« Reply #17 on: March 01, 2010, 03:44:04 PM »
I don't know why there is a difference between initial vs later, if any, as they all call the same function, stadt_t::step_baue().

But I have found another bug in stadt_t::baue(), in the code portion on renovation :
Quote
gb = buildings[simrand(buildings.get_count())];
buildings is a weighted-vector, so any randomisation should be done with buildings.get_sum_weight(), not buildings.get_count().

Edit :

Sorry, I misinterpreted the quoted code. It is correct and it just randomly chooses a building, not based on its weight.
« Last Edit: March 01, 2010, 04:28:57 PM by Knightly »

Offline Dwachs

  • DevTeam, Coder/patcher
  • Administrator
  • *
  • Posts: 4602
  • Languages: EN, DE, AT
Re: Better density for small cities on map generation
« Reply #18 on: March 01, 2010, 04:21:34 PM »
I looked into stadt_t::baue() and suspected that there is something wrong with the logic flow of the code. I then set up hit-counting breakpoints at the calls to
:bulletblue: baue_strasse()
:bulletblue: baue_gebaeude(), and
:bulletblue: renoviere_gebaeude()
respectively, and create a new 512 x 512 map with 8 cities and 3200 median population size.
It would be interesting to run the same procedure with no intercity roads and intercity roads.

My suspection is that generated cities tend to renovate their buildings, since there are too few roads are built. Intercity roads are build after the city generation.

knightly

  • Guest
Re: Better density for small cities on map generation
« Reply #19 on: March 01, 2010, 05:11:20 PM »
Dwachs, here are the results for with and without intercity roads :

Quote
Pak64 (12% renovation as per cityrules.tab), 8 cities, 3200 median population size

:bulletblue: Intercity Roads = 7000
    :bulletpurple: Total calls = 12367
    :bulletpurple: Build new road = 126
    :bulletpurple: Build new building = 100
    :bulletpurple: Renovate old building = 1339
    :bulletpink: Actual %Renovation = 1339/(100+1339) = 93.05%

:bulletblue: Intercity Roads = 0
    :bulletpurple: Total calls = 24104
    :bulletpurple: Build new road = 165
    :bulletpurple: Build new building = 125
    :bulletpurple: Renovate old building = 2807
    :bulletpink: Actual %Renovation = 2807/(125+2807) = 95.74%

As you have said, intercity roads are built after city generation, so there should be no difference between the 2 cases.

My suspection is that generated cities tend to renovate their buildings, since there are too few roads are built. Intercity roads are build after the city generation.

I think you are right. If you take a look at the statistics again, not only that the % of building new buildings compared to total calls is low, % of building new roads to total calls is also low. If inter-city roads are present, the chance of getting a suitable place to build new buildings is higher.

Offline Dwachs

  • DevTeam, Coder/patcher
  • Administrator
  • *
  • Posts: 4602
  • Languages: EN, DE, AT
Re: Better density for small cities on map generation
« Reply #20 on: March 01, 2010, 07:44:56 PM »
Another possibility would be to drastically reduce the renovtion_percentage in cityrules.tab.

I also got the feeling that cities had lower level building if more roads are constructed: setting the chance values nearer to -7 (which means this rule will be checked 100% if the city builder wants to build a road).

Offline VS

  • Senior Plumber (Devotee)
  • Devotee
  • *
  • Posts: 4855
  • Vladimír Slávik
    • VS's Simutrans site
  • Languages: CS,EN
Re: Better density for small cities on map generation
« Reply #21 on: March 01, 2010, 08:11:09 PM »
That could be quite easy to explain. More roads mean that rules for construction near roads hit more often empty space... so new low level building are created.

knightly

  • Guest
Re: Better density for small cities on map generation
« Reply #22 on: March 01, 2010, 08:38:11 PM »
A patch for correctly enforcing renovation_percentage.

Warning : With this patch, renovation percentage of 10% will really create 9 new buildings out of 10 times. Existing paksets will most likely need to adjust the renovation_percentage figure again. If you use the existing figure of 12% and build cities with heavy population, you will end up with a vast expanse of city bulidings (maybe that's what James want for his suburban transportation).


Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Better density for small cities on map generation
« Reply #23 on: March 01, 2010, 09:13:08 PM »
Knightly,

thank you very much for looking into this - I have not tested your patch yet, but this looks very promising. I do indeed want something suitable for suburban transportation, but with some balance between realistic sprawl and realistic city centres.

Offline z9999+

  • Coder/patcher
  • *
  • Posts: 377
Re: Better density for small cities on map generation
« Reply #24 on: March 02, 2010, 06:42:14 AM »
I couldn't find major difference from original version.
Could you show us new Actual %Renovation value of your patched version ?

[EDIT]
An another problem.
If I set 8000 population and minimum_building_desity renovation_percentage = 70, it takes long time to make a new map.
« Last Edit: March 03, 2010, 06:12:17 PM by z9999+ »

knightly

  • Guest
Re: Better density for small cities on map generation
« Reply #25 on: March 02, 2010, 09:23:51 AM »
Thank you very much for testing, Z9999+ :)

Here are the results with Pak64 (%renovation 12 as per simuconf.tab), 8 cities, 3200 median population :
Total calls = 11985
New Road = 7192
New Building = 2021
Renovation = 1492
Real %Renovation = 1492/(1492+2021) = 42.47%

The rate of renovation is a lot lower now. The reason why it isn't roughly the same as the stated 12% is that, the original code (and after patched) actually only distinguishes between (new road and new building) vs (renovate old building), as there is only 1 percentage_renovation setting. If you calculate this way : 1492/(1492+2021+7192) = 13.93%, it is much closer to the stated %. This is not the case before patched, so there indeed is a significant change.

As for slowness, due to the fact that it is really hard to find suitable locations for new roads and buildings (as evident in the statistics in the previous posts), unless we are satisfied with forsaking some randomness in the shape of the cities and adopt the approach used in distributing fields (which are distributed ring by ring, with randomness only within each ring), I am afraid I can't think of a more efficient way to handle this problem. Of course, if someone can think of a better method, it will be nice ;).

Regarding your case specifically, I will check if some rearrangement of logic flow might help, as I suspect that the program is stuck when there is no suitable location to place new roads/buildings.

Incidentally, city centres no longer appear after patched. It is because the original renovation code does not bias towards buildings in the city centre. Those city centres created with the original code are actually by-products of the bug -- initial buildings have many chances to get an upgrade when the city is still small. I will add some code to make city centres appear again.

Offline wlindley us

  • Devotee
  • *
  • Posts: 978
    • Hacking for fun and profit since 1977
  • Languages: EN, DE
Re: Better density for small cities on map generation
« Reply #26 on: March 02, 2010, 12:00:12 PM »
While you are modifying this, could you permit the creation of buildings older than the current year?  Then in a timeline city, there will be some "old" (discontinued in timeline) buildings not just "new" ones? 

One way might be to save the current year; move the current year back by a factor times the desired city size; then with each building built, increment the current year by the factor; and then restore the year after building the city.  Thus the old buildings will tend to be smaller, and the new buildings larger (renovated).

Towns in a timeline game will look much more realistic; a game started in 1930 will contain a few buildings from the 1700s.

Offline z9999+

  • Coder/patcher
  • *
  • Posts: 377
Re: Better density for small cities on map generation
« Reply #27 on: March 02, 2010, 12:25:24 PM »
Thank you for your explaining.

The rate of renovation is a lot lower now.

Ok, then I change the question.
How much minimum_building_desity renovation_percentage value should I set to get the same result as original version ?

Quote
Incidentally, city centres no longer appear after patched.

But if I set higher value of  renovation_percentage minimum_building_desity, result is the same or worse than original.
And also, lower  renovation_percentage minimum_building_desity value only means lower building level for both big town and small town.
« Last Edit: March 03, 2010, 06:13:37 PM by z9999+ »

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Better density for small cities on map generation
« Reply #28 on: March 02, 2010, 12:38:18 PM »
Knightly,

the speed issue is somewhat important. Would it be possible to have an option in simuconf.tab to use the ring system instead of a totally random system just for the first-run generation of cities? That would not need re-versioning the saved game file format, since, as it is a value that would only be used on map generation, it is not a value that would need to be saved.

Offline prissi

  • Developer
  • Administrator
  • *
  • Posts: 9566
  • Languages: De,EN,JP
Re: Better density for small cities on map generation
« Reply #29 on: March 03, 2010, 01:17:24 PM »
I have the feeling, that most routines depend on preserving the order in a vector. I am not sure that there are some side effect caused by this.

And of course instead testing a single random coordinate, one must test the whole ground first and then again applies the rules. But I think one could use this approach with a little less time required and still the same result.

knightly

  • Guest
Re: Better density for small cities on map generation
« Reply #30 on: March 03, 2010, 05:10:08 PM »
@Prissi

I have the feeling, that most routines depend on preserving the order in a vector. I am not sure that there are some side effect caused by this.

If you look more carefully, you will see that I have added a default argument "true" for "preserve_order", so all old calls retain old behaviour. I have anyway changed it into a separate function already.

But I think one could use this approach with a little less time required and still the same result.

Although I may not work on this patch anymore due to performance issues, I would still like to know how to improve on this. Currently I have cached the remaining candidate coordinates for use in the next call (after a suitable location is found to build new road/building).


@Z9999+

You do not need to change minimum_building_density : if you set it to 70%, the city boundaries will rarely expand, suffocating city expansion and forcing more renovations. There is nothing wrong with that setting; what is wrong is renovation_percentage. You can try adjusting renovation_percentage upwards. I don't know what setting will bring back the original version, as the underlying mechanism has somewhat changed.

But please don't bother to test anymore, unless the performance problems are overcome and I can release a new patch.

Offline z9999+

  • Coder/patcher
  • *
  • Posts: 377
Re: Better density for small cities on map generation
« Reply #31 on: March 03, 2010, 06:15:05 PM »
You do not need to change minimum_building_density

Thank you for pointed out my mistake.
I tested renovation_percentage and I thought I wrote as renovation_percentage.
Corrected them.

knightly

  • Guest
Re: Better density for small cities on map generation
« Reply #32 on: March 03, 2010, 06:54:59 PM »
@Z9999+

I see, you really tested renovation_percentage. Actually, the main purpose of my patch is to better enforce renovation_percentage. Once that is properly enforced, we can add some logic so that when cities are still small, renovation percentage will be reduced. E.g.
    1/4 of %renovation if population<500
    1/2 of %renovation if 500<=population<1000
    ....
Or, (population/2000) x %renovation for population size <2000 ...

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Devotee
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: Better density for small cities on map generation
« Reply #33 on: March 03, 2010, 07:51:41 PM »
Knightly,

as to performance, do you not think it worth a go to see whether you can use the field approach as discussed in a previous post?

Offline prissi

  • Developer
  • Administrator
  • *
  • Posts: 9566
  • Languages: De,EN,JP
Re: Better density for small cities on map generation
« Reply #34 on: March 03, 2010, 08:58:04 PM »
For building city centers, one could easily do:
         gb = buildings[buildings.at_weight(simrand(buildings.get_sum_weight()))];
instead
         gb = buildings[simrand(buildings.get_count())];
The higher level would be more likely to recieve renovation.

EDIT: But the main point is, if the user feel that the current system produces unnatural towns. In a short test, I had some troubles to spy out the differences for normal standard values.
« Last Edit: March 03, 2010, 09:02:41 PM by prissi »

knightly

  • Guest
Re: Better density for small cities on map generation
« Reply #35 on: March 03, 2010, 11:10:11 PM »
@James

The ring-by-ring approach is not without problem. Unlike fields, there may be holes in a ring due to inapplicability of house rules or road rules. A reasonable criteria to determine whether to expand search to the next ring is to see if an exhaustive search in the current ring fails. However, even an exhaustive search is not really exhaustive : rules are only checked if they first pass the chance test (based on their respective chance factor), meaning that some tiles may have applicable rules which are not applied. This leads to premature expansion of search to the next ring, thus losing much of the benefit of this approach.


@Prissi

gb = buildings[buildings.at_weight(simrand(buildings.get_sum_weight()))];

I have tried this approach already, but it ends up with a few very high-level buildings here and there near the centre, and there are some level-one or two buildings at the city centre even for very large cities (as they never have the chance to renovate just because of their low level).

EDIT: But the main point is, if the user feel that the current system produces unnatural towns. In a short test, I had some troubles to spy out the differences for normal standard values.

I don't know if you mean you have tested the original code or my patch. If it is the latter, I want to emphasize once again that the major purpose of my patch is to better enforce renovation_percentage, and while it is not difficult to do, I have not yet included any code in the above patch which deals with the difference between large cities and small towns.