So, let's talk about adding new spellcaster classes to NWN.
It doesn't work. Not easily anyway. Most of the stuff is hardcoded right into the game, no matter how often you set that spellcaster flag in classes.2da to true, and no matter how many spellgain tables you define. There's a few ways to work around, with feats, subradial spells and so on, or with all the heavy scripting the Player Resource Compendium employs, but it's clunky, I tell you - no fancy, easy spellhandling like with the existing classes, suitable at best for a secondary caster with limited spellcasting - say, if we ever get around to implement a proper assassin or blackguard.
It's pretty much why I built my witch character as a druid. It was close enough to what I wanted. But, alas, it was not perfect. So, how to get a set of nifty witch abilities while avoiding the entire "make a new spellcaster base class" issue? The answer will be obvious to those of you playing any of the P&P 3.x derivates - a prestige class. Easy solution, right?
Except not. NWN has a funny way of handling spellcaster progression in it's prestige classes, so, I started experimenting and taking notes. I took the Champion of Torm, and gave it full progression, arcane and divine, and removed the prerequisites. As expected, I did gain new spells per day, and even access to new spell levels precisely as I should, no matter the class, just as if I had taken levels in whatever base class I started out with.
That was pretty much where it stopped working right, however.
First off, the most glaring issue with all classes - it does not advance caster level. So even though you might cast the same number of spells as a pure-classed wizard; if you are a Wizard 5 / Loremaster 10, your Chain Lightning spell stops at 5d6 compared to your Wiz15 buddy's 15d6, and your roll for dispel and spell resistance checks is at a meager +5 instead of +15. In other words, in many cases you effectively neuter yourself.
The second issue - not for everyone, but just as or even more showstopping: Spells Known. While a PrC can advance your spells per day, it does not, in fact, grant you new spells to fill those slots. For divine casters, this is a non-issue - they know all spells on their lists right from the start. Wizards do not gain their two free spells per level, but could at least learn new ones via means of scrolls. Sorcerers and bards? Nada. You do not learn new spells through prestige classes, ever. As a sorcerer 5 / prc 5, you might have fifth level slots - but you know only second level spells, exactly the same as any other fifth level sorcerer.
In other words: I found that PrCs as-is are not worth it at all for bards and sorcerers, and are only of marginal use to everyone else, at least if you want to play a primary spellcaster.
That is, until niv told me that he could probably get the caster level progression working.
Making a Witch
So, a druid-based caster PrC with actual caster level progression? It's a divine class, so getting new spells isn't an issue. What's to stop me, then? All I need is, effectively, there, or at least possible.
Still, it took me a while to really get along to it. Started writing down some random thoughts a good six months ago, and every now and then between other things. Nothing in engine, all in a shiny, SRD like google-documents table. Read through various other sources for inspiration. The Pathfinder Witch for instance is pretty cool, and has been part of the character's inspiration in the first place. Elsewhere, too - monster abilities, other games, books, whatever I could think of. Eventually, I cut most of the random ideas away and reduced it to something that seemed well suited to replace the normal druid progression early on - and grant a new or improved ability every level, too.
So, three days ago or so, I actually started putting that fancy document into NWN. Lots of 2da work there - classes.2da first, of course. One long line handling things from it's hit dice or skillpoints over references to other assorted tables to NWNs weird calculation method for challenge rating. I mean, what is the point of setting the CR gain for each individual level? No matter, the hardest part about that line was finding an appropriate icon - a thing we have many of, luckily. Check silm_icon.hak if interested.
Thus, the class was theoretically in the game. Without any text labels, let alone abilities, and probably making the game crash due to a lack of related data. So, I copied a few other tables - the wizard saving throw table, the druid class and bonus feat table, and of course a table for the prestige class prerequisites, and renamed the class designator to 'witch'.
Prerequisites first - after some back and forth about what was even possible within NWN limitations I flat out required druid levels, and 5 ranks of survival. That way, you'd need to be a second level druid to get access to the prestige class, which was my intent. Aside from some odd multiclass combinations, this pretty much ensures it being an alternate for the druid only, and replaces most druid abilities with witch abilities. The PrC has 18 levels, and then goes into epic, granting a bonus feat every third one.
So, now I have a prestige class requiring essentially druid 2, and granting... still druid abilities, but with a worse base attack. Need to edit cls_feat_witch.2da for that. That, however, references feats, it does not define them. Thus I need to add my abilities to feats.2da, and there, reference a new line from spells.2da for all the active feats, create a spellscript for those feats, create feat duplicates for those changing with level in uses per day and define each one's succeeding feat, and when all's done, list them to be granted on the appropriate level in cls_feat_witch.2da. Oh, and remove all those druid and epic druid feats from it, too. And on top of that, I need to add tlk-entries, often two or per line in classes.2da, feats.2da and spells.2da, and reference them by line number in those files.
Well, at least most of that was tedious, but easy. Spells needed some fiddling to get their casting behaviour right, and it took me a while to get appropriate sound effects - the Cackle ability even actually cackles, with different voice sets for male and female. With that done, and about an hour of icon-delving, I moved on to spellscripts - first to test the 2da entries by means of the usual Hello World stuff, then for real. Making Curse of the Witch was easy - it's only a variant of Bestow Curse after all, though there I already realised that I needed my own functions for the caster level and saving throw DC since I was casting via feat, not druid spells, which will be handled by niv's adjustments to GetCasterLevel() later on. So, extra mini-library to be included. Easy.
Then I tried to quickly modify the Entangle script for my Vile Roots variant which does roughly the same as the spell, just with a difference in save DC. Easy - or is it?
I tell you, that spellscript is a mess. Or rather, those spellscripts, because due to it being an AoE, it actually has a spell script fired on cast as well as a onHeartbeat and onExit script for the AoE - and it would have had an onEnter script too had it been done properly. There are multiple variables declared that later remain unused, the comments sometimes speak of completely different terms than what's actually there, and the actual entanglement is deeply hidden inside a ridiculously multi-layered maze of while()'s and if()'s - and in dissecting that maze, I found that the NWN variant of Entangle works completely different from the D&D 3.5 Entangle spell too.
After much back and forth, I finally decided to nearly completely redesign the spell itself, and the scripts. A generic script containing ApplyEntangle() and RemoveEntangle() that I could use for the normal spell, too, and four new scripts for my Vile Roots, handling caster level and save DCs separately. Upside: I get to bypass another NWN issue with area spells. Since GetSpellSaveDC() always applies to the last spell the AoE creator cast, casting Entangle and then, say Flame Strike actually causes saves required by Entangle after the second spell to use that spell's save DC instead of its own. Vile Roots uses the scaling DC from my witch abilities, and passes that number onto ApplyEntangle(). Bit trickier to fix for Entangle itself, but I get around to fixing that spell once I'm certain my own works perfectly.
My other active engine spell feats were, again, fairly easy - Eternal Slumber is just a single target sleep after all, and Cackle throws a fear effect on every hostile creature within range - I blatantly stole most of that code from Fear and Wail of the Banshee.
So, after some more local testing, the class was pretty much done, with the majority of the work done in maybe seven or eight hours of work. That's... not too bad actually. Granted, a lot of abilities are for roleplaying use only and have no NWN engine effect, but still.
The PrC is online. Rebuilt my character, and aside an already corrected oversight with the class skills, seems to work as intended. The GetCasterLevel() fix is there too, though niv still has to look into a few spells using core libraries - don't really want to recompile every core script to make it work. Most however work, in most respects. Spell resistance and dispel checks are a hassle. At that, I might still need to write my own resist function for the feat-based spells unless he manages to get that factored in correctly.
If all works well, I'll look into adapting the original Entangle too, and maybe add active spell scripts to the Tongue of the Wild and On Wings of Black abilities. Certainly gained some insight into all those .2da files too, and I already have a few other ideas. Maybe finally make some assassin or blackguard spellcasting, as hinted earlier? Shouldn't be too difficult once we get all the save, resist and caster level stuff out of the way. For the divine side of spellcasters, it's very doable. For the non-magical ones, sure.
Still sucks for the arcanists, though. Maybe one day.
I'll have the class details up on the web page soon, too, for all those who are interested.
Edit: Class Writeup is online: Witch of the Wilds