I missed last week’s Sharing Saturday post due to the most bizarre event. I had to pop into work, and as I was unlocking the door a mostly-naked girl ran up asking for help. I got her covered up, and as I tried to calm her enough to find out what type of help she needed she collapsed, twitching at my feet. Called 911 and got her into an ambulance (her father called later to let me know that I’d saved her life; heart problems!). It left me thinking about mortality, a little shaken, and not at all in the mood to write an update!
Anyway, it’s been a busy two weeks. I’m now two features away from calling the graphics engine done (it needs particles and a cursor/selection highlight system – both of which are blocked by getting some other features ported), and a handful of systems ports to be done with this branch. I fixed a bunch of small bugs, and worked hard on porting over game systems to the new architecture. The following systems are ported now:
- The settler spawner system is in, so more crew-mates can join your settlement over time.
- Door system, allowing doors to be opened/closed (there’s some path-finding work to fixup, but it basically works).
- The dijkstra map system is back in, uses the new threading regime, and is a lot better about not trying to update repeatedly when lots of things change at once.
- The fisheries and wildlife system is ported over, so wildlife can once again spawn and bother you. Some asset creation is still required.
- The explosions system is ported, but is waiting on particles and damage to be overly useful. Lots of
- The sentient AI system is ported, so natives will once again wander around and try to kill you if you tick off their civilization. There’s a few integrations remaining from systems that aren’t ported yet.
- The corpse system is ported, and corpses will spawn, rot away, yield bounty when harvested (leather, meat, bone, etc.). Awaiting the particle system to make rotting yucky.
- The mining system is ported, so the map can be changed by mining (and can collapse, etc.).
- The inventory system is ported, providing other systems with an index for fining things (and answering questions like “is this weapon better than what I have?”, “do I need to search for ammunition?”)
- The stockpile system is ported, sans UI (so stockpiles work, but the method for defining them doesn’t).
- The workflow system is ported. This is the backbone of a LOT of other systems; every building, reaction and queued task goes through here, so it was really important. It’s undergone a number of performance enhancements, and is better than ever.
- The visibility scan system is ported, so entities can react to what they see.
- The “AI New Arrival” system is ported, so newly arrived settlers can complain about life, the universe and everything.
- The “AI Scheduler” system is ported. This system checks what shift a settler is on, and sends them to the appropriate “work”, “play” or “sleep” systems.
- The “AI Sleep System” is ported. This keeps a “sleep clock” going, and also manages scheduled sleep time. Sleepy settlers seek out a bed, and take a rest (or sleep on the floor and complain about it).
- The “AI Leisure System” is ported. This currently makes settlers wander aimlessly during their free time; it’s going to be where they seek out food, entertainment and company.
- The “AI Work Time” system is ported. This was a huge job, and ended up with MUCH cleaner code. Underlying the system is a “jobs board” that tracks available work (with tasks registering themselves, to keep coupling down). Jobs are selected based on preferences (setting if a settler can/cannot do a work category), distance (settlers prefer nearby jobs) and importantance (which is a little hand-waivy, but prioritizes older jobs so that they get done eventually).
- The “AI Lumberjacking” system is ported, but needs quite a bit of integration work. There’s some major template-based code behind the implementation of various labor types, so this meant it was time to modernize a bunch of convoluted templates.
There’s still a few systems left to port, but it’s coming together nicely. Porting to the new system entails:
- The previous version had systems in a class, inherited from a base class. The new system moves each system to free functions in a namespace.
- The previous version profiler was poor; I’ve fixed that. Through some template trickery, the “run” process for each system automatically profiles it.
- The previous version had a lot of stupid coupling, so cleaning that up is leading to MUCH more debuggable code (I was already being really careful about managing side effects, but I’m also being a lot more strict about using
- The previous version relied on a message-passing system that worked well at its primary purpose (systems don’t have to know about one another), but fell over badly when exposed to threads. It kept getting more and more hacky, with things like
emit_deferredfor sending a message in a threaded environment (which in turn ended up buffering outgoing messages in a mutex-protected queue before actually sending them). Now, there’s a bit more explicitness about where messages are going – but they go through a single, templated system that ensures thread safety (so long as I stick to multi-writer, single reader). I was in danger of needing the Actor model, and this cleaned things up quite a bit without having to implement green threads!
Overall, I’m glad I’ve taken the time to rebuild the foundation. It’s coming together really well (even if part of me keeps wondering if I shouldn’t have just built atop something like Unreal; that would have worked faster, but I wouldn’t have learned so much!).