This week, my focus was to continue improving the player experience when starting a new game. I am working on adding a few interesting quests based on interactions with NPCs in the starting city. I’m also preparing the release of Pre-Alpha Test 4, so a lot of my time went into fixing bugs.

New features

Conversations are more dynamic than before

  • Shared text arrays have been added to conversation tree nodes; they can be inserted at any point during the conversation. In other words, this prevents having to repeat text between nodes. It also enables me to write different leads just before using common text, so that NPCs have more subtle response to the player’s choices.
  • Dialogue choices can now have requirements. For example, intimidating an NPC require a certain strength rating; invoking a deity will require a certain piety rating. I will eventually add traits to the character creation; some of these traits will unlock unique dialogue selections.
  • Added interaction flags that can be set during conversations or outside conversations. This applies both to conversations (which pause the game to offer choices to the player) and dialogues (text bubbles over NPCs during gameplay). This makes the NPC able to “remember” certain actions or conversation choices made by the player and react accordingly.
  • NPCs can now join the party temporarily or permanently based on the player’s choices during conversations.
  • Added several new variables for conversation and dialogue text, such as %TIMEOFDAY%, %GENDER% and more.
  • Divided Kingdoms is a highly moddable game, so you will be able to create your own conversations for your custom campaigns. I have included an example of a YAML file defining a conversation at the end of this post.
  • I am preparing a detailed post on how conversations work in Divided Kingdoms; this will probably be one of the first in-depth posts for this blog.

Work In Progress: Citizen now look for entertainment at the end of the day

  • A typical NPC schedule will make them go to the nearest tavern to have a few drinks around 6 PM. Once they get to the tavern, they go sit to the nearest place and ask the innkeepers for something to eat. I’m still working on getting the innkeepers serving food correctly, it’s a still bit buggy at this time. Then, before midnight, they go back home for a good night’s sleep.
  • I added several new dialogue types for this, such as WantsDrink, WantsFood, Drinks, Eats, TavernBanter, TavernGreet, and more. I really care about adding unique dialogue types for specific situations, because that is one of the things that make NPCs much more believable.
  • In a future alpha version, NPCs will start interacting more with each other. I am planning to add more depth to the relationship system between NPCs, so that they can develop over time. Hopefully this will end up in emergent behaviour and interesting (and hopefully, unexpected!) results.

Other improvements

  • I added signs at the entrance of each important building to help guide the player. I had to merge meshes at runtime to make the mesh collider work properly, so that was more complicated than expected. For now the signs are pretty basic, but soon enough I will add plates on walls (similar to Ultima 7) and other interesting ways to identify buildings.
  • I fixed several bugs in preparation of releasing the next version of the game, Pre-Alpha Test 4.

GIFs for this week

Conversations are more dynamic than before

Click here for a larger version of the GIF

Citizen now look for entertainment at the end of the day

Click here for a larger version of the GIF

A quick demo of how signs work, with zoom demonstrated

Click here for a larger version of the GIF

Take care, and see you next week!


Addendum

Here’s an example of a YAML file defining a conversation:

- Id: "act1_quest_harold"
  StartNodes:
    - NodeId: "pissedoff_0"
      RequiredKeys: ["HasPissedOff"]
    - NodeId: "met_0"
      RequiredKeys: ["HasMet"]
    - NodeId: "firstmet_0"
  CommonText:
    - Id: "intro_firstmet"
      Text:
        - "<d>You see a middle-aged bearded man sat on a bench, sharpening his sword. He is wearing a green tunic with leather pants.</d>"
        - "Hello there, stranger! The name's %NPC%, and I'm pleased to meet you. How's the %TIMEOFDAY% going for you so far?"
    - Id: "quest_explanation"
      Text:
        - "<d>%NPC% coughs a bit.</d> So here's the story. I've heard rumors that a group of lizardmen have recently moved to the deeper levels of the sewers. At first, I didn't believe those rumors. Lizardmen? In this town? 

<d>He looks perplexed.</d> But then I met Rowan, the town's innkeeper. He personally told me he saw one go by his home window during the night."
        - "<d>He starts to shout loudly.</d> Can you believe this? Stinking lizardmen, living right here in this town! Someone must get rid of them!"
        - "<d>He clears his throat and speaks a bit softer.</d> I know they're not a menace to us, at least for now. But I like to get rid of things that don't look human. Especially when they are disgusting lizards! 

<d>He studies your face, waiting for a reaction from your part.</d> You must agree with me!"
        - "<d>%NPC% seems to want to say something, but is interrupted by a series of coughs.</d> Bloody hell, will this cough ever go away? <d>He tries to clear his throat.</d>"
        - "Anyway, I suggest that we go explore the sewers together and teach them lizardmen a lesson they won't forget. We will return to town as heroes and we'll get richer in the process. <d>He looks anxious to know your answer.</d> So, what do you think?"

