News:

Want to praise Simutrans?
Your feedback is important for us ;D.

New city generation function.

Started by inkelyad, July 03, 2010, 12:46:00 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

inkelyad

Ok. Release time.

Changes:

'minimum_city_distance' in cityrules.tab was deleted. There is 'city_repulse_factor' instead (I need better name).
It set how much cities avoids each other.

Water now attracts cities. How much is set in 'Water appeal' setting in climate dialog.
It does not work well with 'Cities ignore height' option. Result is confusing.
Use 'Cities ignore height'==on and 'water appeal' !=0 or 'Cities ignore height'==off and 'water appeal' =0

Cities now form clusters. 'Number of clusters' and 'Cluster size' in Create new game dialog.
Number of clusters == 0 means no clustering.

See 'Cities ignore height' option thread for screenshots.

Isaac Eiland-Hall

city_repulse_factor --> city_avoid_factor?

inkelyad


inkelyad

And small MSVC compatibility patch.

jamespetts

#4
Inkelyad,

thank you very much for your patch; most interesting. I have not yet had the opportunity to try it (I am currently away from home), but shall investigate when I get a chance.

However, you will need to make this work well with the system for making cities more likely to be built on lower ground before I can release it. May I ask what the problem is with interaction between the two systems is so far?

Edit: Also, can I check - does this significantly slow down map generation for, say, a 1024x2048 map with 250 cities?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

#5
Rivers usually lower ground too. 'Cities ignore height' status become almost useless when 'water appeal' is enabled.

It is somewhat slower. But city growth stage is much longer. I don't change that part.

jamespetts

In Simutrans, rivers lower ground by one tile immediately around the river. Cities being attracted to water does not have the same effect as cities preferring lower ground. Cities' preference for lower ground should not be almost useless when they are attracted to water: the two are distinct.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

It is really hard to notice when there is many rivers  on the map. All lower ground become near water. Rivers flow that way.

jamespetts

I am not sure that I understand - what is really hard for whom to notice? And what of the case where there are not so many rivers on the map? What of distinguishing between medium high, high and very high ground?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

AP

Quote from: Isaac.Eiland-Hall on July 03, 2010, 01:22:38 PM
city_repulse_factor --> city_avoid_factor?
City isolation factor?
City mutual attraction factor? (if you invert it)


inkelyad

Quote from: jamespetts on July 03, 2010, 09:38:48 PM
I am not sure that I understand - what is really hard for whom to notice?
It hard to notice 'Cities ignore height' effect. All rivers/seas pull cities to coastline. It is 'lower ground' -> no cities at mountains. Like when 'Cities ignore height' == off.
Quote from: jamespetts on July 03, 2010, 09:38:48 PM
And what of the case where there are not so many rivers on the map?
Then 'Cities ignore height' == off works.

inkelyad

Quote from: AP on July 03, 2010, 09:45:48 PM
City isolation factor?
I will use it.
How about all others parameters? I doubt 'water appeal' and 'Clusters' too.

sdog

repulsion and attraction would be terms corresponding well.

inkelyad

Quote from: sdog on July 03, 2010, 10:52:50 PM
repulsion and attraction would be terms corresponding well.
It will conflict with 'Tourists attractions'

AP

Quotecity_repulse_factor  >>  "city isolation factor"
maybe then:
Water appeal >> "City river proximity factor"


With the clusters, if set to >0 , are you specifying the precise number of clusters, or a probability? Ie, if set to 2, on a 2000x2000 map, will you still only get 2 clusters same as on a 200x200 map? Or does it "scale"? I quite like the term "cluster" though, it explains itself well.


One other thing, I wonder if "settlement" would not be better than "city" as a term, since a village of 300 people is not exactly a city!

inkelyad

Quote from: AP on July 04, 2010, 12:38:11 PM
maybe then:
Water appeal >> "City river proximity factor"
"City river proximity factor" really does not say anything about what it do.

Quote from: AP on July 04, 2010, 12:38:11 PM
With the clusters, if set to >0 , are you specifying the precise number of clusters, or a probability?
Ie, if set to 2, on a 2000x2000 map, will you still only get 2 clusters same as on a 200x200 map? Or does it "scale"? I
It will be 2 clusters.

