Editorials

Neverwinter Nights 2: Admin’s Corner: PWs: The Nature of the Beast – Part 2

0

Admin’s Corner: PWs: The Nature of the Beast – Part 2

Lanessar (Jason) has been a PW Admin for close to 4 years, and is currently working as the Vice President for QA at a CAD software company.

In response to the very interesting comments received on the forums, I thought I’d ensure that people know my basic intent is to change the way people think about the toolset and PW construction from NWN1 to NWN2. There are differences.

If you’ve read my previous articles ( Admin’s Corner and The Nature of the Beast Part 1), you’d know that I was all for outside of the box stuff. At release, however, you have a finite piece of software to work with. There are limitations. You have to know a spoon is there in order to bend it to your will.

For those “normal” folk who are not programming geniuses intent on revolutionizing the field the first day of release, there are certain revelations you’d probably be interested in before starting on “Harry Potter XXX – Hermione’s Bachelor Party”.

What is true is what is true for you. But having some information before starting never hurts.

And so we swing into point two of my little dissertation.

Basic scripted features. Whether they are dying, frying hordes of kobolds, or swinging around the Sword of DM-Slaying +5, these are always there and can kill your server.

Any admin worth his salt knows that a server is limited not by imagination, but by the ability to manage that imagination with twenty or even fifty content-starved players running around waiting to play whack-a-mole with whatever ingenious evil plot you have planned for an area.

Any system within your module will have to be ruthlessly made efficient as possible. I think that the older methods of scripting for “anyone who needs them” will seriously hamper performance unless done by a VERY skilled programmer. But, at the start, that may be what you need to use. Later, you can graduate up to using totally custom events.

The newer methods of doing things will be custom crafted for specific things you want done, lean and mean. Having five thousand lines of code to take a bath, whether or not you’re using soap, did you bring a toothbrush, all that will end up being excess baggage to start with.

To be as efficient and streamlined as possible, I can make some suggestions (to change over from the old style of thinking) and see if that helps.

We used to have 5000 scripts for starting up a merchant. One per merchant. This gets totally ridiculous when we want to save resources, for sure. It was a wizard function for setting up a store, in the Aurora toolset, and frankly, only efficient if you were making a single-player module.

The BEST way to accomplish that is to create one script, which just gets the nearest merchant waypoint, and bingo, opens a store. Or, opens a specific merchant by the tag on the store, set on variables contained on the creature. Either way, you want one script for all of this stuff.

Other things you’ll end up finding this on that I’ve encountered: Closing and locking a door after X seconds. Closing a door after X seconds. A sit script for PCs. Lots of different things having to do with stores. Items which summon creatures. Moving a PC from point A to point B.

All of this can be handled with one script, using variables set on the object. While this might mean some additional time for builders to figure out the system, if you do not, your module with be glutted with the following scripts:

Mod_sit_pc
Sit_onuse
Sit_pc
Pc_sit
Sit_in_chair
Zzt_sit
Lan_sit
Sit_script

And the list goes on for about five or ten more I do not remember. The same went for a simple script to make PCs climb rocks, get teleported by a portal, or any other thing which moved a PC without an area transition field. Handling this all with one script is not “the ideal”, it’s downright necessary.

And unless you’re an army of one doing the whole world, you’re going to run into this, no matter how much you document it (and PW admins are usually short of time to write well-documented building instructions and script useages for building stuff).

There’s no perfect way to write code to handle problems. I’m not going to get into how one should code as much as some of the basic ideas about coding. Arguments about whether a handling in programming is “good” or “bad” quickly devolve into crazy pros and cons and come off sounding like a religious debate (or at least a debate about balancing DnD classes for PvP when people who cannot think with the word “strategy” – quite impossible).

As an example, there are lots of good reasons to use exceptions, and lots of good reasons not to. Any design is about tradeoffs. There is no perfect design and there is certainly never any perfect code. Write whatever you want to, make it as streamlined and “powerful” as you wish, use pseudo-arrays or whatever else, the code will end up changing at some point or another as you find it unworkable or need it to do something different or play better with some new feature or script.

If you’re not a genius programmer as an admin, then you have to get one, or use the stuff on the Vault to accomplish what you wish. Which never quite works out to your vision, so getting a scripter becomes necessary.

However, there’s a simple way to tell a good programmer from a bad one. Every time.

Can you read the comments and understand the code?

This reminds me of a time when I was administrating for a PW and got a wonderful teleport spell script. I mean, it was fantastic. It did the job extremely well, for years. Then, one day, I switched from a listener script (we used DMFI) over to an NWNX plugin which logged chat. The chat logging script was far more efficient and reduced system resource lag by at least 30% over using DMFI with all the convos and whatnot.

