I made this XP system specifically for PW Arkhalia in 2011. They didn't yet know what they want so I tailored a system with high degree of customization. This is done with a 2DA file from which the script reads all informations such as BaseXP, bonus penalty for high/lower PC level, party size bonus/penalty, penalty for associates and more.
It is essentialy very simple and fits for action and hack&slash modules. The 2DA lookups are a bit expensive but in the gameplay this isn't noticeable not even when there are 20+ creatures killed in same fashion. Still yet it could be improved to cache 2DA values as local ints which I might eventually do if desired.
Note: this system is running over three years on two PWs, both still active, both action style where monsters dying in hundrets. There are no lag issues caused by this system. Believe it or not.
Package contains:
- readme with detailed instructions how to install it and modify default settings
- ERF package to import this into your module
- shxp_settings.2da which needs to be put into override
- test module to test the xp settings in real time (see the image)
Update: I added 2DA caching so this should be a bit more efficient. You won't spot the differency though, I assure you. Keep in mind this, and neither any of the highly configurable systems isn't perfectly optimized. The more configuration options (and the easier way to set them up for end user) the less can be the script optimized and efficient. If you aim for 100% efficiency, then the only way is to write your own XP calculation script with everything (hard)coded in.
Author clarification:
Due to the comment about this and rating this project acquired, I consider important to defend this. Before I will explain all the stuff, I want to tell that this is what I do. My projects always had comments like this and bad rating from other scripters and builders who didn't know how things works, didn't understood the purpose or the advantage of my concept or because I proved they are less skilled than they thought. So. I think I proved already that I know things and I am one of the biggest NWN gurus. You don't have to believe anything that I say, I know lots of peoples out there thinks they know better than me and hate me and my projects. If you are one of those, just rate 1star and don't try to rationalize it. For others I bring a clarification of the method I used for this project.
1) 2DAs are evil! Anything that uses them is bad!
This is an old propaganda. Yes compared to for example GetLocalString they are somewhat slower. But I am scripting in NWN for decade and till that time I saw only one instance where 2DA was a problem and that was PRC 2DA Caching. First time you run PRC on a server, all 2DAs gets cached into database. This takes few hours to complete. Paradox is that if they didn't cached 2DAs and simply used 2DA lookups there wouldn't be any problem and the game would be still smooth. Also, do not mistake that Get2DAString would always located high-priority 2da, opened it, found the position and read from it - this is not true. If it would then changing 2DA manually in a middle of running game would work but its not working. Thats because 2DA are (and always were) loaded when opening module and stored in memory. Another thing that is not known is that the game engine itself uses 2DA lookups. Every here and there. Lastly, 1.69 implemented some sort of 2DA caching which improved 2DA lookups performancy.
In my opinion the 2DA lookups aren't any bad than database calls - doesn't matter if BIO db or NWNX. Anyone who know how NWNX works will agree - if you don't you got to trust me. Might explain that later in some kind of tutorial but NWNX calls aren't any better. If someone want to prove otherwise, please bring a proofs. Clock the speed of thousand 2da call, thousant cached 2da call (mean the method I used in this newer version or something similar), thousand bio DB calls and thousand nwnx DB calls.
2) That must cause big lags in big combats.
Funny, do you have a proof of that? No... You maybe read the code and you are doing precipitate conclusions. As I said already, this XP system is currently working on two PWs (and thats the first unopimized version there). Both actions, one abadoned by players but the other one (Arkhalia czech PW) is still very active and there are 10-15 peoples in a prime time (20:00-23:00 GMT+1). And this is an epic loot server where 99% events happens at lvl 40. Monsters dying there in dozens every hour and the module is capable of running 2weeks without significal lags. This is possible because the server is running on linux and I improved whole module from everything that consumed lots of resources (for example, there was an area using 100 gargoyle statues as a decoration lol). Anyway. What is important to understand is that monsters doesn't die that often. Neither in big combats. On average a monster dies maybe once per two seconds. Much less if you count the time when there are no players. Even when you cast a banshee spell - the spell effects (damage, death) doesn't all occur in one moment but are always delayed. So actually that two monsters died in the exact same moment never really happens. Not even in a epic combats.
3) Lags that are real.
To be honest, there actually are big lags often when monster die. But this lag is not caused by my 2DA system but due to the badly designed monster AI and bad module design. What happens when a monster dies is that it tell all others in close range to attack its killer. Twice actually. That cause all surrounding creatures to trigger OnConversation event and start the full combat routine (all twice). So if there is more than 40 monsters at once it starts to be noticeable. The biggest problem is actually when a spell with aoe range hit such huge monster pack. Combined with a case when some of the monsters dies, you can get a lag that crashes your server. Worse if the spell is an AOE spell like storm of vengeance and worst if this is stacked with itself or other AOE. I partially fixed this issue in my community patch project, but its still there. If you are a builder try to avoid designing such situation or if its unavoidable then consider using my Low-Impact AI which was specifically designed for this situation (since we had several areas on Arkhalia where monsters were designed this way).
Attachment | Size |
---|---|
![]() | 26.83 KB |
Xp systems should never use 2das, esp for PWs...
2da lookups, even cached, are very inefficient compared to a simple script alternative.
*Voting 1 - Not Recommended to Anyone*
(My honest technical assessment)
I am known for doing things that others would not dare to do.
They say 2DAs are evil, but I did it anyway and it doesn't seems to be problematic.
Will try to incorporate that caching if you are worried about 2DAs.
2DA systems are often more maintainable than scripts, and not too heavy, last I heard. I'd welcome some metrics, and/or comments from other PW owners.
I use a 2da file as the basis for my PW's basic XP table. It's based on the D&D 3.0 table with some adjustments (for handling CRs from "less than 1" to "more than 40"), then the scripting makes further adjustments for things like level, party level, henchmen, etc. Haven't seen any drawbacks to it on my end.
Removing my vote, but it seems 12 2da reads per kill is VERY inefficient/laggy, i would still be leery of using this system myself till fully tested...
12 2da reads per kill? Dang. That does sound like it would get laggy in big fights. My comment above was just in reference to my PW's XP system, which uses a single 2da read per kill, just for a base XP value by CR, rather than for that plus multiple other variables.
Definately warrants further testing by the look of it. And how well it really does could depend entirely on what's going on otherwise in the module using it.
Still, probably a good example for scripters to look at. I know I've learned a lot over the years looking at how others have gone about using NWScript to get things done. With 2da caching, there may not even be much of a performance hit it the rest of the script is efficient.