Sprint 16 - Adam-Poppenheimer/Civ-Clone GitHub Wiki

Goals

  1. Some passable form of map generation

Risks and Mitigation

  1. Procedurally generating maps is something I've never done. That lack of experience could hurt me substantially.
    • Luckily the hex map guide I've been using has sections on procedural generation of maps. I can start there to get a basic sense of how such things are supposed to work. If that's not sufficient, I can spend some time looking for other techniques that people have used. I suspect this sprint will primarily be a learning experience and I should treat it as such.
  2. While the hex map guide I've been using up to this point has several sections on map generation, it's not clear how well they'll apply to my current implementation. I have changed a lot of what I've taken from that guide, which means its solutions might not produce good results.
    • There are some fundamental things from the guide I'll definitely need; building continents, simulating a water cycle, and determining biomes will all be important. The basic logic for rivers and vegetation I can almost certainly make use of. Elevation will be less useful. If it turns out that the guide's implementation doesn't work as a good base, I can always look for another solution. I'm sure there's more information on procedural generation of maps. Maybe I can find out how Civ 5 does it.
  3. Generating maps will require more than distributing continents. I'll also have to figure out how to distribute terrain shapes, vegetation, specialty resources, and player starting locations. That'll require policies for distribution and figuring out how to implement those policies, both things that I do not have at the moment.
    • There are a couple of things I can do here. For starters, I can study Civ 5's map generation for ideas about how it does what it does, what its priorities are, and whatnot. I can look for more specific information online. At the end of the day, I don't need my map generation to be perfect, and I can build it in steps. I can start with a fairly rigid template for nearby hills, forests, luxury resources, and strategic resources and make it more sophisticated from there.
  4. Generating a large map is going to emphasize the severity of my performance problems. It's entirely possible that even simple maps have such poor performance that I can't work with them efficiently.
    • The performance problems will have to be addressed one way or another. If anything, random map generation will give me a much better sense of where those problems arise and how I might solve them, since it'll produce more typical results I can use as a benchmark. Probably I'll defer such performance considerations until next sprint, but if they start getting too severe I can set aside map generation and work on improving performance. The important thing is to prioritize work. If performance becomes a higher-priority issue that more sophisticated map generation, then that's what I should be working on anyways.
  5. Generating a good map will require understanding how to set up good starting locations, hinterlands, regions of conflict, and whatnot. It'll be intrinsically tied to the design of the game. I do not have a very thorough understanding of Civ 5's design, which might make it very difficult to come up with reasonable solutions.
    • While I don't know how Civ 5 was designed, I have played it for hundreds of hours. My familiarity with it is one of the reasons I chose to clone it. I can spend some time studying Civ 5's randomly-generated maps, trying to figure out how they function. I can also spend some time looking for talks or lectures on 4X map generation more generally to give me a sense of what I need to worry about. And of course I can build it in stages. More important than building a balanced map is building any map at all. I can slowly add more complexity as time goes on.

Review

I spent the first half of the sprint implementing the map-generating solution presented by the Hex Map Guide that I've been using. This involved creating a semi-realistic topology, water cycle, and temperature simulation. After implementing that, it became clear that it didn't give me enough control and didn't produce results good for the mechanics of the game. I then proceeded to build something completely different.

The rest of the sprint was experimentation. My main priority became control. I wanted to create a system that could be configured to produce very precise results, for instance by insuring a certain percentage of a starting location be grassland. I have a somewhat generalized region and continent generation system that achieves those goals to some degree. Map generation itself is brittle and needs work.

Currently, users can generate maps that consist of four small continents, each intended to have two players. These continents consist of a pair of starting regions with a boundary region between them. Continents pseudo-randomly generate ratios of various terrains, shapes, and vegetation based on a number of configurable policies. Map generation does not currently include rivers, resources, or starting unit placement. There is a single template for starting locations and three for boundary locations, which continent generation randomly selects between. Generation doesn't correctly apply fresh or shallow water and has no policies for assigning these terrains.

While generated maps attempt to follow the instructions provided by their configuration data, generation will often violate those restrictions. The creation of snow and tundra regions especially can severely compromise terrain percentages and lead to highly unbalanced starts.

As expected, there are performance problems due to the number of trees. These problems do not currently make the game unplayable for most generated configurations, but they are an issue that needs addressing.

Retrospective

What went well?

  1. Despite my lack of experience with procedural map generation, things are going quite well. My custom solution is already producing interesting results in a (relatively) clean and organized way.
  2. Generating maps has given me a much better sense of how all my visual elements interact with each-other. It's helped to show me what is and is not working in ways that my own testing never could've.
  3. I have a clear understanding of the problems facing map generation and have lots of ideas for how to fix them.
  4. I'm more excited about the state of this project than I have been in months. Seeing all the work I've been doing, especially the graphical work, finally coming together into a cohesive thing has me in good spirits.
  5. Even just a week of programming has given me a pretty good start for a custom map generation system. It's fairly generalized, highly data-driven, and parts of it have pretty decent architecture even at this early stage in their development.
  6. Working on procedural map generation has piqued my interest in this field of study. I suspect this will not be the last time I attempt to generate worlds through code.

What could be improved?

  1. I still haven't taken a thorough look at how Civ 5 does map generation. I really need to reinstall that game and study its products to inform my own implementation. I'm sure that'll be very enlightening.
  2. It's becoming clear that I need trees along cell edges, not just scattered throughout the middle of cells. That might require reworking feature placement.
  3. My current way of generating continent outlines and topologies is not brilliant. It's not efficient nor extensible, and it doesn't provide me the sort of control I'm looking for. I need to completely rework how continent shapes are determined and how oceans are declared.
  4. I need a better way of determining tundra and polar regions. The current system has the potential to severely degrade certain starting regions, especially when the continents are vertically-aligned.
  5. The continental subdivision I'm using will occasionally produce continents where the boundary region doesn't really separate the two starting regions. I need to change subdivision to make sure that boundary regions more consistently separate starting regions. If I want adjacent starting regions, I can set that as a policy elsewhere.
  6. I'm going to need to spend a lot more time fiddling with configuration values to make acceptably good regions.