Dispatches From Neverwinter

A journal of my progress as I (attempt to) learn how to build modules for Neverwinter Nights.

Name:
Location: United States

Started playing Neverwinter Nights back in November '05 and got hooked. Tried to write my own module, but I just didn't have the time. Maybe I'll try again someday.

Monday, December 25, 2006

Yet Another Lesson About the Smallest Things Can Become The Biggest Headaches

It's Xmas day and I did not end up getting NWN2, but I did get a new graphics card so that when I finally do pick it up, I'll (hopefully) be able to run it. But anyway, over the long weekend I put in some time on the module, and finally created two new areas and started work on a third. I would have had more done, but I got very caught up in mapping out the course of the module in Paint. Doing this was not only useful, but necessary, as I now have a sense of how many exterior areas I need, where different encounters will take place, and what the terrain should look like in each area. However, I got a little too obsessive doing the map, and spent way too much time tweaking it and changing it and so on.

The three areas I worked on were an outdoor area, an abanoned house, and a cellar for the house. One of the more frustrating things I had to deal with was setting up a few triggered encounters of the sort where "If the PC has variable X set to number Y, then trigger the encounter, and then change a different variable so that if the player passes over the trigger again, it won't go off again." I've done this a bunch of times, but I've done it in different ways, and part of the problem is that I don't fully grasp how if/else works in conjunction with "GetIs" functions. I know that sometimes you want "GetIs" before an if/else statement and sometimes you want "!Get/Is" before it, but I'm having trouble sorting out how it works. I recently discovered a trigger wasn't working because I had the former when I should have had the latter, but every other time i've used the former.

Anyway, as it turned out my real problems weren't with that, but with paying attention to the little things. I couldn't get the first trigger to work until I realized that I had typed the variable the script was looking for in all lowercase when, in fact, the first letter should have been capitalized. The second trigger, however, nearly gave me fits. The idea was simple: when the PC walks into the house, he gets a variable put on him set to the value of 1. When he walks out, he steps on a trigger that checks for that variable, and then activates the encounter. Since the PC won't have the variable on him until he goes inside, he can pass over that trigger on the way into the house without setting it off. It seemed simple enough - and in fact, I'd done it before - but I simply could not get the thing to work. At first I thought it had something to do with the arrangement of the code, and so I copied a script that worked exactly the same way as I wanted this trigger to work, but it still didn't work. The variables matched, and everything looked ok. I finally figured it out by accident: after the encounter didn't trigger for the 10th time, I didn't log out of the game for whatever reason. Suddenly, my PC was attacked, but the attackers came from the opposite direction of the spawn point. I tried it a few more times, and got the same results - the reason it took them so long to show was because they were stopping to attack a bird. Then, I finally figured out what happened: when I was setting up the spawn point, I accidentally moved it off the edge of the area, at which point the game automatically puts it in the lower right corner. Instead of deleting it, I just created a new spawn point, figuring that it would automatically eliminate the old one. It didn't, and the monsters kept spawning at the original point. At least a half-hour of agita could have been avoided had I not made this one tiny mistake.

Desigining the interior of the house was easy, and it also wasn't too hard to figure out how to set up a secret trapdoor to take the player down to the cellar. Designing the cellar was a lot tougher, because I couldn't find a tileset that I liked. I finally ended up going with the kitchen tileset, which wasn't ideal because I had to make the area much larger than I liked. I could have gone with a one-tile kitchen room, but that has a fixed doorway, which I didn't want. I tried using some placeable walls to cover it, but that just looked stupid in the game. I also tried partitioning off a smaller section of the larger kitchen room with placeable walls, but that looked even worse. So I'm stuck with a large cellar. It took a bit of trial and error to set up a placeable ladder that, when clicked on, would take the PC back upstairs; although the code is simple, I put it in the OnClick event instead of the OnUsed event, and then forgot to change the script to use "GetLastUsedBy" instead of "GetLastClicked." Ai yi yi! But I finally got it all working, and was pleased at having done something new. The last thing I did was start putting down some placeables. Next, I have to finish with the placeables, and then I want to set up an encounter with a ghost. I just haven't decided how to trigger it yet. I might have it go off when the PC opens a chest, or I might have it go off when the PC picks up a piece of jewelry, or I might just have it activate when the PC passes over a trigger, but have it delay 30 seconds before firing.

