Mar 2003

Implementing Subraces and ECLs

There are two big problems with putting new PC races into NWN: implementing the racial traits, and implementing Effective Character Levels (ECLs). At first glance, it seems that implementing racial traits can’t be too hard (hey, BioWare even provided a custom “subrace” option for your PC!), and ECLs are much harder. Experience has shown, however, that it’s the other way around.

Racial Traits

Each race has a bunch of unique traits; for example, Aasimars have a +2 ability modifier to both Wisdom and Charisma. They can also cast the Light spell once per day, and have a few energy resistances (e.g. 5/- for electrical). How do you implement these?

The method done by all the modules I’ve seen give the character a skin. Skins are normally only given to monsters, but there’s no reason you can give them to a player. Think of a skin as an invisible, intangible item which the player possesses, but can’t access in her inventory (so she can’t drop it or trade it to other players). The skin can then have the properties usually associated with magical items, to simulate the racial traits: e.g. an Aasimar Skin would grant them +2 to Wisdom and Charisma.

However, there is one large problem with this: ability modifications are not part of the character herself. Some things in NWN, such as feat prerequisites, are based solely on the character’s real, permanent ability score, and do not take into account the ability modifier given by the skin. The full list of things which use the character’s unmodified ability scores are:

  • Feat prerequisites. e.g. if you have a Str of 12 and a skin which gives you a +2 Str adjustment, you should be able to access the Cleave feat, which requires a minimum of 12 Str. You can’t.
  • Spellcaster levels. A Druid or Cleric with 17 Wis and a skin which grants a +2 Wis adjustment will still only be able to access level 7 spells. The same applies for Sorcerers and Bards with the Charisma ability, and for Wizards with Intelligence.
  • Intelligence modifier for bonus skills. A character with an Int score of 10 and a skin which grants a +2 Int adjustment should receive 1 bonus skill point per level, but instead receives no bonus.

You can sorta overcome this restriction by giving the character a specially tailored-skin and picking an ability to adjust which doesn’t affect your character, but that solution’s not very satisfactory.

So far, there doesn’t seem to be a way to modify the permanent statistics of a character via NWScript, which means that even if you find another way to give ability adjustments instead of skins, it won’t make a difference.

NWN also seems to have some protection against character editing: changing the ability scores of the various .BIC files in the localvault directory will make your character invalid if the total ability points don’t add up to 30. So you can’t use a character editor to adjust your character’s ability scores (yet). This makes sense, otherwise it would be very easy to use a super-character to cheat on multiplayer servers.

So, unless there’s a way to permanently adjust ability scores, using skins is a hack which works, but doesn’t really work well enough. The other solution would be for Bioware to patch NWN so that it uses the adjusted ability scores, rather than the permanent ability scores. Unfortunately, doing it either way has its share of implementation issues.

ECLs

Effective Character Levels, or ECLs, are a way to compensate for the traits of the more powerful races. The average drow, for example, has a whole bunch of fun abilities that make them far more powerful than the average human. To compensate for this, some dude came up with the concept of an ECL.

Drows have an ECL of +2, which basically means that they’re two levels lower than other races at the same amount of XP. For example, a human with 11000 XP would normally be level 5; a drow with 11000 XP is level 3. ECLs “lag” your character behind by a certain number of levels, to compensate for your more powerful racial capabilities.

I’ve managed to implement ECLs in NWN. The solution is quite elegant in some ways and pretty ugly in other ways, but as far as I know, it’s the first complete ECL implementation done to date.

You can always have a look at the NWScript code to figure out what’s going on, but since all programmers are lazy, here’s a rough idea of how it works, and why it’s been written that way.

A first attempt at an ECL implementation

(Warning: deep knowledge of NWScript and 3E/ECL rules (or serious crack) will be required to understand what the hell I’m talking about here.)

Conceptually, an ECL changes the XP progression table. The PC is treated as if she’s some number of levels higher than she actually is, only for the purpose of determining the XP required to level up. If you try to translate that concept directly into code, though, you’re doomed.

Initially, the most obvious way to implement ECLs is to use a module’s OnPlayerLevelUp event. Every time the player gets enough XP to level up, take some amount of XP away, so that she has to earn more XP to go up that level. Yeah, that will work, but it presents two nasty problems:

  • The OnPlayerLevelUp event is triggered after the player actually levels up. It’s not triggered when you hit the amount of XP required to level up. That means that if you decide to take away some XP, it will be done after the player has picked all their classes, skills, etc., only to have that level immediately taken away. Raaather annoying. This first problem isn’t solvable, but if you’re really intent on having ECLs, but you can live with it if you really want to.
  • If you take away XP when the player levels up, how do you know whether you’ve done this before? This is easily solvable by storing local variables on the PC object.
  • Since you cannot store any persistent information on a PC object, you don’t know whether you’ve taken away the XP before. What if the character has had her XP taken away before, then exports her character for use on another server, only to find that when she levels up, her XP has been taken away again? Unfortunately, this problem is unsolvable, and it’s a showstopper: users will not accept XP being taken away from them unnecessarily.

Statefulness and persistence

The core issue with the third problem is that it relies on state. (Functional programmers, don’t you all feel good now?) It relies on being able to store information with the character that can be used at a much later time; if the character is exported before that event occurs, things go completely screwy. So, any ECL solution that is done must be stateless, or at least executed quickly enough that there is no practical chance for such a race condition to occur in practice.

