Feature: setting for more flexible town spacing #7745
I experimentally increased MAX_TOWN_SPACING to 12.
I think it's of benefit when player wants grid layouts with space for infrastructure. Examples attached showing grids with min 8 and max 12. There were no really pathological examples when I tested.
Obviously the centre of towns looks odd, as large buildings are adjacent to empty green space. But that can be avoided by choosing lower grid spacing. Player choice eh.
For the natural town layout, increasing the grid spacing is a neutral choice. Towns work fine, there's no real gameplay benefit for spacing 8 or 12 compared to 6, and no pathological effects.
For the grid layouts, the improvement I see is for players who want to build metro / urban train networks, where the empty areas can accommodate short stations and tunnel entrances etc.
This is all very interesting stuff openttd is in my opinion/experience desperately in need of.
Issue with single-scope planning
At current larger grid divisions there is no way for a town to "fill in" the space between major divisions. The buildings only appear within fixed distance from roads. So it requires some hierarchical sub-division planning to fill those voids as neighborhoods, parks or natural (forest, ...) spaces.
Realistic city blocks are almost never square, but rather tend to be strongly (10 to 1 or more?) biased
These decisions are almost always up to local municipalities... but generally speaking you start out with cheap-to-build roads dividing larger sections. These long-straight roads snake around large obstacles and connect industries and farms to population centers.
The municipality then decides on a grid-filling layout which might include some specification for high-traffic avenues or mid-block service lanes dividing different classes of city blocks. (Industry, commercial, residential at the most simple abstraction.)
Examples from the real world (NA, different places in Europe or elsewhere have different styles by region.)
Here's an example from "Garden City" in Detroit, MI (no alleyways) (12x2 blocks.)
Here's Corvallis, OR (alleyways) (looks like 2x6 blocks with some double-width properties.)
A residential layout may include straight rectangular blocks, or more modern suburbs tend to be built with heavy (double one-way) commercial avenues dividing main streets on a coarse grid and smaller court or place lanes within smaller neighbourhoods with cul-de-sacs and similar. This is because the large-scale rectangular grids look awful and tend to produce traffic and other problems (service distribution, crime, large-scale planning issues, ...)
Practical implementation for openTTD
While this goes really beyond over complicated for something like openttd, it's rare to see endless grids of perfectly square blocks outside larger grids of streets, within larger grids of avenues. So in the very least it would make sense to have multiple layers of planning... in the least a plan might include specific dimensions for residential and commercial blocks rather than a single dimension and single grid. From some fixed plan for the larger neighborhood/district grid (X x Y) various sub-types could be selected randomly (2/3rd common, 1/12th * 4 rare?) for rows or columns within each.
Due to limited by-default selection of road type in openTTD, features like parkways, avenues and alleyways are all limited to being represented by one road type. So for that reason combined with the fixed tile grid it does not make sense to feature high-res details like alleyways.
A practical example might be:
The lanes/roads would then be initially run out at a grid spacing of 28x12. Each town would begin with a single road intersection in the center of 4 sections, 16 neighbourhoods and 64 blocks.
(... removed some vaguely related rambling about neighbourhood and block sub-types.)
Even with three simple hierarchical layers I can tell it would be easier to understand with some graphical representation... such discussion might have a better place to occur, I'd like to come back to this post and move 99% of it to a feature-request or planning thread instead linking both ways. That improved description of the idea would get some bitmaps to visualize my descriptions.
Many municipalities develop very slowly over time, where sections of such a plan are added one-by-one in single neighbourhood units, or at larger scales towns = "districts". From a planing perspective these blocks are typically fit around obstructions like hills or cliffs (any change in Z in openttd.) The origin of the large-scale dividing roads in many plans and the source of names also come from historic destinations like "Timothy Station Rd." or "Olhamm Farm Rd."
That natural evolutionary process is way out of the scope of openttd currently, so the question is how to produce highly-playable approximately real looking results without such a process.
Points of reference
While there is no definite scale in openttd, it is possible to come up with a range of practical scales. A typical lane/street is approximately 20 meters wide, so as a very rough starting point based upon roads we can assume 1 tile = 20 x 20 meters. The scale for buildings on a tile is then weird since a small residential lot is generally rectangular such as 15 x 40 meters, but this is definitely close enough assuming no driveway, no garden space and such 15 x 15 sized homes are typical. That would be 225 sq meters or near 2400 sq feet.
So with confirmation of the rough house + road scale at 20 meter units, we can say a 4096 map edge would be 81.92 kilometers, meaning a 4k x 4k map could reasonably approximate the whole of the city of Detroit if everything were at perfect 90 degree angles.
Such a region could contain 798915 7x3 city blocks, 199728 neighbourhoods and 49932 sections. 7 x 3 x 2 x 2 x 2 x 2 = 336, 4096^2 = 16777216, 16777216 / 336 = 49932.
So this verifies that the 4k scale is way beyond enough to contain towns with such "realistic" block sizes.
We have talked this over a few times now, and I keep coming back to: I really like what this PR does, but I do not think this is the right solution for vanilla OpenTTD.
The thing is, we now make the distance of the grids a setting; it looks cool, but as the comments show, immediately new ideas pop up to improve towns further. And this keeps piling up. Up till what point should this be done hard-coded in C++, and where do we say: someone should make this possible in a "mod" (either GameScript or NewGRF or something new; I have not given that any thought). So despite me liking the result, and it somewhat cleans up some parts of the code too, I think it is the wrong move for OpenTTD to take.
Unless one of the developers thinks otherwise about this, I am tempted to close this Pull Request. I hope someone says: I am going to make this moddable, as that would be straight-up awesome. People can then just invent their own algorithm to grow nice looking towns .. can't wait to see that result :D
I disagree regarding whether towns are a core element of vanilla OpenTTD. I would argue that towns do not work, never worked and the current implementation and the original TT code upon which it was based were temporary stopgap solutions that were never replaced with a working solution.
In that respect the current stopgap can be considered a void. Towns are not currently a functional element of OpenTTD and detract from an enjoyable game more than they add. Industry to industry transport is more or less functional and despite notable issues it works. Transport from an industry to the border of a town (goods, ...) more or less works but can be troublesome when the single building accepting goods, mail or passengers is arbitrarily moved to the opposite side of town by the current code.
Mail and passenger transport between towns is barely functional with no sensible mechanism to reserve space for tracks and construct efficient transportation networks (road, rail, ...) in conjunction with continuous interference from the town AI.
edit: An attempt to clarify;
I would argue that yes, such small improvements are exactly the right solution for OpenTTD unless a specific objection can be made to some part of this implementation. Outright rejection of any improvement whatsoever is also possible.
Towns as they are currently serve one significant purpose that I'm aware of: the base for industries.
The location of a town, roadways constructed by the town, buildings and industries for the most part have no logic applied to ensure their placement makes sense. A town can be constructed on a sharp ledge on the side of a slope and will merrily construct sheer roadways and houses on cliff edges with no planning whatsoever. Various industries are likewise only implementing minimal logic routines such as that used for farms.
The real threat of admitting the core issue with the structure of towns is that they are a void which serves as the foundation for the entire game.
Actually, we did discuss this before.
Putting aside the parts about "we should do this completely differently", one particular part of this PR that i was never content with is the following:
this discrepancy gets annoying if you want to mix grid and natural town layouts
if i were to work on this PR (which i won't, because you said you're going to reject it), i would probably try to change this to:
although dividing by 3 is always a bit awkward.
this should make it less likely that you want different setting values for
This site tends to be more reliable than webster.
Concerning "which part should be C++, and which part mod", this is highly dependent on how we are going to achieve modability, but i feel like the moddable parts should be higher level, like placing "city districts" or something, and a few basic road placement algorithms should be provided in C++, with possibility to implement custom algorithms
Good modular design provides for a reference implementation as a module using the same system as any other module. This acts to verify the modular interface capabilities by application.
How one might go about this task depends upon particularities; nonetheless a functional implementation is required first to determine the requirements of the modular interface. That is to say first you make it work, then you modularize it, then repeat, recurse and so forth.
Well. I could write an essay or a dozen about how a complex codebase with lots of legacy has problems following "good design" principles.
one "legacy" conflict with this design principle is that there is a long standing policy that the game does not get bundled with "mods", even if they would pretty well serve as a "reference implementation". e.g. OpenGFX
the other problem is that, even if a modder can provide custom road layout algorithms, should they have to? someone that just wants to change high-level stuff like how the town reacts to player activity shouldn't have to be concerned where each and every piece of road goes, they should just be able to say "yeah, do whatever vanilla does"
Well, from my point of view there is nothing to discuss regarding modularity. Yes, you're 100% correct with regard to primitive codebases being poorly designed and inflexible, difficult to maintain and impossible to modularize. Modern c++ implementations are fully modular and moving the OpenTTD codebase toward this is I agree something that should be a top priority.
I think this concern with "piling up" is an apparent (although false) conflict between maintaining the original implementation and making it more flexible, adding options and eventually the full modularization of it. So in that respect it must be carefully measured in terms of whether this pull request improves the original code whilst maintaining its original function, or is merely an additional functionality that does not improve the original code.
With that in mind I would point out the fact that the majority of the town AI is not original to begin with; nonetheless it is a valid concern to avoid piling on additions that make the code more complex rather than simplifying it and adding flexibility.
From what I can see this is entirely an improvement, it maintains the original functionality and does not add any excessive new functionality.
As mentioned earlier, and as no dev has come forth, I am going to close this PR for now.
Work for moddable town-layouts is slowly starting up, where the first few drafts of the concept have been made. So at least we have that to look forward to :)
As always, if any of the devs feel I am in the wrong of closing this PR, feel free to open up that dialog! I am just managing expectations here, to not let PRs open for years on end, where no dev wants to touch it; not fair to the author and not helpful for the community at large.
Nevertheless, as I have mentioned a few times already, I do like the result of this PR, so I do hope we can make it possible soon to implement similar behaviour :D Tnx for the work!