Jump to content

The Black Scourge of Candle Cove -- Tchos' development diary


Tchos

Recommended Posts

I spent a day going through the other 27 areas that, unlike the docks, can be opened without crashing the toolset, and both took note of their area tags and any existing area scripts, and added references to nonexistent scripts in the rest of the area script slots, for future contingencies.

It wasn't until I started doing this that I finally understood something that had eluded me since the beginning, regarding areas and their tags. I had been using the GetArea() function in my scripts, but that's a roundabout way of getting the area by checking an object and returning the area the object is in, so I didn't see why I was having to enter a tag on my areas when the function didn't even use the tag. I didn't understand that an area itself is an object, and so I should have just been using GetObjectByTag(), using the tag of the area.

I also wrote a little generic activation script so that I could have a single item that I could drop to start a new quest. That was the plan, anyway, but I can't really make it a single item, because each one needs its own description and icon, so it's more of a template than a generic multi-use script. But the idea is just to have a script in place to help me add quests in other ways while you're out in the field.

Doing more work on the undersea cave, and I needed some primitive stuff for decoration. Now, I have to be careful with these two races, the kuo-toa and the sahuagin. Neither race is unintelligent. They typically have above-average intelligence (average 13 for kuo-toa and 14 for sahuagin). Sahuagin are described as building cities, having barons and kings, and strong communities. However, sahuagin are water dependent and can't be out of the water for longer than a short raid on coastal villages, and this module does not show their underwater communities. Thus, there will be relatively few sahuagin in this cave, scouting around, with out-of-water bases and camps that are hastily and crudely made.

Kuo-toa, on the other hand, are amphibious, and are described as living on dry land in places with pools for recreation and spawning, so they do indeed have housing that the player will see. They're described as building great temples to their god Blibdoolpoolp. Despite their intelligence, though, they're also described as insane and fanatical, so this should be reflected in their architecture and settlements. "What goes on inside the inhuman minds of these cold-blooded creatures defies contemplation, and what ancient horrors they consort with in the deepest chasms of the world are better left unknown." (Description of kuo-toa from Drow of the Underdark.) So, mad devotees of Lovecraftian horrors. And, of course, kuo-toa and sahuagin hate each other.

What I'm trying to find is information on what the kuo-toa temples look like or what materials they're made from. Given their fanatical leanings, I imagine the best of their work would go into the temples, to the detriment or exclusion of their common dwellings. They also raise their young in pens, sorted by age and ability, after they're old enough to leave the spawning pools. For the information, I'm referring to Drow of the Underdark, Underdark (campaign accessory), and the Monster Manual. I also have Gary Gygax's module D2: Shrine of the Kuo-toa on hand, which I haven't read through yet, but which looks like it has some of those living arrangement and architectural descriptions that I want.

NWN2ToolsetLauncher%202013-05-25%2018-28

Anyway, I made some standing torches of a sort I didn't see in the toolset. Three variations: one relatively straight, and the other two increasingly crooked. Should provide a good variety when combined with rotations, sizing, and sinking into the ground. I also made a larger version of the torch fire VFX, since the stock one is too small and doesn't completely cover the combusting region.

Link to comment
Share on other sites

  • Replies 254
  • Created
  • Last Reply

Top Posters In This Topic

Today I examined the Legends Banter scripts to see how Marshall was handling the On Perception barks. Most of the plugins rely on a database, since they're for a persistent world, and this is one of them.

 

The way it works is to leave the default perception script alone except to add a line to fire another script, which checks what kind of perception event happened, and picks a line from a database to bark in response to it.

 

I combined the necessary functions into one script to use to replace the default perception script, which optionally fires the default at the end of it. I changed the database dependency to instead fire conversation files, where you can put whatever conditions or randomness you want. I also added a couple of variables to the list of variables you can put on the NPC, to control talk volume and whether to fire the default.

 

In my tests, it seems to work fine. I expect Shadow Thief: Crimmor has a much better-developed perception system, but I think this is sufficient for my needs. It fires different conversations if the NPC sees you, or hears you but doesn't see you, or when it no longer perceives you.

 

Now, I've heard here and there that anything you put in a perception is risky and may not fire, but I don't know what sort of things that applies to. One thing I was thinking of was having a group of NPCs gathered together with a nearby ipoint controlling their talking idle animations on a heartbeat, perhaps with bark strings as well. On perception, I would destroy the ipoint so that they would no longer use the idle animation or speak any more barks, and they would speak one battle cry bark and engage the PC in combat. Any reason why that wouldn't work?

