Sprint 15 - Adam-Poppenheimer/Civ-Clone GitHub Wiki
Goals
- Sensible estuaries for rivers when they make contact with standing water.
- A reasonable visual profile for marshes.
- Better terrain textures.
- A smooth terrain with natural-looking hills and mountains.
- Cultural borders that run along the edges of rivers when present, rather than meeting in the middle of the river.
- Version tolerance for saved games and maps, so that old versions of saved games don't throw exceptions and are not immediately invalidated when small changes are made.
- Some sensible way of displaying farms.
Risks and Mitigation
- The shaders for estuaries in the guide's original implementation were quite complex, and I found myself struggling with estuaries towards the end of last sprint. It's possible that I'll continue to struggle on estuaries and waste a lot of time.
- I think I've already managed the triangulation. I can rework the UVs by slowly building up each component of the estuaries one step at a time. Then, once I've got my WaterShore and River UVs working properly I can figure out how to combine them. It shouldn't be that hard. I think I was struggling at the end of Sprint 14 because I was tired and needed rest.
- While I suspect welding my mesh will smooth out my terrain mesh, I won't know for sure until I've done it. And if welding doesn't work, I'll more or less be at a loss as to what I should do.
- My current implementation doesn't look that bad, so even a complete lack of progress isn't that bad of a result. And I can't imagine what mesh welding would do except smooth my mesh out. I'm more worried that it'll smooth the mesh out too much and the whole map will stop looking like much of anything. If the welding doesn't work, at least I'll know for certain that my terrain shader isn't interpolating normals, which is a very specific problem that I should be able to find solutions for.
- My current implementation of culture is messy and inefficient. That could make modifying culture to adhere to rivers a lot more difficult. Not to mention that culture triangulation could get messy between river and non-river edges.
- I know what I need to do. I need to extend my culture triangulation to the midpoint of my cell connections. I'm already triangulating in both directions, so that won't be too hard. Much more complex will be where to pull the culture back to. I'll need to define another set of hex corners so that I can draw a culture gradient even when the whole connection has been taken up. It's also possible that I'm overthinking the rivers case. I could probably get away with letting my culture cut off rivers near connections. Civ 5 doesn't seem to terminate its culture at rivers, preferring to give the river entirely to one side or another. So I might be able to avoid fiddling with corner connections, which are by far the most complicated part of triangulation.
- It's not entirely clear how I might adhere farms to the terrain mesh, especially since farms in Civ 5 have somewhat complex visual behavior. Figuring out and implementing a policy could take an inordinate amount of time.
- Incremental changes are the name of the game here, I think. I can add a Farmland mesh that sits above the terrain and probably below roads. I can then draw a few rectangular patches of farmland in the middle of this mesh that align with the terrain grid. I don't need to worry about continuous stretches of farmland, or farms along the edges of cells, for the first pass. I can elaborate on it later.
- I'm not sure how I'm going to make marshes work. It's not clear if I should use a marsh texture, if I should have marsh-like features, if I should perturb the terrain mesh, or what.
- It turns out marshes in Civ 5 aren't nearly as inundated with water as I'd expected. They don't seem to interact much with nearby coasts and lakes, so my solution probably doesn't need to either. I'll probably need some way of blending between the given terrain texture and some water texture, which should probably be shiny to make it look more like water. I can probably a texture blending logic similar to what I'm using to blend terrain types together. I'll need to blend it across the entirety of marshy cells, and I'll need to use some sort of sampling texture to select between the water texture and the terrain mesh, but I think the guide I've been using has a tutorial I can repurpose.
- Making hills and mountains look more rugged and natural might require either normal maps or a much more complicated triangulation. Given that I tried and failed to add such things before, it's not clear that I'll be able to apply such solutions now.
- Normal maps failed before because I wasn't welding my meshes properly. I can try using normal maps again once I've made the terrain smoother. I'll need to repurpose my pseudo-random sampling to make sure the normals don't just cause random noise. If that doesn't work, I know there are other, more sophisticated alternatives to bump mapping that I can try out. I should defer modification of the terrain mesh as a last resort, since doing so will make roads a lot harder to implement. I can always apply my bump mapping to my roads in the shader, but adding additional triangles will force me to rework road triangulation.
Review
I've made a lot of progress on better incorporating water into the visual profile of the game. Estuaries are working again and looking fine. I have an acceptable solution for marshes that took surprisingly little time to implement. River surfaces and especially river corners are looking a lot better. I've also fixed some visual glitches and finally put my terrain textures in a better place. Plains, tundra, snow, and mountains now finally look like what they should look like.
I've made some progress on smoothing out my terrain mesh. It turns out this task will be an ordeal larger than I'd anticipated. I've figured out how to weld my mesh together, but that's just revealed shortcomings of my texture and visibility system. Welding was sufficient to smooth out the middle of the cells, but index and weighting inconsistencies make it either very difficult or impossible to weld vertices that lie between multiple cells. Right now I'm selectively welding the center of cells and tried to smooth river troughs, as well. If I want to smooth out the rest of the terrain surface, I'll need to come up with a completely different solution for associating cell data with vertices and fragments.
Retrospective
What went well?
- I came up with a pretty decent solution for marshes surprisingly quickly. I managed to apply an altered version of my open water shader, a splat map, and an additional HexMesh to add splotches of water to the map. It even plays well with all of the other terrain features.
- I managed to get a fairly solid estuary solution that applies sensibly to corners. Even though it had a lot more complexity than the solution the hex map guide proposed, I was able to apply its lessons to my own case efficiently.
- Rivers are finally in a good place. They interact well with open water, hills, mountains, and each-other.
- I managed to present at least a reasonable solution to the river corner problem. I figured out how to animate my UVs in a curved fashion across a single triangle. I'm not confident that my solution is efficient, and I suspect I'll need to tweak it to make it look good, but I did manage to resolve a problem I once thought was beyond my capabilities.
- I finally addressed a months-old terrain mapping issue. Cells now have terrains that look like what they're supposed to look like.
- Mountains and hills look a lot better now, though their new-found smoothness doesn't quite match with the polygonal nature of the rest of the map.
What could be improved?
- I think I over-prioritized fixing my cultural boundaries. As soon as I started working to improve culture triangulation I began to feel like I was wasting my time. I think I need to deprioritize culture interaction with rivers for now.
- While I'm satisfied with the results of my waterfall triangulation, the process by which I arrived at it was very inefficient. I got stuck in a set of false assumptions that led me to waste a lot of time traveling down a fruitless path. When I encounter difficult problems in the future, I should more aggressively back out of current assumptions when I get stuck. This probably means I should take breaks quicker and reason about the problem more carefully sooner rather than later.
- I think I spent too much time concerning myself with small and relatively unimportant pieces of important problems. There were several times when I caught myself worrying about UV or terrain triangulation that probably won't be visible to the player. I need to be more careful about focusing on important tasks. More specifically, when I start trying to improve on something, I shouldn't spend hours trying to make that part perfect. Instead I should iterate on it, making it look better up to a point before moving on to more important tasks.
- If I want my terrain to look smooth in places, I'm going to need to come up with a better cell indexing solution. I don't think I can assign indices and weights in the triangulation code, since doing so screws with my mesh welding. Instead I'll need to assign weights and indices post-weld, probably by checking the XZ positions of vertices.
- I ended up solving some of my river problems by substantially decreasing the amount of vertical noise present in the map. That has left the terrain looking less natural. I'd probably benefit from spending a bit of time fiddling around with various levels of noise, so I can get something natural-looking that doesn't severely impact my rivers.
- My use of Git branches remains somewhat messy. I need to be more disciplined about splitting off separate branches for each type of task. My half-baked cultural improvements, for instance, should be on their own branch separate from the more completed products of Sprint 15. If I had done that, I could've easily pushed to Master all the parts of Sprint 15 that are ready for integration. Instead I'll have to spend some time before Sprint 16 begins extracting my cultural solution from everything else.