Guess what?

We had NO idea how to update and correct this script, because the code (while brilliant) made no sense save to the programmer who wrote it. I had at least three paid professionals with 12+ years of resume experience try to update this code, and while we managed to add Group Teleport and some other very neat features, half of them never worked properly and we never could do without the damn listener being summoned (which was a lag-creator for sure).

We ended up going to some other code for teleport, because the old code got outdated (and actually became unusable with updates to the core systems). Sad, but true.

The bottom line is, every line of code can be inspected by itself, and if every line of code is correct, the entire body of code is correct.

If there are “gaps” in a logical sequence of actions, then there will be something wrong with the code, or the programmer forgot to comment something that one day, perhaps not soon, but one day, will bite you in the ass.

For those who think they cannot read code or comments, it should read like making a cup of coffee. It’s very simple. You need coffee grounds, a filter, a coffee maker, water and a cup. Code will carry you through the basic sequence of making this coffee.

Get the coffee maker. Get the filter. Put the coffee filter in the coffee maker. Get coffee. Action: add X coffee to filter. Action: add water to coffee maker. So forth, right on down the line, even up to asking “Would you like it black, or with cream, or cream and sugar?”

With a good programmer, this is easy enough to follow even for a moron.

Even if you ARE a programmer, you’ll want those comments in as clear as a bell, or you’ll end up hunting for something or where something happens, and losing precious time doing so. At the very least, think of the poor bastard who takes over two years from now (once you’re burnt out) and has to fix something. There is simply no coder who can write a 500-line piece of complicated code and pull it up five months later without touching it in between, and find the exact spot where you need X to do Y instead.

One thing to be careful of is people who insist on code re-writes. I’ve made this error in the past, starting over from scratch, and I can tell you it is not pretty.

There’s a subtle reason that programmers always want to throw away the code and start over. The reason is that they think the old code is a mess. And here is the interesting observation: they are probably wrong. The reason that they think the old code is a mess is because of a cardinal law of programming:

It’s harder to read code than to write it.

This is why using existing scripts in different ways is so hard. This is why everybody on your team has a different function they like to use for making a PC put on a pair of socks. They write their own function because it’s easier and more fun than figuring out how the old function works.

As a corollary of this axiom, you can ask almost any programmer today about the code they are working on. “It’s a mess,” they will tell you. “I’d like nothing better than to throw it out and start over.”

Why is it a mess?

“Well,” they say, “look at this function. It is two pages long! None of this stuff belongs in there! I don’t know what half of these constants are for.”

When you throw away code and start from scratch, you are throwing away all that knowledge. All those collected bug fixes. Years, in many cases, of programming work which was proved to have worked by being tested in the only flame that matters: Players trying to wreck it.

There are sometimes architectural problems. The code is not factored correctly. The comments are not clearly written. The functions are not laid out in a manner which the new programmer is familiar with, or the constants or variables are not named “to their standards”. These problems can be solved, one at a time, by carefully moving code, refactoring, changing constants. They can be done by one programmer working carefully and checking in his changes all at once, so that nobody else is disrupted. Even fairly major architectural changes can be done without throwing away the code.

Once, I had the worst failure I ever went through as an admin occur, and not in the too-distant past. I decided that all the code was SO messy, I wanted to streamline it all. Problem was, I did not do the above steps, until halfway through the re-coding process.

Did some of the old HCR code need to go? Yes. It was rather bloated and we used about 10% of the functions in the damn thing. It was three versions out of date.

BUT, we had programmers fixing and tweaking little bits of that HCR code for over three years, and it worked VERY efficiently, did exactly what we needed it to do. In the end, it was a dog’s breakfast, and I ended up using another person’s code for a PW which later I discovered was written solely and only for single-player mods. Heartbeat functions which (quite frankly) the coder had to be INSANE to stick there, since there were other scripts which did the exact same thing far more efficiently through different (non-resource intensive) events. To this day, I regret that. Don’t make the same mistake I did and end up with a partially-crippled world for months.

On another note, I’ve seen features advertised in some worlds which barely have the first three areas built, which read like the features list for World of Warcraft: The Burning Crusade.

Okay, here’s a rule for the Mr. Overzealous Non-Programmer: PR and code should come from the same person. Too many PW admins or designers quote great features which may or may not be present in a final build, and end up getting dropped. Even skilled programmers make this mistake, as you cannot see how everything will work together at the end on a new program untested as yet.

I recently saw an NWN2 persistent world advert which proclaimed several systems that, singly, could be made to work at release. As to whether or not they will ALL work, I frankly doubt it would work on a full PW on a program not yet released. Half of them required Database functionality, and who the hell knows what we will have at release on that? Who can even assume that NWNX3 will even work properly with NWN2 Server?

