In today's MMT we're talking about BUILDINGS! Well… more like… refactoring of buildings. We’ve done refactoring of other stuff before, but building refactoring is a bit harder to describe. This is going to get very technical, but for the sake of transparency and to understand how big of a change this is, we’ll try to explain it as best as we can - in layman’s terms.
Previously, we used a method called inheritance to create and manage buildings in our code. Inheritance is the mechanism of basing an object or class upon another object, retaining similar implementation. We had a base class called BaseBuildableObject that contained common code for things like construction, deconstruction, and storage. Think of a base class as a master blueprint. It's a basic plan that other, more specific blueprints are based on. All constructions were derived from this base class, and that’s why we created two separate instances:
- BuildingInstance: Inherited from BaseBuildableObject.
- FurnitureInstance: Also inherited from BaseBuildableObject.
One would be for building and the other one for furniture. If we had to introduce a new object within furniture, and that object would have some furniture properties but not all of them - we would have to expand FurnitureInstance and create a new class that inherited it. That could work, but it’s far from good practice, as we would have to expand FurnitureInstance each time we would add a new thing. We would just add unnecessary code that could be accessed from all classes that inherit it.
In this old architecture system, we had separate .json files for each building type. Basic buildings were in one .json file (such as walls, doors, stairs… in the Buildings.json), furniture was in another file (tables, chairs, beds… in the Furniture.json) and so on (check all these .jsons in the steamapps\common\Going Medieval\Going Medieval_Data\StreamingAssets\Constructables).
So, for the game to access that new furniture, it would have to go through the Furniture instance, process all of the code that covers functionality of every furniture, in addition to accessing the separate code of that new furniture. That can cause unnecessary processing power and extra steps for the whole process.
To solve those issues we’ve decided that it’s best to rewrite (technical term REFACTOR) all code related to buildings. The new approach we’re using is called component based architecture.
Component based software architecture is a style of writing code in multiple different classes (called components) that do one specific thing. Components are loosely-coupled and can be reused, making the code base easier to modify and expand without adding unnecessary code.
Now, we will have one single storage file with all the possible buildings inside it, called BaseBuildingRepository. However, they initially don't do anything except take up space in the game world. For example, beds can't be slept on, production buildings don't produce anything, and torches are always off and don’t give out heat. With just this .json, you would only be allowed to construct buildings and they would need resources for construction. Here is an example of campfire code in the old architecture (left) vs the new one (right).
To give buildings their functionalities, we had to create specific components for each building type: BedComponent for beds, TableComponent for tables, ChairComponent for chairs (TrapComponent, GraveComponent, DoorComponent, ProductionComponent) etc. Each component type will have its own JSON file describing its functionality.
To tie it all together, we have to do a couple of things. The first is done in Unity via prefab editing. In game development, a prefab is a ready-to-use model of an object (like a campfire), which you can then add specific functionalities to, like making it actually produce heat or light. In our case, a camp_fire prefab will require, among other files, a ProductionComponent.
The second thing is that we need to specify the productionComponentID within the campfire id in the BaseBuildingRepository.json.
This references a specific production component that the campfire will use. It could be any production component, not just for campfires. It doesn’t need to be a campfire component - it can be a research table component or a skep component (basically any production component). To make it more clear, here’s a snippet from the new ProductionComponentsRepository.json for campfire:
Notice how it only contains information about productions, no information about buildings.
Same principle goes for all other buildings. Some .json files may be nearly empty, like this one for caravan post (CaravanPostComponentRepository.json):
That’s perfectly normal. If we wish to expand caravan post functionality later on, we can edit that .json file and add appropriate code to the caravan post component. That way, all code related to a single type building will be contained in just a few classes and it’s much easier to debug everything (if there are issues with buildings of a certain type, we know exactly where to look as each building will have its own component now). And this will make modding of the game that much easier.
So, that’s why this is a big deal to us and why it took a lot to do it. We had to cover all of the building types and tie them all together in this streamlined coding web and this will make development much smoother as we go forward. And don’t worry, this will not break your existing saves.
Did you understand this? Does it make sense, even if you are not familiar with coding? We’re asking in order to figure out if these tech talks are worth going into such detail next time if/when they happen.
In any case, there are more things to talk about - like what you can expect from prisoners and their behavior. We've listened to your feedback and we'd like to extrapolate their functionality and that's worth at least one more MMT. Sooo... talk to you again in two weeks. Until then,
Stay medieval!
Foxy Voxel
Discord Reddit X/Twitter TikTok Facebook