# -------------------------------
# First Meeting

  Nodes:
    - Id: "firstmet_0"
      NPC:
        - Text:
          - "$intro_firstmet"          
      NodeLinks: ["firstmet_1-1", "firstmet_1-2", "firstmet_goodbye"]
    - Id: "firstmet_1-1"
      Player: "I heard you complaining about lizardmen. What's the story about them?"
      NPC:
        - Text:
          - "<d>He bangs his fists on the table loudly.</d> Ah HA! Straight to the point. I like you already!"
          - "$quest_explanation"      
      NodeLinks: ["firstmet_2-1", "firstmet_2-2", "firstmet_2-3"]

    - Id: "firstmet_1-2"
      Player: "What do you do for a living?"
      NPC:
        - Text:
          - "<d>%NPC% lets out a bold and greasy laugh.</d> Well, I am an adventurer... just like you, I guess. I'm looking for someone to help me carve some lizardmen skin. Are you interested?"
      NodeLinks: ["firstmet_1-1", "firstmet_goodbye"]

    - Id: "firstmet_goodbye"
      NodeType: Goodbye
      Player: "I'm sorry %NPC%, but I need to leave."
      NPC:
        - Text:
          - "<d>%NPC% looks disappointed.</d> What, already? I wanted to talk to you about getting rid of lizardmen in the sewers. Do come back if you change your mind."

# ________________________________________________________

    - Id: "firstmet_2-1"    
      NodeType: Goodbye
      JoinsParty: true
      StartsQuestId: "act1_kill_lizardmen_in_sewers"
      Affects:
        - AffectType: Reputation
          Modifier: 25      
      Player: "You are right, these lizardmen must be dealt with. Come with me and let's get rid of them!"
      NPC:
        - Text:
          - "<d>%NPC% stands up and looks ready to go.</d> Yeah, that's what I'm talking about! I can't wait to hang a lizardman head in my house! Let's go!

<d>%NPC% has joined your party!</d>"

    - Id: "firstmet_2-2"    
      NodeType: Goodbye
      Affects:
        - AffectType: Reputation
          Modifier: -15
      Player: "That is a terrible idea. I won't attack a species that's not agressive towards humans."
      SetsFlags: ["HasPissedOff"]        
      NPC:
        - Text:
          - "<d>%NPC% gets suddenly angry.</d> Are you serious? You are defending these ugly creatures? What is it with people these days! BEGONE!"

    - Id: "firstmet_2-3"    
      NodeType: Goodbye
      Affects:
        - AffectType: Reputation
          Modifier: -5
      Player: "Well, I'm not so sure that's a good idea. I have other things to do."
      NPC:
        - Text:
          - "<d>He pounds his fist on the table and shouts.</d> What can be MORE important than getting rid of those lizardmen? They have no place here! <d>He throws his hands up in the air.</d> Whatever, I'll find someone else to do the job. Begone!"      

# -------------------------------
# Already Met

# TODO: Check if the player has heard about the quest or not and offer slightly different dialogue.
    - Id: "met_0"
      NPC:
        - Text:
          - "<d>%NPC% recognizes you and frowns.</d> Ahhh, it's you again. What do you want? Did you make up your mind about going into the sewers with me to kill those lizardmen?"  
      NodeLinks: ["met_1-1", "met_goodbye"]        

    - Id: "met_1-1"
      NodeType: Goodbye
      JoinsParty: true
      StartsQuestId: "act1_kill_lizardmen_in_sewers"
      Affects:
        - AffectType: Reputation
          Modifier: 25      
      Player: "I changed my mind. You are right, these lizardmen must be dealt with. Come with me and let's get rid of them!"
      NPC:
        - Text:
          - "<d>%NPC% stands up and looks ready to go.</d> Yeah, that's what I'm talking about! I can't wait to hang a lizardman head in my house! Let's go!

<d>%NPC% has joined your party!</d>"

    - Id: "met_goodbye"
      NodeType: Goodbye
      Player: "I might be interested in your offer later... but I'll leave you for now."
      NPC:
        - Text:          
          - "<d>%NPC% looks disappointed.</d> Come back later if you change your mind. A lizardman's head would look good in my house. <d>He takes his sword from his holder and starts sharpening it.</d>"

# -------------------------------
# Pissed Off

    - Id: "pissedoff_0"
      NodeType: Goodbye
      NPC:
        - Text:
          - "<d>%NPC% looks up at you and throws his hands in the air.</d> Why are you wasting my time? If you have no interest in killing lizardmen, leave me alone!"