Sprint 24 - Adam-Poppenheimer/Civ-Clone GitHub Wiki
Goals
- The Tradition policy tree.
- The Liberty policy tree.
- The Honor policy tree.
- All wonders up to the Medieval era.
- Golden ages.
- Great people.
Risks and Mitigation
- Social policies and wonders require tons of small mechanical options that'll require tons of small classes and small changes to the codebase. If I'm not careful, those changes could get out of hand and result in a gigantic and hard to understand codebase.
- I'll need to keep searching for ways of defining behavior in data rather than code, or of creating classes that can be repurposed to handle many different types of modifications. I should endeavor to minimize the number of fields per class and the number of classes overall so that I can keep things more manageable.
- Addressing social policies as single tasks results in all sorts of organizational and psychological issues that make it difficult to work.
- I need to break social policies into a bunch of smaller pieces and address those individually, slowly adding functionality to the system and treating each new small piece of the simulation as a separate issue. That should help me focus on the important components of the problem and keep me from glossing over details and ignoring test cases. Plus, having the little green bar increment more often should help with morale.
Review
I began this sprint of policy and small mechanics development by implementing free buildings that certain policies in the Tradition tree provide. This turned out to be a fairly complex task that took more than a day to resolve. The fact that the policies can apply retroactively, giving free buildings to cities constructed after the policy is unlocked, made it more complex than I had first thought.
After that, I extended production bonuses from policies so that designers can provide conditions that must be met (the project is a wonder, is a building, is a military unit, etc) for the bonus to apply.
After that came a handful of smaller tasks: creation of free units from buildings and social policies, the policy cost modifiers from policies, and building creation from buildings (separate from the free buildings issue of policies). All of these were fairly straightforward.
I spent a bit of time establishing CapitalConnectionCanon, which determines if a city is connected to its owner's capital. I then made use of that new implementation to enable policies to provide happiness bonuses from capital connection.
I then mowed through a few tasks that I thought would be a lot more difficult than they turned out to be. The generation of great people from buildings and social policies turned out to be fairly straightforward, and my new Modifiers classes made global growth from buildings a lot easier than anticipated.
From there I continued to iterate on the notion of city and civ modifiers to facilitate all the little mechanics I'd been creating. I used improvement construction rates in buildings and policies to improve that.
After a few more minor tasks I moved on to golden ages, which all told went fairly smoothly. At first I forgot to serialize golden age progress, turns left, and previous golden ages, but that was a fairly simple issue to resolve.
After golden ages I continued to build out a bunch of smaller mechanics, these ones more specialized and less important than what had come before. At this point ICityModifiers and ICivModifiers were in a good enough state that they were making the work fairly efficient.
Late in the sprint I hit something of a snag while trying to add promotions to policies. Promotions turn out to be a fairly messy and poorly-designed section of the codebase, so I spent the better part of a day reorganizing and trying to clean up the acquisition of promotions.
The last leg of the sprint was focused on implementing great people abilities. All but the citadel came fairly easily. The citadel ended up revealing a bunch of problems with ability execution that I needed to resolve. Apparently AbilityExecuter did not support multiple command requests, or did so in a particularly unusual way. I spent a decent chunk of fairly monotonous time rebuilding that process to support the citadel.
I finished the last issue in the sprint (social policies providing happiness from garrisoned units) early in the final day and proceeded to take the rest of the day off.
Retrospective
What went well?
- I addressed every single issue in the sprint, and did so without much difficulty.
- I've managed to add a bunch of mechanical extensions to my codebase without causing a horrific and tangled mess of code to emerge. Organization in most places still seems fairly solid.
- ICityModifier and ICivModifier (and the implementation pattern they represent) were quite useful and show a lot of promise. I can probably get rid of a bunch of the Logic classes I've been using by carefully applying this pattern to them. At the very least I've got a more data-driven way of defining new modifiers and new behavior on several important classes.
What could be improved?
- I'm not convinced that the issues I've been attending have been the most important things to work on. I think I need to reconsider my long-term priorities and focus on other, larger problems. At the very least, I'd like to know what's important to finish the game.
- I have a sneaking suspicion that my unit tests are becoming less rigorous and thus less adequate at ensuring correctness. I'll need to be vigilant for possible bugs that emerge from incomplete test coverage.