Wednesday, December 20, 2006

Reworking

Did some work on the module last night that actually amounted to a reworking of certain things I had already done that I'd never been quite satisfied with. Specifically, I wasn't happy with the first area after the cutscene. In that area, the PC runs into a group of peasants being attacked by goblins. After helping them defeat the goblins, he learns that they're heading north for the safety of the castle. The PC also wants to go to the castle, but the peasants warn him that the goblins and other creatures are moving up fast, and that the road is dangerous, so the PC might want to head Northeast thruogh the forest instead, which is a longer trip, but potentially safer.

The problem I always had with this is that if the road isn't safe, then why would the peasants head that way. The excuse was that because they didn't really have any choice, since they couldn't go through the forest. That's fine, but the thing that bugged me is that after the conversation, the peasants head north and vanish, to simulate that they're moving on. However, if the PC does the same, he moves onto the next area, but the peasants are nowhere to be seen. That bothered me: if both the PC and the peasants are heading north, then why do they disappear? They're both on the same road, after all. For that matter, why doesn't the PC just travel with them?

After thinking about this, I decided to change things so that the instead of heading north to the castle, the peasants are now heading west to a neighboring village, to escape the monsters, which are coming out of the east. This actually resovled a couple of issues: since the PC's goal is to make it to the castle, he won't have any reason to travel with the peasants. Since the monsters are coming from the east, it makes it more believable that they might intercept the PC before he can make it to the castle (beforehand they were coming from the south, and yet for story purposes, they had to get ahead of the PC, even though the PC has a lead on them). And since the monsters are coming from the east, it makes sense that the peasants would move away from them, rather than heading in a direction where they know they'd likely be putting themselves in danger.

Changing the module to accomodate this largely involved resizing the area, adding a new road going west, and moving the peasants and some triggers and placeables. The most onerous part was actually one of the most trivial: replotting the flight path for the two blackbirds that I included for a little extra color. I had to do a lot of tweaking to make sure they didn't run into any trees. Then, when I tested the area, I discovered that my peasants were vanishing a few seconds after my character spawned in. It turned out one of the birds was passing through the trigger that destroys the peasants. I don't know why the bird would trigger it, but it did.

Other fixes involved rewriting some of the journal entries (including changing everything from first to second person) and conversations, and moving the south gate in Cheswick to the west wall, since it no longer made sense for it to be in the south wall. I also put up some signposts and discovered, to my irritation, that I don't know how to make it so that when the player "uses" the signpost it says "X - North" and "Y - West" with the former appearing over the latter. It's a minor thing, but very annoying. It's also annoying that the palette only has one roadsign placeable. Speaking of minor but annoying details, I realized that the reason the peasant women stops walking away if you talk to her, but the peasant men don't, is because the women have a custom script in their heartbeat event. It's a small thing, but details matter, so I'll have to set up the heartbeat script as a user-defined event. Fortunately, that's a fairly simple matter.

Sunday, December 17, 2006

Really and Truly Almost Finished With the Village

I think, finally, that all the problems I was having finishing the village of Cheswick have been overcome.

  • Fixing the trigger/conversation problem was simply a matter of putting in a ClearAllActions line. I don't know why this worked, but it did.
  • Crissa wasn't following because, as I suspected, I had a custom script in her OnHeartbeat event. I moved that to the OnPerception event, and that solved that problem. However, it created a new problem: if I tried to leave the village with her, but without Jocen, she wouldn't run up and initiate a conversation. So I eventually had to add a switch case to her UserDefined event that would handle the stuff in her OnPerception event script. Then I restored her OnPerception script to the default, and that problem was solved.
  • I ran into a few conversation problems, such as journal entries not being added, missing sound effects, etc... but they were just minor issues that were easily resolved.
  • Taking a cue from Saleron's Gambit, I added in more detailed descriptions of the NPCs. Unfortunately, this meant putting in a new conversation node in Jerym's conversation tree right at the start, and then cutting and pasting the existing conversation into that node. This broke all the links in his conversation. Fixing them all was a big pain in the ass.
  • The encounter triggers kept re-firing every time the PC passed through them. I eventually fixed this.
  • I decided to strip the cure light wounds potions the PC starts with and give him a medicinal broth to start with instead. I ran into a couple of problems with this, and eventually decided to just clear the PC's inventory at the start and then give the PC all the items I wanted him to have. I also stripped his gold and then had him start with a lot less (once again taking a cue from Saleron's Gambit).
  • I changed the trigger that fires when the PC enters the village to give a longer description, rather than a line of floating text. This meant changing it to an ActionSpeakString command. I also added a second trigger that does the same thing in the middle of the village, but which only fires if the PC makes a relatively easy listen skill check. In theory, it'll only activate once, whether or not the PC makes the check.
  • Did lots of minor tweaking, including changing music, changing some items in containers, adjusting the inventory in Jerym's store, adding descriptions, changing movement speeds of some of the NPC's, and so on.
