top of page
SpaceBackground.png
SpaceBackground.png

Developer Diary Week 5 – Dialogue, Mood, Energy Recovery, Maintainability, Idle, and Coworkers

  • Writer: gtristanitristani
    gtristanitristani
  • Jun 17, 2023
  • 8 min read

Another week is up, and I have quite a bit to report on, as evidenced by the rather lengthy title! I ended up getting work done in a few distinct areas, as they all worked together pretty closely. I’ll discuss them separately in the order below:

  1. Dialogue system rework

  2. Mood system implementation

  3. Unconscious/relax recovery

  4. Code maintainability

  5. Coworkers

  6. Idle roaming

First off, I wrapped up the Dialogue Rework. I’m going to start by briefly recapping what my plans were for it last week. I wanted the player to be able to choose more specific topics than always leaving dialogue up to random selection, so I planned to start by reworking the interact menu with a dialogue submenu, with the mock-up I made last week shown below. I also wanted dialogue to be even more heavily influenced by the NPC’s energy and mood. Particularly, I wanted the NPC to be short and never enjoy talking with the when certain conditions are met. This would involve decreasing affinity and increasing a negative mood when interacting with the player in this state, as well as overriding all other sub-banks when either condition is active, a bit similarly to the “Busy” dialogue behavior previously.

ree

I finished the logical implementation as I had envisioned it initially. Now, the player has a degree of control over what the NPC talks about, since they have the power to choose the topic. But this isn’t without its limits. As mentioned, there are three distinct conditions where this doesn’t happen:

  1. The NPC’s energy is dangerously low and they’re trying to rest.

  2. The NPC is busy at work and doesn’t want to be interrupted.

  3. The NPC is in a negative mood.

ree

If any of these conditions are active, they will override any other selection protocol. This comes with a decrease instead of the normal increase in affinity towards the player. When the player talks to an NPC while they’re in a bad mood, the interaction exacerbates the bad mood as well.


Overall, I think this change adds a lot to the system and its versatility! The end goal for this project is to have NPCs that live and act like interesting people in their own right, and to accomplish this, I think it’s important that the player is empowered to make decisions like proposing conversation topics when interacting with NPCs.


I had set a goal of implementing the mood system for NPCs, and I’m happy to say it and the proposed mood-luck system are now in place! When the NPC is in a mood and the player talks to them about it, it increases how much they’re feeling the mood, whether positive or negative. As mentioned earlier, villagers in a negative mood don’t want to talk with the player and lose affinity if interacted with in this state.


When the player gives a good or neutral gift to an NPC, a random positive mood of theirs will gain an increase. Similarly, if the player hits them, a random negative mood of theirs gains a drastic increase. Currently, these are the ways that the player can directly influence NPC behavior. For now, I think this is acceptable since even in real life you can’t directly force someone to have a specific mood, though I may add more ability for the player to adjust their mood in the future.

ree

I additionally implemented another feature: mood preferences. Each NPC can have a positive and negative mood that they will more commonly activate than others. This, and the percent of the time this mood should be chosen, can both be adjusted as public variables on a by-personality or by-NPC basis.


After this was all done, I moved back to the random mood adjustment system. As I had outlined last week, this system should activate three times every day, at times configurable by the user. At these times, the system would take each NPC and apply a major boost to a mood, a minor boost to a mood, a major decrement from a mood, and a minor decrement from a mood. This is all determined completely at random, including which moods are affected. This adds another sense of dynamic nature to the system, and makes the NPCs seem a bit more real. People can go through a LOT of unique moods in a day, and I’m glad the NPCs can now do the same!


With the mood system implemented, I came back to the question I asked last week: how will the NPC be able to naturally and consistently recover? I decided against implementing a new type of dialogue or player interaction to let the player determine when this happens. Thinking back, it just didn’t seem realistic, especially since the system currently encourages the player not to try to talk to the NPC while they’re feeling bad.

Instead, I fell back on my other plan of imposing a heavier energy drain when the NPC is in a bad mood, forcing them to rest and recover more quickly. When they relax or are unconscious, they will gain happiness and lose whatever negative mood value is currently highest, at a configurable rate.

ree

In order to do this, I of course had to implement the relax and unconscious states. NPCs will relax, which changes their animation to show them sitting on the ground, while not at work if their energy level is low. They will fall unconscious if their energy becomes dangerously low, even at work. In this state, they will gain back energy and positive mood, while losing any high negative mood values overtime. They’ll get back up and return to normal after their energy has reached the high level.


With all these implementations proceeding so quickly, I realized I haven’t had as much time as I would like to make my code easy to read and maintain. I ended up with a lot of unnecessary switch and if/else statements relating to the new mood system particularly. Even just clamping the values was beginning to get out of hand…

ree