Link to comment
Share on other sites

When I sneak around the NPC with high listen skill, he says "I hear you", and while I'm still in that same range, if he happens to succeed with a spot check, or I unstealth, he'll say "I see you." Additionally, when I use a Dust of Disappearance while standing right in front of him, after he has already spotted me, he says "I can't see you anymore." (These are the messages I put in the conversations I used for this test.)

 

An illustration of what I mean:
http://www.youtube.com/watch?v=d-xt5wZZwWI

 

Here's another little demo I whipped up to show what I had in mind for using this script. Depending on the quest stage, these bystanders make various observations about the PC as she passes by.

In this demo, they're all using the same conversation, but you can specify any conversation for each one, so each one can be different if you want. I gave 3 possible barks for each of 3 quest stages. The conversation file checks the journal stage for the quest and selects one of the possible lines for that stage with gc_rand_1of(). The barks are separate conversation files than their normal conversation that fires if you click on them, though of course you could specify the same one if you wanted.

Since the selections are random, there are some repeats, as expected.

Since they're barks, I had to make a modified version of gc_journal_stage() because that script relies on there being a PC Speaker, and there isn't a PC Speaker when they're using SpeakOneLinerConversation().

http://www.youtube.com/watch?v=BZXCZe4p64k

 

Here, I'm using the perception script from before for a stealth environment, where a guard without any special spotting skill is aided by a guard dog.

For a more complete result, I would make it so that instead of the guard threatening the thief when the dog starts barking, the guard would throw some dust of appearance down to make the thief visible, and then go on with any other actions.

It could start a timer where after issuing a warning, the guard and dog would attack unless the thief backs off, and/or spawn an ipoint to rapidly check proximity and have them attack if the thief gets within a certain distance, destroying the ipoint if the thief backs off. And, of course, any hostile action would have to turn them hostile, too.

Video demo

The audio's a little quiet on the dog bark. It's a stock NWN2 sound file. Also, when I convert these to a compressed format to upload to Youtube, it delays the audio about a second. I don't know what format wouldn't do that and still maintain high visual quality.

Link to comment
Share on other sites

Since I started adding those perception barks, I also added death barks. For quest NPCs, I'm making the chance for them to say something 100%, but for non-quest NPCs, it's a smaller chance.

Since I was adding these, I also added them for monsters. The trouble is that some monsters don't speak Common (even broken Common). Also, I couldn't find any good lists or reference materials for languages like Aquan and Undercommon. I found plenty of Drow word and phrase lists, but the language spoken by the typical Drow is not the same as Undercommon -- it's a hybrid of Undercommon and Elvish, and tends to look more like Elvish to my eye, and unlike the very, very few examples of Undercommon words that I was able to find.

At any rate, I wrote a script to generate phrases from a lexicon of words -- sentences between a minimum and maximum number of words, with a randomly-selected punctuation at the end.

The only caveat is that drow is a playable character race, and drow should automatically understand Undercommon, and can know Aquan as a bonus language, but they won't here. Other races and classes should also have the option of knowing some of these languages.

In this example, I have them speaking 75% of the time just to show the variety of phrases they can speak, but in actual gameplay I would have the barks appear at a lower frequency.

The group of sahuagins is speaking my representation of Undercommon, the water elementals are speaking my representation of Aquan, and the kuo-toas are speaking my representation of the Kuo-toan language. The languages are made of whatever real examples I could find (such as suggested common names), as well as online words from other sources, and my own words based on the descriptions of how the languages sound.

The way this is set up, I can easily add pre-made phrases to their list, or alternate language possibilities for creatures that typically speak more than one language.

http://www.youtube.com/watch?v=-lZMZyIGsBQ

Link to comment
Share on other sites

I finally finished another complicated conversation. I'd been slowly chipping away at it for a long time, and probably would have spent even longer on it if I hadn't opted for the brute force method, and also cutting a branch that promised far too much complexity, as it would have involved blackmail. It was a branch for brash people, but don't despair -- there are plenty of brash options elsewhere and in other dialogues.

I did some work on the final-final-secret-extra boss area, but only the first pass -- the rough work.