The only things I might still have to do in the village is add some music to some or all of the buildings, and possibly tweak some of the items. I've done some testing, and so far everything is working the way it should. I think I can finally move on to new areas. I'll be happy to do so.

Of course, as old problems are fixed, new ones arise. I just discovered the cutscene isn't working the way it should. The NPCs just stand around instead of fighting, until they finally flee. This makes no sense at all. I haven't changed anything since I last tested it (I think). Also, I have no idea why the NPCs are ignoring the fighting part of the script but not the fleeing part. The script is obviously being executed, and the tags are obviously correct too, so what the hell could be causing this problem?

Friday, December 08, 2006

No Time to Work on the Module

It's been well over a week since I really worked on the module, and I may not be able to work on it again before the weekend after this one. I have a four day weekend starting tomorrow, but I'll be away for much of it and I have a lot to do. This is just a hectic time of year, and I'll probably be putting in OT at work, which means that by the time I get home, I won't be in the mood to work on the module.

As it is, I'm also feeling discouraged by the project. When I last left off, I had run into two problems that kept me from finishing the village. The first is that the trigger I set up in case the PC tries to leave the village with only one kid in two isn't working the way it should. It does make the kid initiate the conversation, but he doesn't run off at the end unless you talk to him a second time. Also, I decided that, instead of having the kids be henchmen, I'd have them follow the PC in the same way the mule does, since I got all of that to work. So I copied all the scripts I needed and tweaked them and put them where they should go. After a lot of mistakes, I finally got Jocen to follow the PC. However, I can't do the same for Crissa, and I have no idea why, as I've checked and rechecked the scripts to make sure they're ok. The only thing I can think of is that maybe the custom script in her heartbeat event is somehow messing things up, but I have yet to test that theory. I haven't even tried getting them both to follow the PC, or having one or both of them follow while the mule is also following. I'm really sick of working on this part of the module and frustrated that this has become so difficult to accomplish.

I've also been thinking a lot about the design and feel of the module. I just finished playing Saleron's Gambit Chapter 1, and I was really blown away. The module is practically a case study in how to bring a setting to life, and how to do a low-magic, low-gold, low-xp setting. These are all things I've been going for, except for low-xp, and now I'm reconsidering that aspect of it as well. I’m thinking of taking out the magic potions that appear early in the game, and reducing the amount of xp players get for kills. I don’t want it to go quite as low as Saleron’s Gambit, but I think it may be a bit high at the moment; I think I’m aiming to have the PC reach 3rd level by the end, depending on how long it ends up being. I may revise the areas to make them a bit more gloomy, as I don’t quite feel like the game is capturing the feel of tension I’m trying to instill. I also may copy the descriptive techniques from Saleron’s Gambit as well, although I don’t know how well they’ll translate over, since in that game the PC is surrounded by people he’s known all his life, whereas in my game, the PC is travelling through unfamiliar territory.

Part of the problem with setting the mood is that most of the module is supposed to be sort of tense and gritty, hence the low treasure/magic/xp. However, the forest area has a much more fairy tale feel, which is at odds with the realistic feel I’m trying to produce in the rest of the module. I’ve been wavering between which feel to go with for the whole module, but haven’t been able to decide. I think I might try to make the forest sinister and more foreboding, and try to achieve a dark fairy tale kind of feel. That’ll probably mean heavily revising the riddle challenge with the faeries at the end. On the one hand, I was never thrilled with this, as I don’t care for puzzles and riddles myself. However, I like the idea I had for the PC to potentially acquire different items along the way, which can be traded to make up for getting a wrong answer.