Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: setting for more flexible town spacing #7745

Draft
wants to merge 1 commit into
base: master
from

Conversation

@Eddi-z
Copy link
Contributor

Eddi-z commented Sep 16, 2019

This is an old patch i found on my disk, from around 2011, that i don't remember how complete it was

It allows more flexibility in specifying road layouts by setting the minimum distance between parallel roads in either a "natural" (randomized) or a "grid" (fixed) pattern

during rebasing, i kinda fudged the AI bits, which were not present in the original patch. there probably needs to be some kind of compatibility layer, which i have no clue how it works

@Eddi-z
Copy link
Contributor Author

Eddi-z commented Sep 17, 2019

a screenshot made with a simpler version of the patch:
screenshot1

old forum discussion: https://www.tt-forums.net/viewtopic.php?p=982943#p982943

@Eddi-z
Copy link
Contributor Author

Eddi-z commented Sep 17, 2019

What's definitely missing is a rework of the scenario editor gui for selecting road layout

@nielsmh
Copy link
Contributor

nielsmh commented Sep 17, 2019

This is totally an OpenTTD 2.0 feature (by which I mean we should merge it ASAP and call the version 2.0)

@andythenorth
Copy link
Contributor

andythenorth commented Sep 18, 2019

Tested with min 4, max 6.

Results from a few random new maps are compelling. I didn't run a long game yet to see results as towns grow.

Observations

  • looks better IMO
  • doesn't create enough gaps to trivially build rail stations or smaller airports in towns (I think this would be useful, but maybe hard to achieve)
  • does create enough gaps to ease building tunnels, bridges, rails, RV depots etc in towns
  • I noticed in rare occasions, 1x1 buildings placed with no adjacent road tile, I wasn't sure if that was intended

Related idea, it would be helpful if towns built more bridges of n+1 or n+2 length instead of n. Town bridges tend to be a constraint that block potential routes, and they're non-removable. Creating bridge spans over empty tiles allows routing under the bridge, makes river corridors a viable route into towns. Case could even be made that it's realistic (flood arches) 😺 I put a crude 'delta + 1' hack into GrowTownWithBridge, which works for NE-SW direction only, appears to break bridges for other directions, out of my depth here. Would be a different PR anyway.
bridge_n_plus_1

@Eddi-z
Copy link
Contributor Author

Eddi-z commented Sep 18, 2019

* I noticed in rare occasions, 1x1 buildings placed with no adjacent road tile, I wasn't sure if that was intended

that does not sound like anything this patch should cause, so this is likely existing master behavior

@nielsmh
Copy link
Contributor

nielsmh commented Sep 18, 2019

I've seen mentioned that if a 2x2, 2x1, or 1x2 building is replaced with a 1x1 building, the 1x1 building is always in the top corner of the replaced building, which may be away from a road.

@andythenorth
Copy link
Contributor

andythenorth commented Sep 18, 2019

I've seen mentioned that if a 2x2, 2x1, or 1x2 building is replaced with a 1x1 building, the 1x1 building is always in the top corner of the replaced building, which may be away from a road.

Non-issue for this PR then 👍

@Eddi-z
Copy link
Contributor Author

Eddi-z commented Sep 18, 2019

Note that i am touching some code containing calls to "GrowTownWithExtraHouse", where "extra house" means "fill in the middle of a 3x3 grid", which would not directly touch any roads. IIRC this requires roads on at least 3 sides, 1 tile away.

case TL_3X3_GRID:
if ((grid_pos.x & 3) < 2 || (grid_pos.y & 3) < 2) return false;
case TL_GRID:
grid_pos.x = Mod(grid_pos.x, t->spacing + 1);

This comment has been minimized.

Copy link
@LordAro

LordAro Nov 2, 2019

Member

Not a fan of this weird mod thing. Why is it that % doesn't work / produce desirable results ?

This comment has been minimized.

Copy link
@Eddi-z

Eddi-z Nov 2, 2019

Author Contributor

% rounds towards 0, whereas this Mod function rounds towards -infinity, which does different things for negative numbers.

using plain % would thus create special cases

@andythenorth
Copy link
Contributor

andythenorth commented Nov 2, 2019

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.

7745_3

7745_1

7745_2

@LordAro LordAro added this to the 1.11.0 milestone Nov 23, 2019
@floodious
Copy link

floodious commented Jan 7, 2020

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.

Realism

Realistic city blocks are almost never square, but rather tend to be strongly (10 to 1 or more?) biased
in one dimension and rectangular. For example there are two common older mid 20th century North American layouts, very abstractly sub-dividing them into whether alleyways "service/access lanes" are placed between roads, streets and avenues.

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.)

https://www.vox.com/2016/11/14/13275486/streets-roads-avenues-names-reasons

Here's an example from "Garden City" in Detroit, MI (no alleyways) (12x2 blocks.)
https://www.google.com/maps/@42.3160081,-83.3396002,2483m/data=!3m1!1e3

Here's Corvallis, OR (alleyways) (looks like 2x6 blocks with some double-width properties.)
https://www.google.com/maps/@44.562329,-123.2688142,266m/data=!3m1!1e3

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:

  • block = 6+1 (ave) x 2+1 (street) = 7x3 (tiles)
  • neighbourhood = 2x2 (blocks) = 14x6 (tiles)
  • section = 2x2 (neighbourhoods) = 28x12 (tiles)

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.

SQGSTown.DefSQConst(engine, ScriptTown::ROAD_LAYOUT_2x2, "ROAD_LAYOUT_2x2");
SQGSTown.DefSQConst(engine, ScriptTown::ROAD_LAYOUT_3x3, "ROAD_LAYOUT_3x3");
SQGSTown.DefSQConst(engine, ScriptTown::ROAD_LAYOUT_NATURAL, "ROAD_LAYOUT_NATURAL");
SQGSTown.DefSQConst(engine, ScriptTown::ROAD_LAYOUT_GRID, "ROAD_LAYOUT_GRID");

This comment has been minimized.

Copy link
@nielsmh

nielsmh Jan 8, 2020

Contributor

Perhaps needs some compat.nut stuff for Squirrel, to allow creating and querying towns with the old interface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

5 participants
You can’t perform that action at this time.