For my specialization I've tried to create a village of autonomous villagers who try to build a village to live in, govern themselves, and survive and thrive on the resources they have available to them. All villagers are born with different statistics, such as intelligence and strength, which impact what jobs they are good at. Some jobs are simple, like berry picking, which just involve the villagers going back and forth and collecting food. While some jobs are complex, like the mayor job, who determines what priorities the village should have, where to place new buildings, and what new jobs are available, and how important those jobs are for the village.
All villagers are created in a group of 15 - 25 villagers at the start of the game. When villagers are created, they are created with six stats: Strength, Dexterity, Constitution, Intelligence, Wisdom and Charisma. All these stats are randomly assigned a value between 8 - 20, and these stats affect different parts of their every day life, such as dexterity affecting their movement speed, strenght affecting their productivity in construction jobs, and charisma making them more likely to be chosen for certain jobs. All villagers also use pathfinding similar to that used in my previous projects, which I will not dive further into here, but more information can be found in my page about Spite: Web of Decay.
The villagers behaviors are all controlled by their behavior tree, and when they change job, they also change behavior tree, allowing all jobs to behave in their own unique way, and being easily modifiable. The behavior tree is split into two parts, one villager part and one job part. The villager part controls the most primal needs of the villagers, such as their need to food. The other part of the behavior tree is their job part, which determine what they will do around the village when their basic needs are met and they are not at the risk of death.
As part of the villager behavior side of the behavior tree, the villagers were also supposed to need rest, but I did not have time to implement this. They would have gotten better rest depending on where they rested, for example if they rest outside on the ground, in a communal sleeping chamber, or in their own house.
The world was planned to be randomly generated, but started as a premade world and I never found time to make it random. The world consists of a great grass plane, with a single river running through the world. In the world exists trees, creating small forests, berry bushes which the villagers use as a food source, and rocks, which were supposed to be another building material used to certain building and would come with the miner job, but this was never implemented.
The world uses a grid system for faster collision checks, where every grid cell has information about all creatures and building currently in the cell.
The job system is one of the two vital systems in this project. The job system allows all villagers to change which behavior tree they are using, and provide services to the community to further progress the village.
Villagers choose their own jobs by going to the town hall. In the town hall exists a hidden list of all the jobs the village needs currently, and each job has a weight that shows the villagers how important that job is the for the community. This also allows villagers to change jobs, should they see a job available that is more important to the village than the one they are currently assigned.
The mayor is the most important job in the village, and the one that is assigned first. As soon as the villagers spawn, a villager with a lot of charisma, intelligence and wisdom is chosen as the mayor.
The mayor has two big jobs. The first job is deciding what jobs the village currently needs. It uses different calculations to see if a job is needed in the village, but also how important it is. It adds these jobs to the town hall, where the villagers themselves go and chose what job on the joblisting they want.
The second important job of the mayor is deciding what buildings are needed and where they should be placed. The town hall serves as the center of the village, and is the first major decision the mayor does. He chooses a location that is close to where they are, with as much open space as possible around the town hall, and in close proximity to trees and food.
The builder is one of the two special jobs that isn't taken at the town hall, alongside the mayor. If a villager is in proximity of a non finished building, they will check how important that building is to the village. They will then compare it to how important their current job is to the village, and change jobs if they find it necessary. Villagers without a job will almost always pick up this job if they see a building needing builders, and each time a builder is assigned to a building, the weight of the builder job for that building goes down.
Villagers who already have a job might switch to a builder job if their current job is very low priority and its a high priority building without a good amount of builders already.
This is currently one of the two "Basic" jobs that exists in the project, but a majority of the jobs i was planning to add would work the way this job does. When berry pickers basic needs are met, they will go to the nearest available berry source, pick berries for a while, and return to the village with the food. Before a cafeteria is built, the berry pickers will leave their food in the town hall, but the town hall has a small food storage.
After a cafeteria is built, the mayor will assign the berry picker job more intelligently. Before it exists, the mayor simply looks at how hungry every villager is, and assigns more berry pickers if the average hunger is too low. After it is built, the building provide better data to the mayor, allowing him to make more intelligent decisions. While this does not change the berry pickers behavior in any way, it changes how many berry pickers are assigned, and makes the villagers not change jobs as frequently because of fluctuating hunger in the village
The woodcutter job is very similar to the berry picker, the mayor difference being that while berry pickers are always needed, woodcutters are only needed when a building is being constructed. This job therefore has a higher weight depending on how important the buildings that are currently constructed are for the village.
Similar to the berry picker, the woodcutter has a building associated with it, called wood storage internally. Before a wood storage is constructed, woodcutters will simply bring the needed wood to the building being constructed. But after one has been made, the woodcutters want to fill it up. The wood storage also provides similar data as the cafeteria to the mayor, making it a more stable and long term job after one has been made.
Buildings are placed down by the mayor. Building locations are determined by balancing the want for the building to be close to the town hall, but also being close to any resource potentially stored in the building. When a building is placed down, it needs a certain amount of wood before being functional. It also need a certain minutes of being worked on by builders. A single builder can finish a building on his own, but the more there are, the faster it goes. When both conditions are fullfilled, the building stops being in "construction mode" and turns into a fully functional building.
The town halls is the heart of the village. It is the first building constructed, and is where all villagers will finds all current job listings available. It also acts as a small food storage before the cafeteria is built, and it's there the mayor spends most of his time. This building is also used in the mayors calculation of where to place buildings.
The cafeteria is a building to store the berries that are collected. It is also the first place villagers look to find food if they are hungry, except their own pockets of course. The building collects data of how much food goes in and out of the building, which helps the mayor be more intelligent in how he assigns the jobs. The building makes villagers way less likely to have to go out and forage food on their own, which increases their productivity. This building wants to be close to berry bushes, but it is much more important that it is close to the town hall, since this is where all villagers will be collecing their food, and we dont want them to have to waste time running really far to eat.
The wood storage works very similar to the cafeteria, but for wood instead of food. The placement of the wood storage is also more balanced than the cafeteria, wanting to be both close to the town center and trees about equally, resulting the the building often being placed somewhere in the middle between the town hall and the closest forest. It stores wood for future and current building projects, and also collect data of how much wood goes in and out of storage much like the cafeteria.
The biggest problem I faces during this project, and the biggest reason the project didn't reach the state I wanted by the end, was overscoping. I have for a long time wanted to work on a project like this, and I felt this was the perfect opportunity to get started on this passion project of mine. But the time we had was very limited, and alongside having other things I had to prioritize, and other problems I faced in the project, there simply wasn't enough time to implement the things I wanted. This resulted in a lot of my time being wasted on systems, then only using those systems for a handfull of things in game. The villagers are a perfect example of this, having way more statistics than they ever make use of, and having a half built system for an unused rest mechanic in them.
For this project, I wanted to use a weight system for the villagers to decide what to do for themselves. If something has a higher weight, the villagers will prioritize it more. As an example, if they find a job with a higher weight than the one they are currently on, they will abondon their job and pick up the new one. I didn't realize how incredibly hard it would be use balance these weights againt each other.
As an example, the mayor sees that the villagers are hungry. He does a calculation to see if he needs to add a berry picker job to the joblist, or update the weight on one already there. He uses a formula to calcuate the weight of the berry picker job, which takes into account how hungry the villagers are, how much food is in food storage, and if the information is available, how much food is consumed and how much food is added to the storage.
Then another job needs to be created, lets say a builder. The builder uses a completely different calculation for calculating how important that job is. It uses the weight of the building as its base, which in turn uses a a third completely different weight calculation. All these different weights are compared to each other, so these completetly different calculations need to produce weights that are accurate to how important they are to the village, and it has to be very precise for the village not to fall apart.
I have spent way way more time than I though I ever would, tweaking these calculations, adjusting how much different variables effect the end result. And every time I wanted to add a new job or building, I always had to add an entirely new calculation to figure out the weight, and each time it took a lot of time and tweaking to get it working.
This actually led to the wood storage and cafeteria storing data for the mayor to use, and made the village more functional with these building, which was a cool effect, but balancing weights was easily the biggest issue apart from overscoping this project had.