Naturally, I tend to follow the approach of “get something working in a basic state, then improve on it later”. But with this project, I was so concerned with showing constant progress that I neglected that second step. I spent a bit more time organizing the code, particularly in regard to mood, so I could improve on how easy it was to read and adapt to change. For the mood system, comparing the different levels a villager has and making decisions based on it is something I do a lot. So I decided to make an array of pointers to these values, and ensured that their indices corresponded to the number of each Mood in the original Mood declaration.

ree

This change ended up turning the original code I showed to that below!

ree

Determining the current highest mood became simplified in a similar fashion, shown below.

ree

With the new relax and unconscious states, I also realized that I needed to make the state of an NPC and what actions they could take clearer to change through code. Particularly, I wanted to outline which states can transition into or out of an energy recovery state. I didn’t want to unnecessarily impose a check unless the transition was actually possible, after all. I finalized that logically, the NPC may transition from idle, walking, and hobby into relaxing. They may transition from working, idle, walking, and hobby into unconscious. They may transition out of these two states as well. In effect, if the NPC is currently talking or asleep, the check isn’t necessary to make. Looking at the status update loop for the villager, I realized there actually aren’t a lot of checks that need to be made in general, so I spent some time cleaning and organizing the transitions, shown in the picture below.

ree

I also finished making the coworker response sub-banks and implementing their behavior in the game. Now, NPCs are aware of other villagers with the same job as them, and can talk about them with the player. Similarly, if the player has hurt the NPC in question in the past, the villager is aware of this and will be hostile to the player. This creates a more drastic effect from the action of hurting another villager, which is what I had intended with the system from the beginning. They rapidly lose affinity towards the player when talking about this coworker. For the time being, however, I only want this affinity to drain when talking about the coworker that was hit. I feel it may be a bit too much to have them completely refuse to talk to the player about anything else afterward, though might change my time with more system experimentation and design in the future.

I also implemented a second pass at idle behavior. It was a bit awkward having the villager just follow me around everywhere, so instead, they now just walk to a random point in range when not busy, and idly roam about! I still don’t consider this a final state for idle behavior, but at least a step in the right direction.

ree

With all the systems I was interacting with, there were bound to be problems at some point. In adjusting the Dialog and Job systems, I ended up neglecting to think about how this would adjust prefab values. Particularly those regarding the dialog that should be activated. Unexpectedly, the dialog components were wiped clean of text! Thankfully, I had previous backups through my GitHub and was able to recover what I had written. But this made me think about what I would do if something like this happened again and for whatever reason I couldn’t recover my work. In addition to making a saved document with all of this dialog, I’ve started thinking about how I can protect against this overwrite in the system itself. Because of this, I’d like to spend time next week thinking about how the Dialog Bank system can be reworked to not specify each line of text as a component, but instead letting it read input through an outside source that Unreal Engine can’t adjust. A route I might consider is the format that Unreal Engine 5 uses to store prefab component values, with a snippet shown above. Perhaps it would be worthwhile to allow the option to specify this through a .txt file input?

ree

As a final note, I noticed a few bugs as well. To begin the villagers didn’t stop talking even after the dialog box was closed when receiving a gift, which I fixed by changing the textbox specifying the gift to only activate the gift reaction when the enter key was pressed. Additionally, there was a problem where villagers kept meandering even when the player was trying to talk with them. I was able to fix that by consistently checking if the player is trying to interact with the NPC, turning their rotation to look at the player and disabling meandering for this time.


Next week, I want to improve the DialogSystem’s code organization and setup more. I’d like to include additional bool arguments that specify whether the personality, job, or both sub banks should be searched for a response. This will allow me to reduce a lot of the current code duplication problem I have.


I also want to revise the widget that shows villager data. Currently, it has been getting out of position very easily. I would like it to look better and cling more closely to the side of NPCs, so will be taking some time to look at it next week.


For new features, I want to create the hobby system. Hobbies should be setup as having a link to a game object that is used to perform the hobby, and have a minimum and maximum number of minutes it should be performed for, so the time a villager spends performing a hobby can vary. Each villager should be able to have as many or as few hobbies as the user wishes to specify. This hobby should have a corresponding animation as well, that the Villager is able to activate while they perform that hobby. This hobby will increase a random positive mood while decreasing particularly high negative moods, but also degrade energy at a different, potentially higher rate. This system is entirely new, and I want to take my time implementing it in a way that is versatile and modular for easy adjustment, understanding, and extension in creating new hobbies.


As with before, I would really appreciate it if you checked out my GitHub, linked below, if you're interested in experimenting with this project! It would be a lot of help to hear feedback. Thank you, and please look forward to next week's update!


Find the project at https://github.com/grist-maker/NPCVillagers

 
 

©2022 by Gabrielle Tristani's Portfolio. Proudly created with Wix.com

bottom of page