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.
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.
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.
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)