Next day, I've done a second pass on the boss area, which I'll tentatively call the Plateau of the Elemental Rift. This required some visual effects that don't seem to be in the toolset. I've installed a few FX packs to try them out. Also, there's new lighting and placement of some torches, and an attempt to create what Valve calls a vista here.

I tried out the effects, and some of them were nice, but I actually found what I needed (animated running water effects) under the placeables, not the effects. There could still stand to be a few more available to create certain kinds of streams. Maybe I'll make something like that later.

I'm hoping this will be a particularly fun boss fight in an interesting location, so I'm not sure I should spoil anything by showing a picture of the place. Maybe later, after I select textures and a few more decorations. I used some of the Witcher placeables for it. (I did some more conversions in that project, too, but not enough to show.)

Link to comment
Share on other sites

I thought that the script was working fine that turns off the lights in town during the day, and turns them on again at night, but it's not. I was doing a quick test run with a party comprised of both player-made companions and recruited NPC companions from the module just to make sure mine didn't have the problem I've seen in a couple of other mods where the companions lose all of their items when they die, and I was reassured to find that they behave as expected. But I saw while passing through town that the lights were not on, despite it being past the time when they should have come on.

I had seen this happen before, and I thought I had fixed it by removing the lines in the hourly heartbeat that check if the player is in the area. I'm using a modified version of these scripts, running the lights-off and lights-on code on the dawn and dusk events.

I've seen the lights come on in my presence, and I've also seen them change appropriately after resting at an inn and letting 8 hours pass, so I know it can work even if I'm not in the outside area. It's just a mystery to me why it doesn't work all the time.

Another thing I saw in one test, while I had debug mode active, was that one NPC (a city watchman walking waypoints) was overflowing with instructions, and eventually hit a limit. I looked around his entire patrol area multiple times trying to find him, to see if he was stuck on something, but he was nowhere to be found. I'm guessing some kind of bug made him fall through the ground, or into a non-walkable area, or something of the sort. I'm surprised that the standard walk waypoint scripts don't have some kind of contingency for that sort of thing.

I needed a loud waterfall or rushing water sound, and I didn't find one in the stock resources. Waterfalls and rushing water, yes, but not loud. With the volume all the way up on the slider, the "large" waterfall sound still seemed quieter than the gentle trickling sound of another sound effect near some still water's surface. I'll check Kamal's Freesound project, but if anyone happens to know one offhand, please let me know.

That's when I'm right up next to it, but I also have had trouble getting sounds to sound right from a distance. Sometimes in the toolset they sound fine, but in-game I hear nothing as I approach, until suddenly the sound kicks in at mid-volume, increasing as it should as I get closer. I want this loud sound to be audible from quite a distance, and increase appropriately in volume as you get closer, but I'm having trouble with that.

Last time I said I might not show any pictures of this area to keep it a surprise, but I'm changing my mind. I think I want to showcase this one, actually. It'll definitely in the trailer, so it might as well be here, too. Needs a little more decoration and texturing first, though.

Link to comment
Share on other sites

  • 2 weeks later...

Wrote another quest and a new general-use script to work with it. What the hell am I doing? I don't know, but for some reason I like writing these scripts. This is a revenge quest, and so I needed a basic kill-quest system to work with it.

I wanted to track a certain amount of near-indiscriminate slaughter as well as a named objective, and use custom tokens to update the journal with the running total in the same way as I did the collection quest from before. That time, it was a script with a specific quest, message, and numbers to deal with. This time I wanted to make it entirely general so that I can just put this script on any creature, stick some variables on the creature, and update whatever quest I choose. It also displays a floating string with the running total, and allows for multiple objectives.

I also made it possible to choose whether to store/retrieve the tracking variables on the main PC, the current area, or the current module. I'm using the main PC as default, because that seems to be where the built-in journal stores its information. Maybe I should also add an option to store it on an object by tag, spawning a waypoint with that tag to store them on if the specified object doesn't yet exist.

After adding that quest, I found that my tinkering with a different script had caused an animation to stop playing. After some experimenting, I found that I had incorrectly used "==" instead of "=" in one spot, and the compiler hadn't complained. Fixed that.

