<p>People are what makes dynasty simulators interesting and this episode will be about them. There isn’t much code this time, mainly just how data is organized. Topic is long and split over several episodes.</p>
<p>Some people in game are controlled by computer, while some are controlled by player. There’s no difference on what each can do in game, computer is basically just filling in for players when there aren’t enough players.</p>
<p>There’s plenty of data about people, spread over several entities and database tables. Main one is <code>Person</code>, which stores name, gender, sex, date of birth and some stats (and then some more).</p>
<p>There are lots of various ways of naming people and I chose to model three for the starters:</p>
<pre><code>data PersonName =
    RegularName FirstName FamilyName (Maybe Cognomen)
    | SimpleName FirstName (Maybe Cognomen)
    | RegalName FirstName FamilyName RegnalNumber (Maybe Cognomen)
    deriving (Show, Read, Eq)</code></pre>
<p>The higher the rank, more complicated names you tend to have (for some reason). Later on I’ll try and see if I can add more varied names, like matronyms and patronyms.</p>
<p>Sex and gender I’m modeling with simple system of two enumerations, sex can be <code>Female</code>, <code>Male</code> or <code>Intersex</code>, while gender has values <code>Man</code>, <code>Woman</code>, <code>Agender</code> and <code>Nonbinary</code>. System is coarse, but should be enough to get started with the game. Later on, this can be expanded to more nuanced system.</p>
<p>Traits are defining features of people. These include things like brave, coward, ambitious, content, honest and such. Values are binary, character either is brave or not. And character can’t be brave and coward at the same time.</p>
<p>Relations are modeled as <code>PersonRelation</code> and thus stored in <code>person_relation</code> table:</p>
<pre><code>Relation json
    originatorId PersonId
    targetId PersonId
    type RelationType
    visibility RelationVisibility
    deriving Show Read Eq</code></pre>
<p>I find this corner of the puzzle particular interesting. This models who is parent or child, who is friend or rival. Interconnected web created by relations isn’t completely visible to players (or any other person in game). Relations have visibility, modeled as <code>RelationVisibility</code>, which tells how visible it is. Public ones are known by everyone, family relations are limited to small group of people and secret relations are only known by those who are in the fold. One aspect of the game is acquiring this information.</p>
<p>Intel is modeled as <code>HumanIntelligence</code> and stored in <code>human_intelligence</code> table:</p>
<pre><code>HumanIntelligence json
    personId PersonId
    ownerId PersonId
    level PersonIntel
    deriving Show Read Eq</code></pre>
<p>Essentially it just lists which character has what information about certain other character. So when displaying information to players, this table has to be referenced in order to know how much to reveal to them.</p>
<p>Different types of intels are listed as <code>PersonIntel</code>:</p>
<pre><code>data PersonIntel =
    Stats
    | Demesne
    | FamilyRelations
    | SecretRelations
    | Opinions OpinionIntel
    | Traits
    deriving (Show, Read, Eq)</code></pre>
<p>Person related data is sent back to client in <code>PersonReport</code> record (I’m not copying it here as it’s relatively large). We can have a look on how one field is processed.</p>
<p>For example, in case of traits. <code>PersonReport</code> has field <code>personReportTraits :: !(Maybe [TraitReport])</code>. Exclamation mark in the beginning of type instructs Haskell that this value should be computed immediately when record is created and not left for later. I’m doing this as I know for sure that it’ll always be used and there’s no advantage on delaying computation for the time when it might be needed.</p>
<p>Report creating (high level):</p>
<pre><code>personReportTraits = if Traits `elem` targetIntel
                        then Just $ traitReport &lt;$&gt; targetTraits
                        else Nothing</code></pre>
<p>That first checks that <code>Traits</code> level of intel is available and then creates list of trait reports (one for each trait person has). These have things like trait name, description, trait type and how long the trait is valid. Having separate name and description fields makes it easier to work on client side as I don’t have to come up with descriptions there anymore. I can just use what the server sends to me and be happy.</p>
<p>Comments, questions and feedback are welcome. Best way to catch me nowadays is email or fediverse where I’m <code>Tuula@mastodon.social</code>.</p>
