Luke, I’m your uncle

Lud
Procedural Emotions
6 min readAug 18, 2020

On the noble art of automatically building imaginary dynasties.

Families are arguably the smallest unit of society, so it makes sense to start from them trying to build our way up to wider social structures.

Another reason to start from here is that family relationships are at the core of a lot of dramatic and comedic patterns, just consider Star Wars and ASOIAF, but also the cute habit of discussing genealogy to death so widespread among the hobbits.

Having a procedure that can generate an “extended” family tree given some input parameters can be a very useful starting point in narrative generation and can provide a lot of variability and consistency in many later phases of the worldbuilding process and during story generation.

Cultural biases

Most of the inputs this procedure receives go under the umbrella of “cultural biases” or “societal biases”. These are things like the average age of marriage, average number of children in a couple, what happens to children born outside of marriage, openness to polygamy or other “family formats”, whether the culture is a matriarchy or a patriarchy or a more balanced mix, plus parameters such as social mobility. All these things heavily impact the final shape of the generated family.

I use the term “cultural” in its widest sense here, but in the case of some biases that could rightly be ascribed to biology or society (or even politics) I try to keep track here of only the cultural component. Life expectancy of an individual is largely dependant on race, ethnicity and wealth, but culture has definitely an impact on it as it influences diet and many types of habits such as consumption of alcohol or other substances.

Here is a list of other things that i consider cultural biases:
* ethnicities and races that can be found in the family’s society
* social classes
* types of jobs available to each social class
* types of institutions that can raise orphan children
* a list of class-sensitive areas (think slums vs royal court)

Annals

Another category of inputs to the procedure are the annals. Annals are a list of disasters happened in the last two or three generations. These are of two types: calamities and wars.
Calamities are natural disasters generated for a certain geographic area based on physical features of the land. Areas close to a divergent plate boundary will be subject to volcanic eruptions, areas close to transform or convergent boundaries will be subject to earthquakes (or tsunamis if they are also close the the ocean), areas on mountains could be subjected to landslides, while those near rivers or with high rainfall will have occasional floodings, and forest/shrubland areas with very dry seasons will have fires. And so on.
As for Wars, everybody probably knows what they are. The only gotcha is that in this case they are generated so to happen only between neighbouring countries belonging to different Unions. I’ll talk about Unions somewhere else but for completeness they are an abstraction covering empires, federations, confederations and sovereign states. Basically wars in the annals are generated in a way that retcons the current status quo, which is decided by another module somewhere else. This is one of the many dirty tricks I use to make the generator manageable and analytical, and to avoid the need for a full-scale simulation a la Dwarf Fortress. (To clarify I love Dwarf Fortress and I think Tarn Adams is a genius. But this project has a different goal, and should be able to create a setting given the needs of the story — thus the emphasis on controllability).

Seed character and the algorithm

All the things considered until now are “background information” about the world the family lives in. But where do we start to create a family? My algorithm currently starts from a “seed character”, for which you specify age at year 0 (the current year) along with a bunch of other target traits such as ethnicity, race and social class at birth. Setting the current year to zero means all the dates computed are relative to now and we can compute the real date by just adding the current year to all of them. For instance, if the current year is 2020 and the algorithm says the parents of the target character got married in year -30, that means the real year is (-30) + 2020 = 1990.

The algorithm works backwards and forwards from the character:
* figure out the year of birth of the seed character (which is simple since we have the age at the current year and the current year is normalised to 0);
* generate the number of siblings based on cultural biases and establish the birth order and consequently the birth years of any siblings;
* generate the age at which the parents had the first baby, and then the birth year of each parent;
* repeat the procedure to generate the paternal and maternal families by using respectively the parent and the mother as seed characters (this will provide a list of paternal and maternal uncles and aunts, plus the grandparents);
* establish date of death or of adverse situations for any family member (“adverse situations” means anything that will make the family member unavailable from a certain year, such as permanent invalidity or having left the family, regardless of the specific reasons);
* use cultural biases and annals to establish involvement of family members in wars, disasters (especially efforts for rebuilding after each disaster) and maybe retcon adverse situations using the annals (e.g. uncle Joe left for the war of year -21, never to come back, or the mother of the seed character died in the great fire of year -15).

After this you have a good grasp of the birth family of the seed character. But since a lot of bad stuff happens to families all the time, in the second part of the algorithm I verify whether at any point any family member becomes “abandoned” (having all parents either dead or incapable of taking care of them), and for any of them that became abandoned before reaching that culture’s definition of “adulthood” I try to figure out what to make of them:
* they can move in with an uncle/aunt or with paternal or maternal grandparents if they have any that is available;
* or they can be adopted by another family (in which case I generate the adoptive family as well and add it to the family tree);
* or if they have an adult sibling they can go live with them;
* or they can end up in one of the available institutions that can raise orphans (monasteries, orphanages, workhouses, etc. depending on the cultural biases);
* or if they are old enough they can maybe be hired as apprentices by an artisan;
* or (if the culture biases allow that) they can end up living on the streets.

A generated family tree where the seed character’s birth-father became invalid, the birth-mother abandoned the kid after 2 years and none of the other relatives stepped up, resulting in the subject being adopted by another family.

At this point the family tree is ready, but there are a lot more things we can add:
* a widowed husband or wife can get a new partner, which may also already have children from another marriage;
* for each family member we can make a list of “friends” they made in schools, institutions, during events etc (this can become useful during story generation, when an old friend from school/the orphanage comes looking for you or when you meet an old comrade-in-arms of your grandfather);
* we can keep track of the social class of the family and account for family history events such as someone being hired to work for the king and having the family move into the royal palace, or a merchant family becoming suddenly very rich or very poor;
* etc.

Conclusion

The algorithm is still incomplete, but is good enough for me to leave it behind and focus on the next step. I’ll come back later to clear the backlog, when I will be able to contextualise this part better and figure out what’s important and what is accessory.

Using this algorithm or parts of it, a director module can build a family tree of any depth and with a lot of configurability. Everything is managed through graphs so family trees can be merged and manipulated to reach particular situations if necessary.

--

--