Building an NPC Dialogue System from Scratch
I built a branching NPC dialogue system for my game - head tracking, choice memory, inventory integration, and all the bugs that came with it.
The Challenge
I’ve been putting off building an NPC dialogue system for Scrapconomy because so much of the story is driven by dialogue. If this doesn’t work, the game could feel lifeless. So I finally sat down and tackled it head-on.
The Game Plan
My approach was to build a simple test level to validate all the core features I need. The scenario: talk to an NPC named Steve, insult him, apologize, and then he gives you a key to open his secret chest. It's a simple premise, but it tests everything. Talking, making choices, the NPC remembering those choices, and receiving objectives and items.
Building Steve
I modeled and texture-painted Steve in Blender, gave him a skeleton, and set up an idle animation through Mixamo. Then I used Blender’s custom properties system as a kind of data map. Godot reads those properties to find the NPC’s ID, locate their script folder, and load their dialogue script and voice files.
The Dialogue Script Format
The branching dialogue follows a specific format. It looks more complicated than it actually is. The important thing is staying organized. Writing branching dialogue honestly feels like writing a choose-your-own-adventure book. Once I settle in, I actually really enjoy the process.
Head Tracking & Camera Cuts
In Godot, when an object is identified as an NPC through custom properties, the engine searches for two things: a camera parented to the NPC for cinematic dialogue shots and the NPC’s head bone so the NPC slowly turns to track the player. This little detail helps the game feel more alive.
The head tracking system had way more bugs than I expected. Player position, NPC position, head rotation, and range limits to prevent unnatural movement. I spent about three hours buried in documentation and code before I finally got it working.
Breaking It Into Pieces
This isn’t the kind of system you build in one sitting. I broke it into chunks so I could feel a sense of accomplishment each session:
- Night 1: Coming up with the script format
- Saturday evening: Head tracking system
- Next session: Building the dialogue UI with typewriter text effect
- Final night: Connecting dialogue to inventory and objective systems
The Result
Seeing it finally work made everything feel worth it. It’s not a perfect system. There are no face animations yet, but it’s enough to tell the story I’m trying to tell. At the end of the day, that’s what it’s about. Creating something others get to enjoy. Or, you know, maybe we’re just making silly games.