I also found the reason for a problem that had plagued me for months -- certain of my goblins had one of those black cubes with the red question marks on them, which indicates a model that doesn't have any assigned textures. I had thought, since the box was on one of their arms, that it was the shield causing this problem, but changing the shield and ultimately removing the shield didn't help. Today I thought to check if perhaps it was one of their armour pieces, like the bracer. Well, I didn't determine that exactly, because somehow the blueprint had lost all of its custom armour settings. So I copied a different blueprint, reassigned the proper feats and put the same name on it, and removed the old one. That fixed the problem.

Rather than search for a louder waterfall sound, I just opened the existing waterfall sound from the game in Audacity and took a look. Indeed, it was far quieter than it needed to be, so I amplified it to the maximum it could go without clipping. I also noticed that there were fades in and out at the beginning and the end of the waterfall sound, meaning it could never loop smoothly. Why, I can't fathom. But it didn't seem to matter, because after I removed the gaps, it still had a brief pause at the beginning/end of each loop. The only semi-solution I could think of was the put two sound objects there, with slightly different pitch variations, so that they would start and stop at different times, partially masking the gaps.

I got the sound to reach as far as it needed to, and to get louder appropriately as you approach. I used a different distance on the second sound, so that as you ascend to the plateau the volume has a more distinct rise at point at which the waterfall is coming into view.

Next I made another general-purpose script, to use on an object that you have to place items into in order for something to happen. I made it so that you can specify as many items as you want in the object's variables, and have it update the journal and/or fire another script on success. I realised a little too late that I could have simplified it a bit by using an array, so that you'd only have to add 1 variable for all of the objects you wanted to check for.

Link to comment
Share on other sites

Watching Marshall's Legends plugins demo videos always gets me fired up to do more in the toolset on my module. Since some of the plugins are for PWs and require a database, I've written a lot of scripts to provide the same kind of functionality without a database, though this of course means there's more manual work on it, since I can't use the plugins to generate all of the required resources automatically. Still, it's inspiring stuff!

It inspired me to go back and add in the special mechanics I had originally planned for one encounter in particular, but which I was going to just leave as a more straightforward fight. Now it's a little more challenging with some special things to do. They should be obvious, but woe to anyone who embarks on a quest without a full party!

I worked on some conversations that are necessary for the main plot, which were placeholders before (notably the Harbourmaster).

All this time, and I finally learned how the "preview" tab works in the toolset. So I can see what placeables look like without dragging them into an area. For anyone who doesn't know, you select the blueprint, click the Preview tab in the properties palette, and make sure the "Preview" toggle button is active in the strip at the very top of the Properties palette.

While looking through some scripts, I found a script that reports the PC's current location and current facing angle, whereas the "loc" command reports only the location, and I had to estimate the facing. The script gr_where_am_i() reports both.

I finished the Harbourmaster conversation, and moved on to the AI for one of the bosses. I'm trying a slightly different method than I used for the last boss, which was a damage switch in the spawn script. It worked, but I think it would be better if I moved the special event phase actions out of the actual NPC and into a regulator ipoint, which won't get interrupted by signals from the default AI.

I'm using a script in the On Damaged slot for this one, which will signal to the regulator's On User Defined event, and that's where the special actions occur, aside from the initial one in the perception script and the death script.

While looking for the event constants for this, I stumbled across exactly the command I was looking for before, and couldn't find. I wanted to be able to change a creature's scripts on the fly. I found a workaround at that time, in the form of SetCreatureScriptsToSet(), which required me to add entries to NWN2_ScriptSets.2DA, but what I really wanted is actually called SetEventHandler(). I couldn't find it before, because I was looking for commands with the word "script" in them. This is perfect! It will allow me to more easily and flexibly repurpose existing NPCs in a running game. This is great news because it makes it possible to expand a module/campaign nearly without limit, without the player needing to start over each time. However, my glee is very slightly dulled by reading that it doesn't function properly on areas or the module itself. But for what it does, I'm very glad.

Link to comment
Share on other sites

I've got the fight AI working. It consists of a perception script to start the whole thing off, a damage script to signal when to move to the next phase, a death script, and a regulator heartbeat that handles all of the special actions and abilities.

I've learned enough about scripting by now to add in the special abilities the sea hag is supposed to have, but which aren't in the NWN2 toolset -- namely, Evil Eye (3/day) and Horrific Appearance (aura, 1 save for each PC per 24 hours). So I got rid of the placeholders for those abilities: Death Gaze, Daze Gaze, and Pulse Strength Drain. She uses one of her special abilities on each stage, and the player is notified. She also has a bowl of commanding water elementals, and I've scripted her to make sure she uses it when necessary.

