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

Goals

  1. Experience and promotion trees.
  2. The ability to fortify.
  3. The ability to pillage.
  4. Unit maintenance.
  5. The notion of fresh water.
  6. The notion of shallow and deep water.
  7. Rivers that run along the edges of cells.
  8. Elevation and water that more closely resembles the base game.
  9. Bugfixing of existing components.
  10. The ability to spend culture on social policies.

Risks and Mitigations

  1. Changing where rivers appear is going to require major changes to the way the terrain mesh is generated. Since that section of the codebase is both fairly complex and very, very messy, that could end up opening an enormous can of worms that'll take me weeks to figure out.
    • The state of the HexMap namespace would be a problem even if I never touched it again. It needs to be extensively refactored and regression-tested anyways. This simply gives me a clear reason to spend time modifying it, which'll make things better in the long run. And the appearance of the map is important enough to justify weeks of work. The simplification I'm planning for the map's representation should help make things easier, as well. If it starts becoming a big problem, I can always take stop-gap measures (like representing rivers as something other than deformations in the terrain mesh) as partial solutions.
  2. Because of what it modifies and how I acquired it, my HexMap namespace has no test coverage. This means that tinkering around in it could create a ton of bugs that I wouldn't immediately become aware of.
    • Since all of the pieces of HexMap I'm going to modify are decoupled from the rest of the codebase, the bugs I'm likely to get will be visual rather than problems with the simulation. That should at least contain the problems, making them easier to find and resolve. As long as I build things out in stages and carefully consider all the edge cases (using the original guide as a starting point) I should be able to avoid most latent visual glitches.
  3. Making rivers run along the edges of cells might make it difficult to define where rivers appear, since they cannot be as trivially associated with a particular cell as before.
    • I can repurpose RiverCanon so that it checks for the presence of rivers based on a cell and a direction. It'll be up to RiverCanon to make sure HasRiver(cell, direction) and HasRiver(neighborInDirection, oppositeDirection) have the same values. I can then check for the existence of rivers in three of the six hex directions for the purposes of building the mesh. For drawing rivers in the map editor, I can search for the nearest edge and either add or remove rivers from that edge. That should be a reasonable first pass.
  4. Many of the social policies up to the medieval era require pieces of the game I've not and might never implement, which decreases the value of implementing social policies.
    • I can set social policies as a lower-priority task, since they're not critical to the core experience of Civ 5. And even if I can't implement all of the policies in Civ 5, I can at least set up the UI, the system for adopting and unadopting trees and individual policies, and whatnot. I can also set up how policy trees are defined, how policy costs are calculated, and how the trees are displayed. Specific policy implementations can be deferred until later.
  5. While I've become more aware of the places in my codebase likely to cause problems, going into the innumerable classes with incomplete test coverage and adding automated tests would take an enormous amount of time. But the ad-hoc testing I've been using to find bugs thus far will become less and less effective at finding problems as the obvious and close-to-startup problems disappear. Thus I don't have a good way of ensuring code quality for classes not already under tests.
    • The most complex and least well-designed classes are the ones most likely to cause problems. Classes with lots of dependencies might have issues at higher rates, as well. One possible way of finding problems is to interrogate the largest and messiest classes, separating them into pieces or maybe even adding test fixtures for them. That might be a good way of prioritizing which classes get tests, which could help make that activity more productive. Thinking about acceptance tests and user-driven tests might be helpful in this regard, as well. Building sample executions of the program will at least give me instructions I can follow to test important use cases.

Review

I made substantial improvements and additions to units during this sprint. I've got a more-or-less functional implementation of unit experience and promotions and have added most of the promotions I expect to be in the game. I've also formalized and expanded unit healing and resolved a few bugs.

Beyond units, I've begun conforming the map of the game to more closely resemble Civ 5. I removed manual control over elevation and added shallow water, deep water, and fresh water as terrain types. Elevation changes are now driven entirely by terrain and shape, which means the map is more or less based on a flat plane. I began but did not finish modifying rivers so that they appear along the edges of cells rather than through their centers. River modifications will have to be deferred to another sprint.

Retrospective

What went well?

  1. I've put units and promotions in a much better state. The mechanical aspects of units are nearly complete and are reasonably well-covered by tests.
  2. I worked my way to a pretty reasonable solution for promotions that's well-organized, sufficiently expressive, and straightforward to test and extend.
  3. I've made slow but still noteworthy progress on redesigning rivers. At the very least I'm able to wrap my head around the geometry at play.
  4. After struggling considerably with river-carving, I managed to pull myself out of a disorganized state, analyze the problem in a more rigorous way, and get myself making progress again.

What could be improved?

  1. I think I've improperly prioritized development of units. It's not clear that I should've implemented, say, Indirect Fire or Charge given all of the other more important things that the current implementation lacks. I need to get a better sense of task priority so that I'm always focusing on what needs to get done.
  2. I spent a lot of time trying to solve the river-carving problem in a fairly ad-hoc manner, which ended up producing poor results. I need to remember to analyze and reduce complex problems before me into their constituent pieces and make sure I know what problems need to be solved before I start solving them.
  3. Given how much I'm struggling with HexGridChunk and map mesh triangulation, I should make sure that I thoroughly comment all of the river-generating code I'm making right now. Otherwise I'll have no idea what's going on if I ever need to work with this code again.