For an RPG I want to generate a world with lots of NPCs, and the NPCs all have relations to eachother. They can be eachothers parents, children, siblings, friends, bosses, lovers, lieges, vassals, etc. And they have an opinion of eachother between -100 (hate) and +100 (love). If person A is close, like the child or lover, of person B that gives a bonus (say, +50) to B's opinion of A, etc.
This system is closely inspired by how relationships between all the characters in Crusader Kings 2 work. It can also be compared to The Sims.
Ideas
I am wondering what would be the sensible way to store this kind of data? Here are the three main approaches I can think of.
1. Object oriented: In the object oriented approach I make a Character class and a Relation class. An instance of the Relation class has pointers to two different Character instances and information about the relation between them. I have to store an array of Characters and an array of Relations. Probably also each Character instance should have an array of pointers to the Relations she has (maybe the global array of Relations is not necessary then?). A Relation instance does not necessarily need to exist between two characters that does not know eachother (as opposed to Crusader Kings, where every character has an opinion of everyone), but I can add new Relations if two NPCs starts to interact.
# Pseudocode concept of what a Relation instance could contain
Relation:
chars = [charA, charB]
opinions = 50, 60
relations = ["child", "parent"]
2. Normalized database: Have a Character table and a Relations table. The Relations table must have two columns, charA_id, charB_id, which references two unique Characters. This approach is quite similar to the object oriented one, just that each Character and Relation is a row in their respective tables instead of instances of a class.
3. Matrix: The Characters can be either class instaces or a database, but the Relations are stored in a big n*n matrix, where n is the number of Characters that exists. In this approach every NPC would have an opinion of every other, whether or not they actually know them. This will store an abundance of information, but in a very simple format. With a few 100s of NPC the size of matrix will be in the 10000s. This could work well if I just wanted a simple opinion number for eachother, but as I also want to store the nature of the relation (parent, lover, vassal, etc.) that can be clumsy to put in a matrix.
What it is
I'm not making a video game. This system is a tool to generate a world for tabletop RPGs like Dungeons & Dragons. The goal is to be able to quickly populate a fictive world with lots of procedurally generated characters to give the game master a rough slate from which to flesh out more details. If this project is successful it could be very useful for grand campaigns with lots of social interactions. The game master could plop down a new city full of people for the players to interact with in a matter of minutes.
Since it is not a game per se, the way of storing the information and having a good way to view it is the most important. The benefit of making a database is that I can perform queries like "Give me all the blacksmiths in city X" or "Give me all the female family members of person Y". The object oriented approach has the benefit of being more powerful in that it is very flexible in what kind of information I can put in a class, and I can make functions, like generateChild(personA, personB). I might go for a hybrid approach. Even if I make the system object oriented I could still convert it into a database to query against.
The final result will be
- A program that can generate (and change) chunks of new Characters and Relations and store them to file(s) in some format.
- An interface to search through and view the data.
Question
My question is what would be the sensible way to store this kind of data? Which of my ideas are good/bad? Do you have other suggestions?
Are there other games than Crusader Kings and The Sims that does something like this? How is it typically done? Relations between Factions can also be a thing, not just between individual Characters.
Example
I made an object oriented prototype that can generate random characters like these. Each character has their relations listed under them (not all the relations make logical sense at the moment).
name: Pupyq
age: 79
gender: female
lifestyle: wretched
alignment: neutral neutral
niece/nephew: Tesemakebi (31)
cousin: Tesemakebi (52)
name: Hyp
age: 37
gender: male
lifestyle: modest
alignment: neutral evil
cousin: Nyle (-69)
employee: Agegixuku (-86)
parent: Qogilatyji (95)
name: Agegixuku
age: 21
gender: male
lifestyle: poor
alignment: lawful neutral
employee: Zizewib (48)
employer: Hyp (-41)
employee: Hagimiqox (72)
child: Imibimataz (-85)
name: Qogilatyji
age: 80
gender: female
lifestyle: squalid
alignment: neutral good
aunt/uncle: Zizewib (-14)
child: Hyp (81)
name: Tesemakebi
age: 53
gender: female
lifestyle: poor
alignment: neutral good
aunt/uncle: Pupyq (29)
liege: Ovi (95)
employer: Zizewib (-43)
cousin: Pupyq (79)
name: Ovi
age: 74
gender: male
lifestyle: squalid
alignment: neutral neutral
vassal: Tesemakebi (100)
aunt/uncle: Hagimiqox (-82)
name: Hagimiqox
age: 37
gender: male
lifestyle: wretched
alignment: neutral evil
employer: Agegixuku (36)
niece/nephew: Ovi (-41)
name: Imibimataz
age: 76
gender: male
lifestyle: comfortable
alignment: neutral neutral
parent: Agegixuku (-100)
name: Nyle
age: 68
gender: male
lifestyle: wretched
alignment: chaotic neutral
cousin: Hyp (-65)
name: Zizewib
age: 34
gender: female
lifestyle: wealthy
alignment: lawful neutral
niece/nephew: Qogilatyji (-36)
employer: Agegixuku (30)
employee: Tesemakebi (-52)
name: Ile
age: 16
gender: male
lifestyle: wretched
alignment: chaotic good
sibling: Pocohyjep (12)
aunt/uncle: Qegalydu (45)
employer: Pocohyjep (-29)
name: Qehiqiqej
age: 69
gender: male
lifestyle: poor
alignment: lawful good
spouse: Qegalydu (87)
name: Omux
age: 72
gender: female
lifestyle: modest
alignment: neutral evil
name: Qegalydu
age: 15
gender: male
lifestyle: aristocratic
alignment: chaotic good
spouse: Qehiqiqej (58)
child: Pocohyjep (68)
niece/nephew: Ile (4)
name: Pocohyjep
age: 63
gender: male
lifestyle: wealthy
alignment: neutral evil
sibling: Ile (-8)
parent: Qegalydu (75)
employee: Ile (-6)