Right. So all those “promises” go right down the toilet, and make for a bigger failure than you can ever hope. Then there’s the rush to implement all these things for the coders, and I can tell you this: Rush a programmer and you get bugs. Lots of bugs. Bugs that another programmer will not be able to fix and may insist on re-writing the code for…

Instead, when you begin your project, only promote those things you know will work. Immediately.

Don’t get me wrong here, I think aiming high is good. Make that bloated features list and keep it for the development team to work on, keep the eye on the mountain of making an incredibly scripted world.

Just don’t announce them to the possible player base as fact in an advert. Don’t even hint at most of them until you’ve done at least a dry-run with those events in place and a few players on.

That way, as you develop your project and it nears release, you can add development updates and remind the people that you exist, what newest thing you came up with, or the brilliant cat-color-changer or back-scratcher which will be in your world as a feature.

Plain and simple, you never promote something you do not have working. If you have not actually walked into the player client in NWN2 and tested it, I would heavily suggest not adding it to the features.

There are a few exceptions of course, but your idea of “tons of scripted quests” and the reality of “I’ve only found two in five levels which work” can quickly disillusion players. I remember a time when I had a brilliant system worked out for the decay of underdark/drow items exposed to sunlight. Heck, I even wrote the code for it. I tested it. It worked great in a single module, with nothing else in it.

I looked over the whole project, saw it would take an OnAreaEnter event, saw the number of events already in there and scrapped it. It would have been insane to try and add that code into an already overburdended event in the server, and even had I gotten it done, it would have to be removed a few weeks later due to lag issues. Yes, I could have added it. But when I looked over the whole thing, all the pieces together, I did not want to any longer.

Too much is sometimes too much. I mean, I know people can make 300 subraces or recreate every PRC in the books. That’s fine and dandy.

The question is, should they be included in your PW? I suppose for an action server this totally works, but having ninja or samurai running around in a Moonshae Isles RPPW would be like watching the final boss of a level in Doom III end up being Mother Theresa. Jarring and rather off-setting.

So, keep your features list realistic to begin with. Especially with unknown changes to the NWScript system. A few people might understand why five out of 250 features are actually working in your PW at release, but the majority just silently slink off, if those features are your major draw. Start small, and you can accomplish everything eventually. AFTER you know it works.

Scripting will very likely be, in coordination with reduced areas, one of the most important points for a persistent world.

In NWN1, there used to be three ways to make a world “good”. Note that these are not black-and-white, but that shades of grey exist for all three in a PW of any success. One type does not mean that there was none of the other types present; it just means that they focused on that one type more than the others.

The first, is a content-filled world, with many haks, lots of well-made areas and tons to do. NPCs were well-crafted and involving with conversations, or there were many quests, or each area was meticulously crafted with all sorts of custom outfits for players. This was the tried-and-true way to draw players.

The second way was to make a well-built world with loads of scripting, scripted quests, tons of scripted items and loads of content, all achieved through scripting. VERY few worlds relied on this method. The few that did this well, were the most stunning PWs I’ve ever played on. Most did not have many players.

The third type relied almost solely on DM interaction. My PW was based off of this to start, then went over to the first type later in it’s life. It can be successful only to the point that you have good DMs, fair staff, and no politics get involved. As we all know, politics seem rampant and cries of favoritism tend to mess this up somewhere down the road.

There are a few, VERY few, that combine two or even three of these styles completely. I’ve never run into one that did all three at once, in equal (high) amounts. If there was, I’d still be playing there, and NWN2 would not be anywhere near my list of things to buy. While I’ll get claims that there was one, after playing on several hundred PWs over my time, I can say definitively that most of those people were wearing rosy glasses and fell firmly into one of the three and lacked on one or more of the other two.

In NWN2, PWs will have to be focused on at least two of the three. Without proper scripting, there will be too few areas or too little content to make it last long, unless the DMs are rampantly present and areas are well-made.

Crappily made areas will keep players only so long as it’s well-scripted, and the DMs are heavily involved in making players involved.

Heavily DM’d worlds will still fall short if scripting or content is short; there will be only so much the DMs can do with the world if it is lackluster or there are not well-scripted things which keep the player’s interest.

If you actually make a world which focuses on all three, and does it well, let me know and I’ll give it a go when it’s ready for release. I can guarantee pulling in thirty or so players with me on that one, if it’s for real.

Keep the above in mind when you make your world; it is a change from NWN1 to NWN2. Ignore it at your peril.

Biography: www.joelonsoftware.com.

About the author