Quote from: AP on July 04, 2010, 12:38:11 PM
One other thing, I wonder if "settlement" would not be better than "city" as a term, since a village of 300 people is not exactly a city!
Simutrans uses term 'city'. I think to change it is not wise -- it will break all translations.

jamespetts

"cities_like_water=xx" is a good name, I think, for the water setting. To my mind, Inkelyad's existing terminology for "city clusters" is clear enough, and he is right about the consistent use of "city" in Simutrans to mean any conurbation.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

Quote from: jamespetts on July 04, 2010, 01:51:36 PM
"cities_like_water=xx" is a good name, I think, for the water setting
For *.tab file, yes. But it is part of climate dialog now. Shuld I move it in *.tab file too?

jamespetts

It should probably be used consistently for the config.tab file and climate dialogue.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

    'Water appeal' renamed to 'Cities like water'
    'city_repulse_factor' renamed to 'city_isolation_factor'
    Some minor math tweaking regarding 'Cities like water'.

inkelyad

#20
Some profiling data.

3072x1024 map, 128 cities.
unpatched:

index % time    self  children    called     name

-----------------------------------------------
              27.53 62961.33     100/100         karte_t::enlarge_map(einstellungen_t*, signed char*) [4]
[6]     63.1   27.53 62961.33     100         karte_t::distribute_groundobjs_cities(int, short, short) [6]
               0.05 40672.88   12800/12800       stadt_t::stadt_t(spieler_t*, koord, int) [8]
               0.00 8847.02   40515/43866       wegbauer_t::calc_route(koord3d const&, koord3d const&) [24]
               1.86 8838.05     100/100         stadt_t::random_place(karte_t const*, int, short, short) [27]
              31.71 1628.01 209344308/2306701683     karte_t::lookup_kartenboden(koord) const [7]
               0.00 1548.64   26459/26465       route_t::calc_route(karte_t*, koord3d, koord3d, fahrer_t*, unsigned int, unsigned int, unsigned int) [52]
               0.00  788.25     100/100         karte_t::create_rivers(short) [69]
               0.00  530.16   16212/30612       wegbauer_t::baue() [59]
               0.33   28.08 79228917/79228917     groundobj_t::random_groundobj_for_climate(climate, signed char) [177]

--------------
                1.86 8838.05     100/100         karte_t::distribute_groundobjs_cities(int, short, short) [6]
[27]     8.8    1.86 8838.05     100         stadt_t::random_place(karte_t const*, int, short, short) [27]
                0.60 8824.66     100/100         karte_t::finde_plaetze(short, short, climate_bits, short, short) const [28]
                0.97    6.77   51200/54551       weighted_vector_tpl<koord>::remove(koord) [237]
                1.10    0.79 37050074/37050074     slist_tpl<koord>::remove_first() [362]

patched

              68.95 5786.79     100/100         karte_t::enlarge_map(einstellungen_t*, signed char*) [4]
[5]     53.2   68.95 5786.79     100         karte_t::distribute_groundobjs_cities(einstellungen_t const*, short, short) [5]
               0.00 2256.80   16866/21638       wegbauer_t::calc_route(koord3d const&, koord3d const&) [6]
             376.41 1561.93     100/100         stadt_t::random_place(karte_t const*, vector_tpl<int> const*, unsigned int, unsigned int, short, short) [12]
               0.08  642.40     100/100         karte_t::create_rivers(short) [25]
               0.01  585.30   12800/12800       stadt_t::stadt_t(spieler_t*, koord, int) [27]
              23.66  109.43 628365130/867552698     karte_t::lookup_kartenboden(koord) const [11]

-----------------
             376.41 1561.93     100/100         karte_t::distribute_groundobjs_cities(einstellungen_t const*, short, short) [5]
[12]    17.6  376.41 1561.93     100         stadt_t::random_place(karte_t const*, vector_tpl<int> const*, unsigned int, unsigned int, short, short) [12]
               1.67  709.43     100/100         karte_t::finde_plaetze(short, short, climate_bits, short, short) const [24]
             161.64    0.00 3538043483/1442927365     array2d_tpl<double>::at(unsigned int, unsigned int) [47]


Results are strange. karte_t::finde_plaetze should take almost equal time in in patched and unpatched versions. Bot it is not.
Some for stadt_t::stadt_t.

jamespetts

