I've had a very ambitious idea in mind for some time now. Ambitious enough that I wouldn't fault anyone for saying it's outright impossible, even though I'd disagree with that idea. It will likely be doable in future Godot versions, but since it's a very distant plan we may as well have Godot 4.0 by the time I'd dream of having a demo released.
In a nutshell, what I wish is to create detailed functional cities; Worlds of the depth and quality as those of the Grand Theft Auto >= IV series. Realistic cities full of details and objects, card driving down roads while respecting traffic rules, pedestrians walking on sidewalks and interacting with their surroundings, and much more. My project actually plans to go further than the detail any GTA game has ever offered: It would allow boarding and walking inside subway / skytram trains, entering random people's apartments, exploring full sewer systems located under roads, etc. Different presets of cities, people, vehicles, items, etc would be defined and possible to mix (present day, futuristic, etc).
There is however a catch... and this is where the crazy part comes in: I also want all this to be procedurally generated, not designed by the mapper as in other games that have this level of detail. When starting a new world, a script will draw the roads, manage the terrain, place the buildings... all using a selection of objects and road segments defining that world. The plan is for cities and characters to always be unique, with players being able to save and share cites by copying the generated file containing them (likely in json format). To add insult to injury, I'm not planning to settle for making those cities flat either: I'll want not only roads that go up and down, but tunnels and bridges that traverse bumpy terrain as well. Crazy I know :)
I already have some ideas in mind about how I'm going to achieve this, based on a similar city generator I once created for the Minetest project (a Minecraft clone). The system would rely on using a 3D gridmap, which by default will be empty and is filled by the script itself... the tiles contain terrain and road pieces, on top of which buildings and other objects would be placed. The rough idea of how this would work is something among the following lines:
- The script starts drawing the roads in 2D space, each road defined as a multitude of cubic segments: The straight I segment, an L segment to steer the road, an X intersection segment, a T intersection segment, a dead end segment, as well as conversion segments to connect different types of road to one another... for height there will be a special straight segment which goes up or down. The script simply starts from one point then draws a random number of segments in a given direction, before deciding whether to steer the road or fork it into an intersection. I don't know if 45* segments could also be supported, as this would add far too much complexity to both the pathing algorithm and the number of road segments needed overall.
- Once a flat version of the road system has been drawn, the system needs to determine the height of each segment. Some straight segments are next converted into the sloped segments mentioned above, which connect upper and lower segments on the grid. Roads will ideally take one of two choices when faced with a height difference: Either go up or down, either continue forward as a tunnel or a bridge. Terrain segments surrounding roads will also have to respect this height, spawning flat planes or slopes or corners accordingly. I imagine the most reliable way is using a perlin noise map but that remains to be seen.
- Now that we have a 3D road and terrain tilemap, we need to know which spaces are free in between roads and what buildings we can spawn there. In every empty patch of terrain, we place a randomly rotated building that can properly fit in between the roads. We also need to place misc objects on road segments themselves, such as street lights and trash cans not to mention vehicle / pedestrian spawners... this will be done by assigning a list of items with probabilities to each segment.
I don't yet know how far this idea can get me. I have alternatively thought of using the new terrain node once it's finally in (I hear Godot 3.2 is the next target) then seeing if I can simply generate the road system in 2D and somehow project it across the terrain surface vertically. What I want is still pushing the limits by far however... namely since cars and peds must know how to navigate those road systems too (trains will need a curve straight out). Performance would be managed by using a smart draw distance limit mixed with model LOD, parts of the world can be (de)spawned in grid chunks similarly to Minecraft.
I'm posting this thread as a discussion rather than a question, since there are a ton of parallel questions that emerge for an idea as big as this one. For the scope of this topic, the primary one remains how I can (ab)use Godot to generate procedural cities using road segments in the most efficient way. I'd like to know if there are any base suggestions on how I'd get started on such a thing, perhaps even some existing demos if anyone has made any! What are your thoughts on this?