To finish off I've done some work on steering behaviours and generating stories for NPCs in certain circumstances.
For steering behaviours I used the Unity component Nav Mesh Agent, however this didn't allow much variation in the movement for the NPCs. The Nav Mesh Agent was simply too perfect, I wanted to add some variation. Rather than making a steering algorithm from scratch, which would involve implementing a path finding algorithm I continued to use the Nav Mesh Agent, but in a different way. I made the Nav Mesh Agent invisible, with no collisions and wrote a simple steering behaviour to follow that agent.
Unfortunately I left it too late and didn't have enough time to experiment with different variations in steering behaviours.
void Update () {
//Set the speed based on the speed of the Body nav
moveSpeed = nav.speed;
//Set the colour and scale based on the Body
rend.material.color = following.GetComponent<Renderer>().material.color;
transform.localScale = following.transform.localScale;
transform.LookAt(following.transform.position);
float dist = Vector3.Distance(transform.position,following.transform.position);
if (dist > 0.5f){
transform.position += transform.forward * moveSpeed * Time.deltaTime;
}
}
While this code utimately acts in a very similar way to before, it gives me a framework to add that variation which will make the NPCs seem more human.
For generating stories I made a few simple algorithms which searches through all the NPC people looking for specific situations to describe a story. The hardest part was distinguishing between fact and implication. Storing what each NPC might know about every other NPC is a challenge in itself, so I decided not to worry about this too much.
Here is a method for generating suspicions about affairs:
void affairSuspicion(){
PersonStats[] people = GameObject.Find("People").GetComponentsInChildren<PersonStats>();
RelationshipHelper rh = GameObject.Find("Relationships").GetComponent<RelationshipHelper>();
//For every person
foreach(PersonStats ps in people){
//If they are stressed, they have a partner and the strength of that relationship is less than 50
if (ps.stress > 50 && ps.partner != null && rh.getStrengthValue(ps.gameObject, ps.partner) < 50){
//For each of the partners friends
foreach(GameObject go in ps.partner.GetComponent<PersonStats>().contacts){
PersonStats cps = go.GetComponent<PersonStats>();
//If they have a good relationship
if (rh.getStrengthValue(go,cps.gameObject) > 0){
ps.stories.Add("Suspicious that partner is having an affair with " + cps.forename + " " + cps.surname);
Stories.Add(ps.forename + " " + ps.surname + " is suspicious that partner is having an affair with " + cps.forename + " " + cps.surname);
break;
}
}
}
}
}
If someone is stressed and the strength of the relationship with their partner is under 50, they will suspect other people who have a higher relationship strength. The limitation being these suspicions are rather unfounded. There should really be another method for getting more generating suspicions with are definitely correct. This mixture of paranoid stories which are unfounded and real suspicions would add to the variation and complexity of the simulation.
Friday, 27 November 2015
Sunday, 22 November 2015
Week 11: November 22nd 2015
For when an NPC had free time I decided to implement a finite state machine. I chose this method mainly for simplicity, I knew in the short term this would be a quick and easy way to do things. However if I add many more states in the future it might be best to switch to a behaviour tree instead.
void freeTime(){
if(dnc.hours <= 9 || asleep){
destination = ps.home.transform.FindChild("Rug").gameObject;
}
else {
if (doneFree){
doneFree = false;
freeTimeAction = Random.Range(0,5);
}
switch(freeTimeAction){
case 0:
getFood();
break;
case 1:
goToBestFriend();
break;
default:
goHome();
break;
}
}
}
As you can see there are only states at this stage. Once the getFood() state is performed the state can transition to either goHome() or goToBestFriend(). Going to best friend than then transition into going home only if it's time for bed.
This current implementation might be limited, but it can be easily adapted for more complex behaviours if required in the future.
void freeTime(){
if(dnc.hours <= 9 || asleep){
destination = ps.home.transform.FindChild("Rug").gameObject;
}
else {
if (doneFree){
doneFree = false;
freeTimeAction = Random.Range(0,5);
}
switch(freeTimeAction){
case 0:
getFood();
break;
case 1:
goToBestFriend();
break;
default:
goHome();
break;
}
}
}
As you can see there are only states at this stage. Once the getFood() state is performed the state can transition to either goHome() or goToBestFriend(). Going to best friend than then transition into going home only if it's time for bed.
This current implementation might be limited, but it can be easily adapted for more complex behaviours if required in the future.
Wednesday, 18 November 2015
Week 10: November 18th 2015
Since I got routines working I wanted to make them more advanced by making them a bit more dynamic, so you could add a new routine for the next day of an NPC. It was as simple as having a separate list of RoutineEntries called dynamicRoutine each night when an NPC goes to sleep this list is merged with the main schedule of an NPC.
//A method for populating the routine
void populateRoutine(){
ps.routine.Clear();
if (ps.occupations.Count >= 1){
foreach (GameObject go in ps.occupations){
OccupationStats os = go.GetComponent<OccupationStats>();
ps.routine.AddRange(copyRoutine(os.schedule));
}
}
ps.routine.AddRange(dynamicRoutine);
dynamicRoutine.Clear();
}
Routines can also be dynamically added to the same day by simply adding a RoutineEntry to the routine list Schedule of an NPC.
I tested this out by scheduling a funeral the next day for every NPC who knew and liked the deceased NPC.
void arrangeFuneral(PersonStats ps){
RelationshipHelper rh = GameObject.Find("Relationships").GetComponent<RelationshipHelper>();
//Foreach person who knew the deceased
foreach(GameObject go in ps.contacts){
//If the strength of the relationship was greater than -20
if(rh.getStrengthValue(ps.gameObject,go) > -20){
//Create a new Routine entry and add it to the dynamic routine of the contact
RoutineEntry re = new RoutineEntry();
re.startHour = 9;
re.startMinute = 0;
re.endHour = 16;
re.endMinute = 0;
re.location = ps.gameObject.transform.FindChild("Body").gameObject;
re.done = false;
re.priority = 10;
if (go != null){
go.transform.FindChild("Body").GetComponent<PersonMovement>().dynamicRoutine.Add(re);
}
}
}
}
While these simple systems work rather nicely, it is still very limited. Ideally events should be scheduled for weeks in advance.
However thinking about it, this could be made possible with a small adaption to the way the dynamicRoutine and routine lists merge. Items from the dynamicRoutine list should only be added to the routine list if a condition is met, for instance the day number.
Wednesday, 11 November 2015
Week 9: November 11th 2015
I didn't have many issues implementing the routines into the movement of the NPCs, although prioritizing certain activities over others if there is a time clash doesn't work as I would like to expect.
For each cycle of the void Update() method:
foreach(RoutineEntry re in ps.routine){
//If task is within start and end hour and it hasn't been done
if ((dnc.hours >= re.startHour) && (dnc.hours < re.endHour) && (!re.done)){
//They are not free
free = false;
freeChk = false;
//change destination to the location of the routine entry
destination = re.location;
p = destination.transform;
//If the type of routine is visit
if (re.type == 'V'){
if (Vector3.Distance(p.position,transform.position) < 2){
//Consider it done once a certain distance has been met
re.done = true;
}
}
}
}
This means the current routine the NPC performs is never saved, each cycle the appropriate action is applied depending on the time of day, and if the RoutineEntry is done or not. This has a few comparisons to that of a behaviour tree. The biggest advantage being that NPCs will immediately react to a change in their routine. However in it's current form RoutineEntries at the beginning of the foreach loop with have a higher priority. In the future I could set a priority to each RoutineEntry and sort the list accordingly each time a routine is added to an NPC schedule. This would solve this issue, and give the NPCs more control.
For each cycle of the void Update() method:
foreach(RoutineEntry re in ps.routine){
//If task is within start and end hour and it hasn't been done
if ((dnc.hours >= re.startHour) && (dnc.hours < re.endHour) && (!re.done)){
//They are not free
free = false;
freeChk = false;
//change destination to the location of the routine entry
destination = re.location;
p = destination.transform;
//If the type of routine is visit
if (re.type == 'V'){
if (Vector3.Distance(p.position,transform.position) < 2){
//Consider it done once a certain distance has been met
re.done = true;
}
}
}
}
This means the current routine the NPC performs is never saved, each cycle the appropriate action is applied depending on the time of day, and if the RoutineEntry is done or not. This has a few comparisons to that of a behaviour tree. The biggest advantage being that NPCs will immediately react to a change in their routine. However in it's current form RoutineEntries at the beginning of the foreach loop with have a higher priority. In the future I could set a priority to each RoutineEntry and sort the list accordingly each time a routine is added to an NPC schedule. This would solve this issue, and give the NPCs more control.
Tuesday, 3 November 2015
Week 8: Novemeber 3rd 2015
To implement the separate and individual routines of all the different occupations I needed a way to store them. So I decided to make an object called RoutineEntry it contains information on the start and end time of the routine, the location, the type of action, the priority and if that action is done or not. Using this object should be flexible enough to create some routines that seem complex. I considered saving function for an action instead of just a location, this might make it easier to encapsulate more complex behaviours. However I want to make each RoutineEntry as simple as possible, so I went for the former implementation.
For the time being I only plan to have two "types" those being visit and stay. The visit routines are considered done once the NPC has reached the location, the stay routines are never done, the NPC only stops performing them when the end time is passed. However I can see this as a future issue if an NPC needs to be interrupted from a "stay" routine they are currently performing. If prioritizing works correctly there's a chance I can add a higher priority routine to their schedule while the game is running and the NPC will switch to that instead. This needs testing though.
To briefly explain how the NPC get their routine's populated, when they go to sleep a hard coded routine from their corresponding occupations are added to the next days routine, and the routine for the previous day is cleared. It would be nice to save the history of each individuals previous routines, however I think this out of the scope for this project currently.
In hindsight clearing and populating the next day's routine when an NPC goes to sleep is a bit naive. Obviously I want the variety of some NPCs to stay up all night and not get any sleep. With the current implementation this would have the interesting side effect of the NPC taking the next day off from any form of work, if they didn't go to sleep.
For the time being I only plan to have two "types" those being visit and stay. The visit routines are considered done once the NPC has reached the location, the stay routines are never done, the NPC only stops performing them when the end time is passed. However I can see this as a future issue if an NPC needs to be interrupted from a "stay" routine they are currently performing. If prioritizing works correctly there's a chance I can add a higher priority routine to their schedule while the game is running and the NPC will switch to that instead. This needs testing though.
To briefly explain how the NPC get their routine's populated, when they go to sleep a hard coded routine from their corresponding occupations are added to the next days routine, and the routine for the previous day is cleared. It would be nice to save the history of each individuals previous routines, however I think this out of the scope for this project currently.
In hindsight clearing and populating the next day's routine when an NPC goes to sleep is a bit naive. Obviously I want the variety of some NPCs to stay up all night and not get any sleep. With the current implementation this would have the interesting side effect of the NPC taking the next day off from any form of work, if they didn't go to sleep.
Thursday, 29 October 2015
Week 7: October 29th 2015
Today I spent a lot of time message around with the more interactive and visual aspects of my game. Namely the player movement and how the people will navigate and steer around the environment. To set this up I decided to use a Nav Mesh Agent. With some help from the official unity documentation and a tutorial on how to make a top down shooter, I implemented a Nav Mesh Agent into my game.
This meant I could focus on starting a finite state machine which will gradually get more and more complex. To test it I wanted each person to move towards their partner if they had one, or move towards there mother. If they didn't have either they would move towards the player.
The final code looked like this:
void Update () {
ps = GetComponentInParent<PersonStats>();
if (!init){
init = true;
if (ps.partner != null){
p = ps.partner.transform.FindChild("Body");
}
else if (ps.mother != null) {
p = ps.mother.transform.FindChild("Body");
}
else {
p = GameObject.FindGameObjectWithTag("Player").transform;
}
}
nav.SetDestination(p.position);
}
I had quite a bit of trouble getting this to work at first. Each person didn't walk to each other, rather they walked to their initial start position. This was because I assigned the variable "p" to parent "Person" GameObject and not the Body which was the part that moved around.
While this system is currently very simple, it should be enough to create some rather complex behavior. Although I am unsure how resource intensive a Nav Mesh Agent is when there are over 100 agents cycling through different states based on different conditions.
Documentation: http://docs.unity3d.com/Manual/class-NavMeshAgent.html
Implementation tutorial: http://unity3d.com/learn/tutorials/projects/survival-shooter-project
This meant I could focus on starting a finite state machine which will gradually get more and more complex. To test it I wanted each person to move towards their partner if they had one, or move towards there mother. If they didn't have either they would move towards the player.
The final code looked like this:
void Update () {
ps = GetComponentInParent<PersonStats>();
if (!init){
init = true;
if (ps.partner != null){
p = ps.partner.transform.FindChild("Body");
}
else if (ps.mother != null) {
p = ps.mother.transform.FindChild("Body");
}
else {
p = GameObject.FindGameObjectWithTag("Player").transform;
}
}
nav.SetDestination(p.position);
}
I had quite a bit of trouble getting this to work at first. Each person didn't walk to each other, rather they walked to their initial start position. This was because I assigned the variable "p" to parent "Person" GameObject and not the Body which was the part that moved around.
While this system is currently very simple, it should be enough to create some rather complex behavior. Although I am unsure how resource intensive a Nav Mesh Agent is when there are over 100 agents cycling through different states based on different conditions.
Documentation: http://docs.unity3d.com/Manual/class-NavMeshAgent.html
Implementation tutorial: http://unity3d.com/learn/tutorials/projects/survival-shooter-project
Wednesday, 28 October 2015
Week 6: October 28th 2015
Today I started the bulk of the work involved in porting the Netlogo model to Unity. Organisation was one of the biggest problems with Netlogo, Unity should solve some of those problems. However I am also adapting to a new piece of software so I sure I'll make some questionable organisation decisions along the way.
Firstly I'm grouping all the relevant objects inside parent classes so I can easily loop through every person and occupation. This is equal to the command "ask people" or "ask occupations" in Netlogo. Doing some research this seems the best way to do things, as I can simply get all children from the associated parent class.
Each Person prefab has a PersonStats script which contains all the relevant information for the individual. To represent emotions I chose four variables Stress, Confidence, Happiness and Temper. So far I'm unsure how exactly I'm going to use these. High Stress and Temper levels will result in more extreme activity. Happiness and Confidence will factor into how those Stress and Temper levels go up and down. Finally each person will have a "state" which changes based on those four levels, which influences how they act around other people. This state will act used in a finite state machine.
Firstly I'm grouping all the relevant objects inside parent classes so I can easily loop through every person and occupation. This is equal to the command "ask people" or "ask occupations" in Netlogo. Doing some research this seems the best way to do things, as I can simply get all children from the associated parent class.
Each Person prefab has a PersonStats script which contains all the relevant information for the individual. To represent emotions I chose four variables Stress, Confidence, Happiness and Temper. So far I'm unsure how exactly I'm going to use these. High Stress and Temper levels will result in more extreme activity. Happiness and Confidence will factor into how those Stress and Temper levels go up and down. Finally each person will have a "state" which changes based on those four levels, which influences how they act around other people. This state will act used in a finite state machine.
Tuesday, 27 October 2015
Week 5: October 27th 2015
There will be two distinct simulations in my overall village simulation. One will be a year cycle and another will be a day-to-day cycle. The year cycle will act as setting up the stage, and the day cycle will be the visual continuous game cycle, which will constitute the game. This day cycle will consist of each person going about their daily routine, sleeping, eating and going to work. Each starting couple will get assigned a house, during the year cycle each person above the age of 18 will get the chance to apply for a job.
For each job I have designed a specific routine. Once this is implemented I can focus on changing the individual behaviors of the people to add variation.
Postman - Goes to the post office, goes to each house, goes back to the post office and then goes home.
Office Worker - Goes to the office, goes out for lunch, goes back to the office and then goes home.
Service - Goes to work in the local supermarket and then goes home.
Teacher - Goes to the school and then goes home.
Student - Goes to the school and then goes home.
Nursery Worker - Goes to the nursery and then goes home.
Baby - Gets taken to the nursery by a parent or family member and the gets taken back home.
Mortician - Buries dead bodies.
Unemployed - Stays at home, goes out for food and then goes back home.
The routine for a baby will probably be the hardest to implement, considering it requires an adult to take them to the nursery. It also required adults to adapt their routine based on if they have children or not. I simple hard-coded routine will not be practical in this case. Each person needs a list of prioritized goals they wish to achieve each day, such as "go to work", "pick up baby from nursery" and "buy food". Not only will a system like this add flexibility but it will allow emotions to govern if a task is really worth doing or not.
Saturday, 24 October 2015
Week 4: October 24th 2015
The stories generated through the procedural generation of all these virtual people and there relationships need to be believable, but also interesting and bizarre enough to generate interesting quests for the player to attempt. For this post I am running my simulation a number of times to try and find some implied stories based on individual stats.
Here is the bio for James Stokell:
As you can see he currently only has one half-brother called Ethan Snow and his parents Sophia Snow and Barry Stokell have divorced. He's married to Kaitlyn Stokell with no sons or daughters. His only friend right now is Benjamin Snow despite the fact he's been at his job for 3 years and has an especially bad relationship with Sita Lees.
Next I ran the simulation for 13 more years and had a look see how James was getting on...
James now has a son and two daughters, the son of which he named after his Father Barry Stokell. Unfortunately his marrage with Kaitlyn didn't work out and they got divorced, but he also got a second divorce after getting married to Tara. Now he's "happily" married to Elizabeth. He was made redundant from his job when he was 23 but reapplied and got accepted into the same occupation, perhaps in a different department? This actually happened again when he was 32, seems like his boss keeps on trying to get rid of him, but he keeps managing to figure out a way to get his job back.
Finally I ran the simulation until James died. He lived to the ripe old age of 91. He managed to keep his job at occupation 34 until he was 67 where he was made redundant. However, probably due to his large amount of experience he then became the boss of another company, he retired at 81.
In terms of family he had one more son and two more daughters, however he went through a total of 13 divorces in his entire life.
Looking the life of Jame's you can imply he was probably good at his job, but potentially had some commitment issues with the amount of marriages he went through. Or perhaps he never did any cheating of the sort, but rather he was just really difficult to live with? Or maybe there was a darker reason?
From the point James' point of view he could possibly ask the player to find out if his wife is cheating on him. Based on his previous experience he could be overly paranoid, for good or bad reason. Or since his work is so important to him, when he gets made redundant he could ask the player to "dispatch" a boss of another company so he can take their place.
Looking at the bios of other people in the same simulation, most people have a large amount of divorces in their lifetime. So this is an imbalance in the simulation based on the flat value of the "DIVORCE-CHANCE" global variable. I plan to slowly remove many of the global variables in favour of a system which provides some more individual variance.
Stories involving Sims AI: http://goo.gl/OWtJMm
Friday, 16 October 2015
Week 3: October 16th 2015
This week I focused on implementing friends, enemies and emotions. This would be the final step required before adding events to my simulation, then I can start porting the Netlogo model into Unity and create steering behaviors for each character in the simulated village.
To store every relation a single person has (excluding immediate family) I added a new "contacts" variable. Each contact has a link with the person which owns a "strength" variable indicating how good the relationship is. A positive value represents a friendship and a negative value represents an enemy.
Currently new friends and enemies can only be acquired by a person if they are in the same occupation as them. This will be expanded to friends of friends, and friends of family members in the near future.
I wrote some pseudo code before I coded the procedure in Netlogo:
Each new feature I add to this simulation the more I realise Netlogo isn't suited to this project. With so many links for everyone's contacts, the visual representation becomes useless. You can see all the turtles bunched up around their occupation:
Adding a strength variable to links has resulted in an unexpected side effect. I was only going to use this variable for relationships between people but I could also use to to show how much a single person likes their occupation.
Finally the strength value of the relationship will be used to adjust emotions of people. For instance if someone dies, that strength value will be subtracted from their happiness. Or if someone got fired from their job, that strength value could also be subtracted from their happiness. So if someone hated their job so much it had a negative strength value, it would actually make them happy to lose their job.
To store every relation a single person has (excluding immediate family) I added a new "contacts" variable. Each contact has a link with the person which owns a "strength" variable indicating how good the relationship is. A positive value represents a friendship and a negative value represents an enemy.
Currently new friends and enemies can only be acquired by a person if they are in the same occupation as them. This will be expanded to friends of friends, and friends of family members in the near future.
I wrote some pseudo code before I coded the procedure in Netlogo:
Right now the chance of getting a new friend or enemy is based on the value of the global variable "NEW-CONTACT-CHANCE". It is important I change this in the future to add more "character" to each person. Outgoing people would have a larger chance to make friends, introverts would have less of a chance and especially egotistically people could have a larger chance to make enemies.for each person in simulation {for each employee in occupation {if employee is not already a contact {set rand = random(100)if rand < NEW-CONTACT-CHANCE{set contacts fput employeecreate-link-with employee {set strength random(100) - random(100)}}}}}
Each new feature I add to this simulation the more I realise Netlogo isn't suited to this project. With so many links for everyone's contacts, the visual representation becomes useless. You can see all the turtles bunched up around their occupation:
Adding a strength variable to links has resulted in an unexpected side effect. I was only going to use this variable for relationships between people but I could also use to to show how much a single person likes their occupation.
Finally the strength value of the relationship will be used to adjust emotions of people. For instance if someone dies, that strength value will be subtracted from their happiness. Or if someone got fired from their job, that strength value could also be subtracted from their happiness. So if someone hated their job so much it had a negative strength value, it would actually make them happy to lose their job.
Friday, 9 October 2015
Week 2: October 9th 2015
This week I focused on implementing
death by old age into my community simulation. This is very necessary
to implement future additions to the simulation, such as events and
emotions.
To begin with I looked up some
information on the annual chance of death in the UK. This would give
me a good basis to start with.
Looking at the data I had a few
choices. I could either implement the statistics as a simple lookup
table, or I could use an equation which somewhat matched the relation
of age and death chance. Then I would be able to work out a death
chance using age as the input. The second choice is more desirable,
but I chose the first method because it would be quicker to do and
therefore give me more time to experiment. Later in this project I
will consider using an equation instead, as it would give me more
flexibility in the long run.
Below you can see how I implemented a very simple look-up table in Netlogo for representing the random chance of death. This is limited in a number of ways, and not very flexible, as I mentioned earlier. Using an exponential equation with a number of parameters will certain make it more interesting, but for the time being this will do.
if gender = "m"[if age <= 4[set rand random(4386)]if age > 4 and age <= 14[set rand random(8333)]if age > 14 and age <= 24[set rand random(1908)]if age > 24 and age <= 34[set rand random(1215)]if age > 34 and age <= 44[set rand random(663)]if age > 44 and age <= 54[set rand random(279)]if age > 54 and age <= 64[set rand random(112)]if age > 64 and age <= 74[set rand random(42)]if age > 74 and age <= 84[set rand random(15)]if age >= 85[set rand random(6)]]
For the annual chance of death I used some real-world statistics from the National Statistics series in the UK. Each year a random number is generated for each person, based on their age and gender corresponding to the statistics it it determined if they die of natural circumstances or not. Future additions to the simulation may include diseases, which may also be hereditary. However this could be another simulation entirely, so it isn't very important for the time being.
For death to work as expected, the
simulation is required to perform a “death-clean-up” procedure
whenever a person dies. This forces the person to remove any partners
they were with if they were married, so the other partner can remarry
as a widow or a widower. It also removes them from any occupations if
they are employed, this “death event” is then added to the
person’s job history. As further changes are made to the simulation the "death-clean-up" procedure will be updated to effect the emotions of any people who know or are related to the dead person.
Reference: http://www.medicine.ox.ac.uk/bandolier/booth/Risk/dyingage.html
Wednesday, 30 September 2015
Week 1: September 30th 2015
Before I started this project I already had a foundation which I built over the summer. Over the next 12 weeks I will expand on this foundation which I have made in Netlogo. Then I will port it to Unity where it can be used in a more playable game setting.
Currently my procedural village generator starts off with a user defined number of couples, these couples can either be hetero or homosexual. They are also given a random name and a random age from 18-100. Currently the age is totally random, so it is just as likely two people of a similar age will get matched compared to a couple with a 60 year age difference. This needs to be changed so that couples with a larger age gap are less likely to occur.
Once these couples have been generated, a user-defined number of occupations are also created. Currently none of these occupations are unique, later I plan to make them more individual. Some will be schools and some will have specific limitations on how many can work there. Perhaps I will also include how "fun" the job is, adding a level of desire for other people to work in more enjoyable jobs. People who work in these more "fun" jobs will also have an increased level of happiness. Additionally, each one of these occupations has a boss.
After this initial setup procedure the simulation can be executed on a year-by-year basis.
Every year a number of processes are executed:
Currently my procedural village generator starts off with a user defined number of couples, these couples can either be hetero or homosexual. They are also given a random name and a random age from 18-100. Currently the age is totally random, so it is just as likely two people of a similar age will get matched compared to a couple with a 60 year age difference. This needs to be changed so that couples with a larger age gap are less likely to occur.
Once these couples have been generated, a user-defined number of occupations are also created. Currently none of these occupations are unique, later I plan to make them more individual. Some will be schools and some will have specific limitations on how many can work there. Perhaps I will also include how "fun" the job is, adding a level of desire for other people to work in more enjoyable jobs. People who work in these more "fun" jobs will also have an increased level of happiness. Additionally, each one of these occupations has a boss.
After this initial setup procedure the simulation can be executed on a year-by-year basis.
Every year a number of processes are executed:
- Processing births for partnered couples. Each couple has a chance to have a child each year. Currently this chance isn't effected by how many children the couple already has. In the near future the number of children will effect the chance.
- Processing deaths. (This isn't fully implemented yet)
- Processing retirement for those currently in working above the retirement age. Once a person exceeds this age they don't immediately retire, there is simply have a chance that each year they will retire.
- Processing redundancy. There will be a chance someone will get made redundant from their job.
- Processing new friends. (This isn't fully implemented yet)
- Processing occupation-change. If a person finds a position for a new job they want, they will quit their current occupation and join the new one.
- Processing new bosses. Each occupation has a boss, each person has a chance to become a boss of an occupation. If a new boss isn't found an outsider is created and made the boss of the occupation.
- Process applications. Each person who is unemployed applies to an occupation and has a chance to be accepted. If none of the applications are accepted they wait until the next cycle to apply again.
- Find partners. Each person who doesn't have a partner tries to find another person who doesn't have a partner. There is also a chance they will be partnered with an outsider.
Before I port this to Unity there are a few aspects I need to finish off:
- Death by old age needs to be implemented.
- A friend/enemy system needs to be implemented.
- An emotional system needs to be implemented.
- Schools need to be implemented.
- Affairs need to be implemented. (They were in a previous version, but not one adapted to the year cycle)
- Job history needs to be displayed in each person's bio.
Subscribe to:
Comments (Atom)