#21
With the patch, I notice quite a number of things with very greatly increased values, for example, "stadt_t::random_place(karte_t const*, vector_tpl<int> const*, unsigned int, unsigned int, short, short) [12]" increases from 1.86 to 376.41, or from 8.8% of time taken to 17.6%. Do you find that this has a noticable impact on real-world performance?

Edit: I have tried applying this patch to the latest version of -devel, but it appears that recent changes to the code merged in from Standard break this patch so that it can no longer be applied. Do you think that you could post an updated patch (or, better yet, create a Github branch and use that instead)?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

Quote from: jamespetts on July 11, 2010, 09:39:12 AM
With the patch, I notice quite a number of things with very greatly increased values, for example, "stadt_t::random_place(karte_t const*, vector_tpl<int> const*, unsigned int, unsigned int, short, short) [12]" increases from 1.86 to 376.41, or from 8.8% of time taken to 17.6%. Do you find that this has a noticable impact on real-world performance?
I find stadt_t::random_place execution time almost irrelevant. Total map generation time very depends on settings. When default settings are used ( upatched: N cities; patched: N cities, one big) my version is faster.
Compare 629.61 sec/map with 57.86 sec/map. When I use 'all cities are big' it is not so.

Another setting 'intercity road length' eat time pretty fast too.

Quote from: jamespetts on July 11, 2010, 09:39:12 AM
I have tried applying this patch to the latest version of -devel, but it appears that recent changes to the code merged in from Standard break this patch so that it can no longer be applied. Do you think that you could post an updated patch (or, better yet, create a Github branch and use that instead)?
I'll do it when my home ISP recover from recent thunderstorm. It fired the big part of access network. I don't have Internet access at home now.


jamespetts

Inkelyad,

thank you very much for this. I notice that you include the new city settings in "einstellungen.cc" rather than "umgebung.cc"; was there a particular reason for this? The settings in relation to cities are used only when a new map is generated; they do not, therefore, need to be loaded and saved with saved games or transmitted accross the network in network multiplayer games (when that feature is finalised); or am I missing something?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

#25
Quote from: jamespetts on July 13, 2010, 09:57:24 PM
thank you very much for this. I notice that you include the new city settings in "einstellungen.cc" rather than "umgebung.cc"; was there a particular reason for this?
No. It was analogy. anzahl_staedte is in einstellungen => all others city-related setting must be in einstellungen too.

inkelyad

I have moved settings to umgebung_t (see github repository)

jamespetts

#27
Inkelyad,

I have finally got around to trying this: see my -devel branch for it integrated with two minor changes (a compile error fix and some slight alterations to GUI text). I very much liked the functionality, especially the "cities like water" settings, which make for a much improved map generation experience. This will make it much easier to play in the pre-canal era with boats on rivers and the sea.

One or two things still need to be done, I think: firstly, there needs to be a way of saving the values entered for "city cluster size", "cities like water", etc. between sessions, in the same way as "number of cities" is saved between sessions. There are two possibilities here. Either the values can be read from simuconf.tab (which might require adding some of the code for reading the values to einstellugen.cc), in which case, pakset authors can determine the default settings, or they need to be saved to settings.xml by using the rdwr function in umgebung.cc (and, in that case, it needs to check for an experimental saved game version number greater or equal to 9). I should be interested in people's comments as to which of the two is preferable.

Edit: One problem that I have noticed with this, however, is that it very often does not produce the number of cities stipulated. I stipulated 200 cities, for example, and it produced about 25. This was with city cluster size 50, 3 clusters and 3 big cities, with "cities like water" at 60%.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

Quote from: jamespetts on July 17, 2010, 01:32:18 PM
One problem that I have noticed with this, however, is that it very often does not produce the number of cities stipulated. I stipulated 200 cities, for example, and it produced about 25. This was with city cluster size 50, 3 clusters and 3 big cities.
There is not  enough room  for 200 cities. cluster size 50 is very small cluster.
Define DBG_WEIGHTMAP(used in unutils/dbg_weightmap.*)  in compilation flags and look for generated .pgm files.
I don't know how work in Windows compilation environment.

jamespetts

Inkelyad,

if there is not enough room for the number of cities specified, the game should give some feedback to explain the reason that the user's settings are not being respected. The previous behaviour was always to build the number of cities stipulated.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

#30
What is the best way to do it? I don't know how GUI works to call message box directly from stadt_t::random_place.

