Game Sandbox II : How to Talk to an NPC

This entry was originally stored in my personal blog engine, but has been imported into WordPress.

There’s a woman walking near the entrance to Coneria Town, and whenever someone talks to her, she says “Welcome to Coneria.” She’ll be saying the same thing until the end of time, her words hardcoded into thousands of Final Fantasy I NES cartridges. That’s the traditional approach to NPC interaction in RPG games, and that’s what I’m trying to avoid in my engine.

Michael Moore, in his Basics of Game Design (yes, yet another book), described a few dialogue options, most of which fall under the category of “branching dialogue.” For instance, here’s the pseudocode for changing the words of a minor NPC:

	PRINT "Welcome to our town."
	PRINT "I hope you're enjoying your stay."
	PRINT "I heard a rumor that the kidnapped princess was taken into a cave in the north."
	PRINT "Heroes like you are always welcome in our town!"

This is a lot of coding for such limited functionality. And if you want to increase NPC responses and interactivity, branching is going to take up a lot of time. However, I found a simple, low-code way of implementing rich NPC interaction, and I found it in the most unlikely of places – an old SNES game, Shadowrun, that I last played many years ago.

Shadowrun had an interesting way of interacting with NPCs. Basically:

  1. When you talk with an NPC, aside from the standard response, you have access to a list of words/topics.
  2. You can ask the NPC about any these topics.
  3. NPC conversations can add more topics to your list, which can in turn be asked about.

This gave the game, I thought, an extreme flexibility. Moreover, you can use available topics as sentinels in the game (e.g., until someone mentions a location in conversation, you won’t be able to visit it).

When I turned this idea into code, I realized how centralized yet flexible this approach is. A simple example will suffice. You can store the words and their availability in a JSON object, as well as the responses each character will give to them. So, this is a list of topics, but are only available when available = 1:

var topicWords = [
	{"word" : "dead man", "available" : "1"}
	, {"word" : "time of death", "available" :  "1"}
	, {"word" : "the stranger", "available" :  "0"}
	, {"word" : "work crews", "available" :  "0"}

NPC responses are stored in a similar manner.

var npcResponses = {
	"jera" : {
		"dead man" : {
			"response" : "I never got his name; the stranger never gave it to me. Or his."
			, "reveal" : "the stranger"
		"time of death" : {
			"response" : "Only minutes after he arrived, sometime after midnight."
			, "reveal" : ""
		"the stranger" : {
			"response" : "He claimed he was staying at the Pathway, but he wasn't there."			
                      , "reveal" : ""
		"work crews": {
			"response" : "Yeah, the stranger claimed they were on a work crew. That's it."			
                     , "reveal" : ""


The screenshot I’ve included shows, for instance, a useful NPC conversation. While conversing with an NPC called “Jera,” the player just asked Jera what he knows about the “dead man.” The program responded with the data stored at npcResponses.jera.[dead man].response.

As an added bonus, using the data at npcResponses.jera.[dead man].reveal, the program updates the “available” variable for “the stranger.” Now, the player can ask Jera – or any other NPC in the game – about that topic.

This approach, as simple as it looks, has the potential to create extremely rich dialogue without resorting to long dialogue branching code. All you need to do is update the JSON object.

The approach isn’t perfect. As I recall from Shadowrun, the list of available topics can get really long, so you take a long time scrolling through and asking about topics. However, that’s a small price to pay for good NPC interaction.

Next I’ll create a central JSON object to control the game flow, movement between map scenes, and event triggers. And, hopefully, to add a good save system.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s