You are here

Bounty Hunters In Persistent Worlds - A Study on NPCs in Neverwinter Nights (Part Two)

Author: 
Brian P. Gefrich

Bounty Hunters In Persistent Worlds: A Study on NPCs in Neverwinter Nights



by Brian P. Gefrich

July 17th, 2001

Part II: Variables, Investigation, and How Sometimes Bounty Hunters Get Lost

Preface

In the first part of this discussion, I laid out an ambitious plan for implementing a NPC Bounty Hunter in a persistent world. I would like to thank everyone who gave me constructive criticism on the article. The main thought relayed was on the complexity of the matter at hand. I think I have a unique perspective on the abilities of NeverWinterNights and NWScript. I view it as an envelope.

Within the envelope will be the functions created by the wizards. Here is your NPC. On a radius trigger around him, he converses with you. If he doesn't get the answer he wants, he attacks. So on and so forth. On the edge of the envelope will be modifications of the scripts created by the wizards. Adding a little spice to the game, so to speak. I want to exist on the other side of the envelope, developing fantastic situations and making the scripting language conform to it. You have probably heard managers or efficiency experts refer to this as thinking "outside the box." Well, that's what I want to do. These are articles to show you not specific ways to code new ideas, but instead how to stucture your thoughts to make it work.

The Events

NWScript is event driven, meaning that certain things will be caused to happen by other things (events) happening. Your world will just exist, with the pathfinding script telling the ogre to walk in a circle around his bridge. When you come close enough to him (trigger) he attacks, after some dramatic posturing first. This event triggers something else to happen. Without triggers, your world would just be a chat program with fancy graphics. So, when setting down the long, winding path of scripting, we must look at our program as a series of events. That is the course followed here.

In the first chapter, we listed the events that happen:

  • The Trigger: Death of a bad guy
  • Brother finds out
  • He contracts a bounty hunter
  • Bounty Hunter attempts to track the PCs
  • Bounty Hunter finds PCs

    OR

  • Bounty Hunter gives up

It's a pretty simple outline of what's going on. Let's look at each event.

The Situation

Let's set our scene first. Our hero, a PC named Darius, has been sent out on a quest to stop an evil tyrant called Falurr who is terrorizing the region. So Darius trudges through the process of killing off all the gaurds and engaging in fierce and bloody combat with Falurr. Well, lets assume he wins, because otherwise my article doesn't go anywhere. Falurr has a brother named Fiersol, an evil warlord from the south. He learns of his brothers death and sends a bounty hunter to find the offending PC and extract slow and agonizing revenge.

The Trigger

This is the big one. The event that sets off everything. Darius kills Falurr, who dies in an overly dramatic way, with lightning and puffs of smoke. XP is awarded, Darius gets the magical staff that Falurr was holding, plus he retrieves the powerful artifact that Falurr had stolen from the temple, and so on and so forth. But what is going on behind the scenes is what's important.

In the script for this quest would be the conditional function OnEventDeath(Falurr). (*Now, with all the code, I am using what I believe the correct usage will be, or I am just making something up. The important thing is the theory here*) When this happens, it triggers our bounty hunter script, which will launch into the creation and execution of the BH. And that's it. Without it, nothing happens. It's that simple. We would use one of the die rolling functions to get a random number. If this die roll, (let’s assign it to a variable. Say…nBHCreateRoll) is within the range you set, Ta-daa! You have a bounty hunter.

The Creation

Now that our event has been triggered, we have to create the bounty hunter. Not going into specifics of the NPC creation process (which we know little about, apart from seeing the wizard in action in videos), there are a few variables we want to initialize for this to work.

  • Detective skill: This will be the key factor in determining his success in finding you. A simple randomly determined integer will suffice. We will use this later.
  • The Bounty's Bounty: Bounty Hunters have a way of pissing off people, so it is possible that this particular hitman has a price on his head as well. This will be important if the PCs kill him.
  • A starting location, somewhere a good distance away from the location of the trigger.

We’ll use a function BHCreate( ). This little snippet of code will set the above factors, in however we want to set them. The detective skill would be a random number modified by the level of the PC it’s hunting, and the bounty would just be picked from some presets. Now, this will all be instant, so the start location will be set off of the place where the trigger happened. We don’t want it too close, because then Bounty Hunter could walk in from the next room, shouting “Ah-ha! At long last I have found you!” So we just regulate this by making sure it’s not too close.

Also, this function would create all the stats, weapons, etc for the BH.

The Hunt is on

So, we have a bounty hunter, standing around, doing nothing. Where do we go from there? Well, he has to start figuring things out, and acting all bounty-hunter-esque. The next step of our process is to see what he knows. We roll his detective skill against a preset difficulty. If he succeeds, then another variable (to represent his progress) is incremented by one. When we attempt Pathfinding, this progress indicator is added to the roll.

An example…

Our variables:

nBHDetective //This is our detective skill

nBHProgress // Our progress indicator

Then we would get the PC’s level, and use a die roll to get our detective skill. To even this out with our character (a stronger character would get a better BH sent after him/her) we would halve the level and add it to our die roll to get the end detective skill.

Now, we roll again, adding our detective skill to it, and test it against a target number ( a simple if/else loop). If we are successful, then:

++nBHProgress;

Meaning he figured something out and is on the right track.

Using a time function, we would have him randomly test again. We would also run this process again if he meets any PC’s or NPC’s.

A more advanced script (that I’m not going to get into now) would test whether or not the PC or NPC contacted by the BH has seen the target. A short dialogue would be an easy way to do that, because then a friendly PC could lie his way out of it.

If the BH was successful in his detective roll, we would move him in the direction of the target. If not, he would move randomly, or along his last direction.

I could write an entire chapter or more on AI, Vectors, and pathfinding, but instead, I’ll just tell you simply what happens. If he is successful, the direction he’s traveling in is moved more towards the target. He might get it dead on, or he might just be closer. This “humanizes” it a bit. Then he moves along until time or contact triggers him to stop.

Here’s an interesting possibility…the bounty hunter rolls very low against his detective skill. He picked up a wrong clue, or just misjudged something? Well, what then? Then , we create a completely random vector for him to move along, and he wonders off, getting lost. The way he doesn’t always go right towards the target on a success would mean that it could take him a while to get back on track.

Definitely not something Boba Fett would do, but then again, our bad guy isn’t Darth Vader.

Somewhere down the road, the BH may begin to doubt whether he will find you, and whether it’s worth it. He would test a random number against a set target number, and if the roll hits the target number, then he gives up, we release the NPC, and that’s that. But for fun, we’d would make the probability really low.

We could also change this with time, so after months of real time chasing, he would be more likely to give up.

The other factor that could stop him in his tracks is actually finding you. Eventually, he collects enough clues, searches long enough, and ends up walking right up to you. Well, what happens now? This would trigger our next script, which has a sort, threatening, standard issue bad guy dialogue, and he attacks the PC target.

Fun, eh? The script terminates with either the death of the PC or the BH. If the BH dies, the PC can collect a bounty on the BH. Turn about is fair play right?

Another interesting thing to add would be to keep the BH alive, and moving around. Maybe one of the target’s friends could extract revenge, or the BH, now more experienced, could be used in another situation.

Well, we have gone into how we would make it work. In the next installment, I will have a small game that puts this little Bounty Hunter idea to the test. I’ll break down the code used (just C++, not NWScript for the most part) and how I made it work. I’m about 50% there, so look for it sometime soon.

Any questions or comments can be sent to me and I’ll be sure to get back to you.

Migrate Wizard: 
First Release: 
  • up
    50%
  • down
    50%