relevant code is

               if (index_to_places.empty() ) {
                       if(city_nr < sizes_list->get_count() - 1) {
                               dbg->warning("stadt_t::random_place()", "Not enough places found!");
                       }
                       break;
               }

Edit: Another way is to place rest of cities outside of clusters.

jamespetts

Hmm, I don't remember off the top of my head how to generate a GUI message: if I were doing it, I'd look to see how it is done elsewhere in the code by searching through the project to find the untranslated string of just such a message.

It is indeed a good idea to build cities outside clusters rather than fail to build cities at all, although the user should probably still be given some warning that it has failed. Also, can it be predicted the minimum cluster size that any given number of cities can tolerate? If so, the allowable number of cities and/or cluster sizes can be adjusted in the GUI.

In any event, thank you again for all your work on this: it does really make a difference to map generation!
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

Quote from: jamespetts on July 17, 2010, 08:57:44 PM
It is indeed a good idea to build cities outside clusters rather than fail to build cities at all,
Changes pushed to github. No warning message, sorry.

Quote from: jamespetts on July 17, 2010, 08:57:44 PM
Also, can it be predicted the minimum cluster size that any given number of cities can tolerate?
I don't think so. Real cluster size depends on central city population (bigger city -> bigger cluster around it).
And it is random.

jamespetts

#33
Inkelyad,

thank you for doing this: however, it appears that the new code has a bug, in that all of the cities generated outside clusters have only a town hall and no city buildings. Do you think that you could look into this? Thank you again for all your efforts in this respect.

Edit: I tried generating without any clusters, and still had some townhall-only cities, so it may not be a clusters issue. Really, there should never be any townhall-only cities at all, as these do not make sense. Perhaps it is something to do with the number of "big cities"?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

City placement go from big city to smaller. Any city outside of clusters will be very small.

'big cities' use 'Median citizens per city' for population (+- gaussian noise).
n-th city after that will use 'Median citizens per city'/n for population (+- gaussian noise again).
(See my posts about Zipf distributions)

It seems city  growth engine think that city hall is enough for population less then ~320.


jamespetts

Hmm. Is there a way, do you think, of making sure that all cities have at least one building apart from the city hall?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

#36
Well, I can hardcode minimum city population.

Better way will be to fix stadt_t::step_bau. But I really don't understand how it should work.

Edit: City hall counts as 4 buildings? Can it be source of problem?
Edit: Most likely it is.
From besch/writer/building_writer.cc:

       } else if (!STRICMP(type_name, "tow")) {
               besch.level = obj.get_int("passengers",  besch.level);
               besch.extra_data = obj.get_int("build_time", 0);


From simcity.h(stadt_t::baue_gebaeude)

       if (h == NULL  &&  sum_wohnung > sum_industrie  &&  sum_wohnung > sum_gewerbe) {
           h = hausbauer_t::get_wohnhaus(0, current_month, cl, new_town);
           if (h != NULL) {
               // will be aligned next to a street
               won += h->get_level() * 10; // woh -- amount with homes
           }
       }


So, from simutrans point of view, people live in city hall.



inkelyad

I have no solution for 'people live in city hall' problem. But I can force cities to have at least one building.
Changes pushed to github.

Second (very small) patch make central part of the new city more dense.

jamespetts

Ahh, thank you! Just trying this now - it seems to work well. Thank you very much for all your work on this.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

We need smaller city hall in pakset. Big stone building does not look right in small village.

inkelyad

Please revert my commit be1798625c3de288d3680374499ef8a3bffda25c ('more dense center'). Sometimes it make almost infinite loop.

jamespetts

Inkelyad,

can you detect those conditions and deal with them instead? This seems to be a good feature in principle.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

It become infinite loop when city can't grow for some reason (i think. It is random condition and hard to debug).

jamespetts

Hmm - one possibility is counting the number of loops and setting an upper limit, after which the program simply breaks away from the cycle. Would doing so cause any instability, or would it just result in a city with fewer buildings than its population would normally merit?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

inkelyad

No, it will not break anything. But cycle limit must be high. Low limit will break 'more dense center' goal.

Further, with current pak128.Britain-Ex and 'obey era' in 18.. this feature does not work as expected -- pak don't have high level buildings for dense center.

So it is better just remove commit. I'll try to invent more smart algorithm later.

jamespetts

This is now incorporated into 9.0.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.