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

Goals

  • The notion of explored and unexplored cells, with the ability to suppress exploration for the map editor.
  • The ability to raze cities when capturing them.
  • The ability to fortify.
  • The ability to pillage.
  • Unit maintenance.
  • The destruction of civilizations that have no cities or settlers left.
  • The concept of world wonders.
  • The concept of national wonders.
  • All wonders up to the Medieval era.

Risks and Mitigation

  1. Adding world and national wonders will require me tinkering around in a very old subsystem. That subsystem might not be well-designed enough to facilitate the sorts of extensions I need.
    • A quick inspection of Cities.Buildings and Cities.Production reveals some perhaps poor design decisions. BuildingProductionValidityLogic in particular has a fairly large method that ought to be split into pieces. Luckily there's only two areas of complexity for wonders: whether they're valid, and what happens when a wonder is completed. The former process is encapsulated entirely within BuildingProductionValidityLogic, so I should be able to implement that without interfering with other parts of the codebase. The latter can be handled partially by production validity and perhaps by continuously checking the validity of a production project every turn. Alternatively I can have events that trigger when a wonder is completed to abort projects with the same building template as it. I'll need to establish the notion of aborting a production project, in that case. If there ends up being more complexity I can always re-organize specific pieces of the codebase as that reorganization becomes necessary.
  2. Wonders are very mechanically complex objects. A lot of them add bonuses that the design cannot currently support. Trying to address all the specific needs of all the wonders could end up making the design incredibly messy.
    • There are a lot of wonders that I simply can't implement. Borobudur, for instance, can't exist because I don't have religion in the game (and probably never will). The Hagia Sophia won't do much because I don't have great people. I can't really complete world wonders task at the moment. What I can do is address each wonder and its mechanical needs as its own issue. The specific implementation of wonders isn't particularly important to the wonder system itself (or the wonder extension to buildings). It might be sensible to set wonder implementation as a low-priority task, since it's likely to create ballooning complexity. The national wonders seem simpler, as well. It might be wise to work on those first.
  3. The destruction of civilizations while the game is playing could introduce problems (particularly memory leak) that are hard to detect and diagnose.
    • I've been creating and destroying civilizations for quite a while now whenever I enter and exit play mode. It's caused issues that I've mostly addressed. I don't know if it's leading to memory leak, but memory leak isn't a priority right now. I highly doubt this'll become much of a worry.

Review

I began the Sprint trying to implement exploration by following the appropriate section of the Hex Map Guide I've been using throughout the project. While its solution was very helpful, it turned out my codebase had a lot of extra complexity that needed to be addressed separately. The shaders in particular took a long time to resolve. But I did manage to apply exploration to (to my knowledge) everything it ought to. I also ended up resolving some visibility bugs in rivers that had been around for quite some time.

After exploration, I moved on to some important simulation tasks, namely razing cities and causing civs to lose the game. The implementation I built was an acceptable first pass, but neither of them are in the state they ought to be. Civ defeat, in particular, doesn't have any UI elements that indicate a civilization has just been destroyed.

From there I addressed some miscellaneous but important issues. I spent some time figuring out to reposition the camera intelligently on game starts and new turns, which turned out to be much easier than I expected. I also knocked out unit maintenance and unit fortification, two issues that've been floating around for months that I've finally addressed.

Following those miscellaneous tasks, I started in on national and world wonders. I started by reorganizing BuildingValidityLogic, splitting it into a bunch of smaller classes that check for specific conditions. Once I'd separated out my validity logic, I spent a bunch of time working through the complexities of when a particular player can construct a wonder and what happens when a wonder is constructed. That took a lot more time than I'd anticipated.

After fleshing out the basics of wonders, I spent some time resolving bugs. I resolved some refreshing issues in production and city displays, fixed some instantiation and state machine errors with city combatants, and changed city summaries so that they, too, were sensitive to the exploration state of the civ. I also suppressed city summaries in the map editor and cleared unit pillaging of improvements, another old issue I wanted to clear out.

I finished the sprint with a bunch of wonder implementation tasks. The framework I had built, after all, didn't include any particular implementations of national or world wonders. I started with the palace, which had a whole series of complications. That required an extension of building production, of capital city logic, and the addition of building destruction. Next I threw together some of the simpler national wonders, which required adding civ-wide building prereqs.

Then I extended the promotion and building systems to let buildings provide global and local promotions to units, since that's something several wonders and buildings require.

Finally, I added the ability for a civ to take free technologies, both from a simulation and a UI standpoint. I repurposed TechTreeDisplay so that it could be used not just for setting tech queues, but also for defining discovered techs (in the editor) and for choosing free techs (during play).

Retrospective

What went well?

  1. I got through the whole sprint, which included a substantial number of important changes and additions.
  2. My solution for setting techs and acquiring free techs is fairly clean. It'll make it a lot easier to set technologies of particular civs in the future.
  3. I've got a solid base upon which to build new wonders, and have a reasonable plan for dividing wonder implementation into sensible pieces.
  4. Despite the added complexities of my codebase, I managed to get exploration working fairly well and know how to apply it to other elements in the future.

What could be improved?

  1. Civ defeat needs to be announced with much greater fanfare. Right now it just sort of happens, which can be a bit disorienting.
  2. I've got some ideas for resolving all the errors my program throws when I exit playmode, but applying them might require changing how runtime clearing occurs (I might need to use immediate destruction, for instance).