Another view on ECLs

There’s no chance of implementing ECLs if we don’t alter our concept of how to implement them. i.e. we have to think outside the box.

We know that an ECLed character requires more XP to go up one level than a non-ECLed character. One way to think of this is that the PC requires, say, 25% more XP than usual to go up a level. As an example:

  • a non-ECL character requires 2000 XP to advance from level 2 to level 3: you need 1000 XP to get to level 2, and 3000 XP to get to level 3. However,
  • a ECL +1 character requires 3000 XP to advance from level 2 to level 3: you need 3000 XP to get to level 2, and 6000 XP to level 3.

So a ECL +1 character requires 50% more XP than a non-ECL character to advance from level 2 to level 3. While we can’t change NWN’s XP progression table to support this (at least not without evil hacking of 2DA files), what we can do is penalise the XP that the PC earns to make it equivalent to the progression table used by the ECL character. This is similar to the XP penalty that is introduced when you multiclass and you don’t keep your non-favoured classes within one level of each other.

So, if we require 3000 XP to advance a level instead of 2000 XP, our ECL implementation will work if we penalise all the XP earnt by the character by a factor of 1/3. Instead of earning 90 XP for killing a monster, the character earns 60 XP. Where she’d normally get 300 XP, she gets 200 XP instead.

While NWScript doesn’t allow you to say “give a PC n% of the XP that she’d normally get”, what you can do is subtract an amount from the XP that the character has earnt. So, when the PC gets 900 XP, subtract 300 XP. When she gets 60 XP, subtract 20 XP. If you do this at a frequent enough interval (e.g. every second), then you have an algorithm which executes fast enough that it’s effectively stateless.

This is the way that the ECL script works. We replace the nw_c2_default1 script, which is called whenever an animation update occurs, so that the XP check is done very often (on average, probably once every three seconds). Previous attempts tried to trigger the script so that it ran once every second, but that can’t be done unless there’s a way to set a variable which only lasts for the duration of the current play session. (See the Scripting page for more information.) As long as players aren’t cheating dramatically and exporting their character within time between animations are updated, it’s all good.

There are a few downsides to the current approach:

  • Do all players need to put the new nw_c2_default1 file in their override directory, or does it only need to reside on the server?
  • The nw_c2_default1 file may need to be updated whenever a new patch is released.
  • There should be a stronger link between the thingy that grants the character the racial abilities, and ECLs, so that if you don’t have ECLs active, you should not receive the racial abilities. (That’s only fair!)
  • It would be better to have a consistent, short time interval between XP checks. It’s good enough right now, but it’s always better to be perfect …

I’ll treat these problems as a TODO list: they may go away as I find workarounds. The ECL scripts, however, work, and work well.

Comments

Quirks

The following is a short list of quirks that I’ve found with NWN, as of version 1.19/1.20. Keep in mind that future patches may fix some of these quirks.

Double weapons are Good

Double weapons (two-bladed sword, dire mace, etc) don’t seem to induce a two-weapon fighting penalty at all.

i.e. If you have two-weapon fighting and ambidexterity, and your normal BAB is +5, you would expect that using a two-bladed sword induces the -2/-2 penalty for the two attacks, so you would attack at +3. However, it seems that you still attack at +5!

This obviously makes double weapons far, far more powerful … can you say “Uthgardt Ceremonial Blade”? It also means that munchkins (like me) who pick one level of Ranger for the dual-wield feat don’t have to, if they only want to use double weapons (also like me).

Druids don’t have weapon restrictions

The Druid’s weapon restriction isn’t.

If you are a Druid, you are proficient with druidic weapons, but you are not restricted to them. While the Druid class cannot learn any non-druidic weapon proficiencies, other classes that your PC has can.

i.e. If you multiclass, the Druid’s weapon restriction disappears.

Put this together with the quirks above and below, and you can have a L1 Fighter/L19 Druid specialising in a two-bladed sword, with no attack penalty. Nasty!

Weapon Specialisation with a Level 1 Fighter

(This may or may not be a deviation from the standard 3E rules, but it’s obscure enough to be a quirk.)

Any PC can take the Weapon Specialisation feat as long as she has one level in the Fighter class. The feat is only available if:

  1. You have Weapon Focus on a particular weapon
  2. Your BAB is >= +4
  3. You are levelling up in the Fighter class

The last one’s the doobie: even if you have Weapon Focus and your BAB is >= 4, the feat is only available to Fighters, and thus only shows up if you are levelling up as a Fighter.

The quirky thing is that it doesn’t matter what particular level of Fighter you are to obtain the feat. You can be a level 4 Ranger (and thus have a BAB of +4), with weapon focus on, say, Bastard Sword. If you then level up to a L4 Ranger/L1 Fighter, you can then pick the Weapon Specialisation feat.

Hold down mouse button 1 to move the character

So call me a gumby, but I had no idea this handy feature existed. (And I’ve read the manual, what, fifteen times? Nehh.)

Instead of cli-cli-clicking on the map all the time to move your character around, you can hold down the mouse button and drag it around the screen, which allows you to control your character’s movement and direction. Much easier.

Using Lore potions to their fullest

  1. Drink lore potion to increase your Identify skill.
  2. Pause game.
  3. Identify everything you want (all 3000 armours from “The Dark Ranger’s Treasure”, heh heh). The Lore potion won’t expire since the game is paused.
  4. Unpause game.
  5. Profit.
Comments