Sprint 23 - Adam-Poppenheimer/Civ-Clone GitHub Wiki
Goals
- Great People generation.
- All wonders up to the Medieval era.
- The ability to spend culture on social policies.
- All social policies up to the Medieval era.
- The notion of a city being connected to its owner's capital, which can affect civics.
- Golden ages.
- More obvious and formal exchange of turns.
- The ability to hover over values in the UI (like yield, happiness, etc) and get a breakdown of how they were calculated.
Risks and Mitigation
- Social policies require a bunch of unusual modifiers that the game does not currently support, even more so than wonders. Adding all of those unusual modifiers in an ad-hoc fashion could cause code bloat and might make it difficult to extend things in the future.
- It might be time to build a more rigorous solution for things like city yield and city happiness. Instead of calculating yield by gathering together all of the disparate sources and processing them, I might consider inverting the dependency. I could define a more generic CityYieldLogic class (for instance) that accepts the addition and removal of various modifiers (percentage, base, additions, and whatnot) and then have my buildings, cells, policies, and whatnot subscribe various modifiers to the appropriate cities. That way any element of the game could, without much difficulty, be extended to change city yields without forcing CityYieldLogic itself to change. I could at least look into that.
- I have no way of implementing either the Patronage or Piety policy trees, since I have neither city states nor religion (and have no plans to add either of these features to the game).
- Losing those policy trees, while unfortunate, is not the end of the world. I'll probably be developing these policy trees one at a time, so I can start by creating the ones I know I'll include. Patronage and Piety replacements can be stretch goal later in development.
- None of my calculation classes provide their consumers with information about how the value was calculated. Since I don't want normal calculations to incur the overhead of introspection, I'll have to create parallel methods for all the calculations I want to provide breakdowns for. That could cause unpleasant code duplication that could lead to inconsistencies and all sorts of annoying bugs.
- I might be able to resolve this by subdividing my logic classes into smaller private methods that my big public calculations call into. Then I can add "Summary" methods that call into the same private methods but provide different sorts of information. I might also be overestimating the importance of performance here. It's entirely possible that eagerly calculating a summary when only a value is needed is fine.
Review
I began the sprint by trying to address problems with starting a new game. Though I'd anticipated that issue being fairly simple, it turns out that I hadn't properly merged civilization templates into the Master branch. When I attempted to merge that old branch in, it caused a ton of merging errors that I had to meticulously pick apart. I ultimately settled for a half solution, one which guarantees that new games start without problems but which doesn't ensure that every civilization is unique.
Next, I moved into great person generation. This task turned out to be far larger than I'd anticipated and should've been separated into a large collection of subtasks, maybe even given its own sprint. I spent a bunch of time working through the infrastructure, determining how great people are born and how they're costed, and then implementing the specific great people I wanted in the game. Ultimately I terminated this issue after ~3 days of work before it was completed. Instead I separated the least-critical components I had yet to implement into their own issues and moved on to more important things.
After great people, I began working on the Tradition policy tree as a single issue. I managed to get most of the tradition tree done, establishing a number of classes to add functionality to social policies before I stopped working. I'm not convinced that the code I created for the Tradition tree is particularly robust, either.
Some combination of Thanksgiving and extraneous life events burned away a lot of the productivity of this sprint. Even just the hours committed were far below what they should have been, and many of the hours that I did commit were done with a distracted and inefficient mind.
Retrospective
What went well?
- I managed to add great people to the game without too much difficulty.
- My yield system proved robust enough that adding 4 new yield types (for each of the civilian great people) wasn't a difficult or tedious task.
What could be improved?
- I did not anticipate the effect Thanksgiving would have on my ability to work. The fact that everyone around me was taking time off and spending time relaxing with their families created an impulse to relax stronger than I could resist. I should be more careful about scheduling work around the holidays and avoid getting my sprints anywhere near big holidays, since I'm unlikely to be very productive then.
- All of the major issues in this sprint were far, far too large. Their size and scope made it hard to focus, decreased the standards to which I was programming, and severely affected my morale. I need to take these social policy tasks and divide them up into much smaller pieces, one for each of the new mechanics or mechanical alterations I'll need. I should also have done that with great people.