News:

Simutrans.com Portal
Our Simutrans site. You can find everything about Simutrans from here.

Cannot create new maps

Started by Matthew, Yesterday at 05:06:17 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Matthew

Steps to reproduce:

1. Start the new game using the latest (2026-09-17) Nightly executable with pak128.Britain-Ex.
2. Try to create a map with default settings.

Expected result:

A new map is created.

Actual result:

After ten minutes, the game is still frozen.

A Discord user reports (on Windows):

QuoteIn log, the last entry is
Message: simmain():    Creating cities ...
Warning: stadt_t::random_place():    Not enough places found for cities.

I couldn't replicate that error message on Linux, but maybe my logging level wasn't low enough.

Observations
The bug has been reproduced on both Linux (SDL2) and Windows.

The bug does not occur using the Linux (SDL2) executable created by the last commit in the ci-repair branch, available from GitHub Actions.
(Signature being tested) If you enjoy playing Simutrans, then you might also enjoy watching Japan Railway Journal
Available in English and simplified Chinese
如果您喜欢玩Simutrans的话,那么说不定就想看《日本铁路之旅》(英语也有简体中文字幕)。

martin509

Github issue created here with some concrete suggestions for solutions (the code cause is unknown but the root cause is almost certainly an AI bot being let loose on production).

In my case, the log filled with messages about creating dirt roads (since the date was 1750) and then stopped logging at all while the game hung.

Isaac Eiland-Hall

I think it might make sense not to speculate about the nature of the cause until the cause is found.

jamespetts

Thank you both for the report - now found and fixed in the latest CI builds (and the server's nightly builds should have the fix to-morrow). 

I am in the process of setting up a new automated map generation test to run with the CI to prevent this sort of failure from occurring in future. 
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.

prissi

I think threaded code should never alter the objlist or the whole threading becomes pointless since you are using a global semaphore. Either each objlist gets their own semaphore (might be a memory overhead of a byte or more per tile) or that part of threading code altering the map needs to be fixed. Because, with a global semaphore (like included in your atomic statement) the code would mostly wait for other threads whenever accessing the objlist, negating all threading advances.

(Unless I got this wrong, somehow, the verbose commetns and multiple defines do not really help to make it very clear).

martin509

#5
Progress so far! The mapgen hang seems fixed and it's no longer impossible to generate a map.

However way building seems much slower than usual, and fills the log with identical messages about way_builder_t::init_builder(). Generating a large-ish map with 50+ cities takes >10 minutes.

martin509

Quote from: prissi on Today at 04:51:37 AMI think threaded code should never alter the objlist or the whole threading becomes pointless since you are using a global semaphore. Either each objlist gets their own semaphore (might be a memory overhead of a byte or more per tile) or that part of threading code altering the map needs to be fixed. Because, with a global semaphore (like included in your atomic statement) the code would mostly wait for other threads whenever accessing the objlist, negating all threading advances.

(Unless I got this wrong, somehow, the verbose commetns and multiple defines do not really help to make it very clear).

After a lot of puzzling over this I think I'm finally on this same page. Previously for whichever reason there were massive and benign race conditions everywhere in code, and now that the bot solved these, mapgen is effectively singlethreaded and bottlenecks massively on its most parallel task, building ways (rivers and roads).

The obvious naive solution I think would be switching from a single semaphore to a list of hazard pointers, since while there are hundreds of thousands of objlist objects, there is a much smaller number of threads and therefore it would avoid memory overhead while allowing multiple objects to be accessed simultaneously. However this would involve ripping apart some very low-level and important code, it would have to avoid deadlock, I don't actually know how many threads Simutrans runs (is it just the CPU thread count or is it hundreds?) and I don't have nearly enough multithreading knowledge to be confident about anything I say about it.