I put in voice barks at each stage, but I ran into the common trouble that creatures taking action will often not play the sounds you tell them to play. In other areas, I used a sound object that I would command to play at certain times. That's probably the best solution for any encounter in a specific area. I tried a couple of different ways here, though, and learned more about what works and what doesn't.

First, I tried having the regulator ipoint play the sounds, but I learned that placeables can't play sounds unless the sound is embedded in a VFX applied to the placeable (in which case I guess it's actually the VFX that's playing the sound).

Next, I looked into the "sound ninja" approach again (an invisible creature that spawns in, plays a sound, and destroys itself), which I had tried once before, but it didn't work then. Here, I just decided I didn't want to even try it again because if you spawn the sound ninja as needed, you need to delay the sound, and in a fast-paced fight like this, I don't want to delay anything.

So then maybe I wouldn't spawn it, and just have it there the whole time. But I don't want an invisible creature standing around, where it could still have collision or something that blocks players or NPCs from fighting. There's supposed to be a way to remove collision from a creature, though I've heard the ghost effect doesn't work, though it's supposed to. Also, I could place it in a space disconnected from the main walkmesh, but there's no way I'm touching this walkmesh again after how long it took to get it working.

Someone around here had a good idea (PJ? Tsongo?) of using spawning animals that are usually just used as decoration, and using them as references for scripts. So I placed a small rat on the pirate ship (not a Rodent of Unusual Size that are used as enemies, but a common normal-sized rat of the kind I used in my "sleeping at the inn" scene. I had the rat act as the ventriloquist, and it all started working. A pretty satisfying fight! Just one sound's still not playing, and that's the one that's supposed to fire when she dies. It's strange, because all of the other commands that occur after that line are firing correctly. Possibly it's because it uses "AssignCommand" to tell the rat to play the sound, and the others are straightforward commands?

At any rate, I put the files on sound objects and placed them in the area, and after a couple of tries where nothing played (the volume was 0, and it was set to play only during the Hours array, which was blank), I got the victory sounds to play.

Next, I created the loot. My bosses are dropping magic items that have a balance of both beneficial and detrimental effects, to make them more interesting. I notice these detrimental effects still add to the item's cost, though, so I correct that by adding a negative "additional cost" to it.

I'm using the SoZ loot system to spawn these items on the bosses from the items' resrefs. This is more convenient and less error-prone than putting it directly in their inventories, because I can make changes to the blueprints at any time, and those changes will show up correctly when the creatures spawn, whereas inventory items are instanced copies. This is especially useful when I'm creating placeholder quest items that I plan to fill out later, with their descriptions, icons, etc.

Link to comment
Share on other sites

What I had in mind for another use of the unobtrusive rat was as a kind of a substitute for a trigger, because I found that OBJECT_TYPE_TRIGGER is not supported by CreateObject, and there doesn't seem to be any other way of creating one other than placing it manually in the area. This is, again, for the docks, and to add certain kinds of quests to the module for saved games in progress.

Using the rat's perception as a trigger was unsatisfactory, because it seems to be like a heartbeat, possibly checking for perception only every 6 seconds like the heartbeat does. Also, there doesn't seem to be any way to enable a creature to be able to see through invisibility without casting a spell (this is also a problem for the kuo-toa, who are supposed to be able to perceive invisible creatures).

Abandoning that idea, I looked into the GetFirstObjectInShape() method, and other methods like GetDistance(), but they all seemed to rely on heartbeats on placeables like ipoints, making them little better. A character could run right through one of these pseudo-triggers without triggering it if they got through in under 6 seconds, and I don't want a lot of sped-up heartbeats adding to the area.

I happened across what I needed while looking through the list of constants, finding a constant called SCRIPT_AOE_ON_OBJECT_ENTER. On enter is what I wanted. I couldn't find any example scripts that used that constant, but I learned what I didn't know, that you can create an invisible AoE object that has its own tag and set of enter, exit, and heartbeat scripts. A trigger in all but name!

So I wrote a quick conversation script to let me go in-game and watch these AoEs get created on command at a few different locations (I'll be using vectors for the locations later, but for the test I got the locations from waypoints), and also an On Enter script to print a message to the screen when I enter it, and destroy itself a few seconds afterward. Works nicely! Next I'll add a little quest that uses it.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...