Feature Specification: Loot drops

Scripted ALFA systems & related tech discussions (ACR)

Moderators: ALFA Administrators, Staff - Technical

Locked
Ronan
Dungeon Master
Posts: 4611
Joined: Sun Feb 20, 2005 9:48 am

Feature Specification: Loot drops

Post by Ronan »

Functional Requirements
This system provides target wealth drop values for creatures so that their looted wealth can conform to ALFA's weath standards. It then executes a specific script to add this loot to said creature. It does not touch or remove loot already marked as droppable.

If no specific loot script is defined, the system must generate its own random loot. The loot generated is based on the following:
  • The static salable wealth already dropped by this creature, no items already marked droppable will be removed by these scripts.
  • Its target wealth in ALFA's weath standards.
  • Its race.
  • Its classes.
  • Its alignment.
  • Its intelligence.
  • Its size.
The loot generated must be intelligent enough that builders are not tempted to switch out these scripts for others. This is of prime importance, since the absence of the default script may mean that creature's drops would not stay up-to-date with ALFA's wealth standards.

NWN Object Dependencies
Item resrefs.

Local Variables and External Configs
Local string on the creature, not changable during gameplay:
ACR_LOOT_SCRIPT: The custom loot script run. If none is defined, the default script is run.

Local int on the creature, not changable during gameplay:
ACR_LOOT_WEALTH_MODIFIER: A positive or negative modifier to the creature's desired total wealth drop.

Logging and Debugging (global LOG & DEBUG (on/off) constants)
If a creature is spawned who's droppable static wealth exceeds the wealth standards, print a warning message.

Persistence Requirements
None.

Event Dependencies
A creature's OnDeath event.
Ideally these scripts would be run when a creature loots a corpse, since that event is rarer and usually more spread-out over time than an OnDeath or OnSpawn event.
Last edited by Ronan on Fri Jun 16, 2006 5:15 am, edited 1 time in total.
Ronan
Dungeon Master
Posts: 4611
Joined: Sun Feb 20, 2005 9:48 am

Post by Ronan »

Leareth wants to try out the default loot generation script, so I'll post the skeleton code I've got so far, here. We really need to this to be intelligent and believable, so if people want to split it up with each taking a different racial type, thats fine.

Item resrefs should be defined as constants at the top of the script. Don't even bother making the resrefs correct, that sort of thing will change in NWN2, and we can just alter the constants to make it work in NWN1. I expect most items to be pretty generic: gems, potions, scrolls, that sort of thing.

Edit: I'm thinking this won't do, and that we will need a system which can read item prices from resrefs. This way the system will adapt to changes in item pricing automatically. This would require some initialization OnLoad with the items spawned, their prices read, and then saved. So the blueprint below may be missing some key functions.

Code: Select all

////////////////////////////////////////////////////////////////////////////////
//
//  System Name : ALFA Core Rules
//     Filename : acr_loot
//      Version : 0.1
//         Date : 5/13/06
//       Author : Ronan
//
//  Local Variable Prefix = None
//
//
//  Dependencies external of nwscript:
//  All item resrefs.
//
//  Description
//  This is the default script which generates loot drops for creatures. It uses
//  ALFA's wealth standards to calculate the desired wealth dropped, then
//  randomizes the drop based on the creature's race, classes, and alignment.
//  The creatures are already assumed to drop the loot they use, this script
//  adds additional loot to that (such as gems, potions, gold coins).
//
//  FIX FOR NWN2:
//  Additional racial types? Different item resrefs?
//
//  Revision History
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Includes ////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

#include "acr_loot_i"

////////////////////////////////////////////////////////////////////////////////
// Constants ///////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Structures //////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Global Variables ////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function Prototypes /////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

// The main function which runs the loot dropping.
void main();

////////////////////////////////////////////////////////////////////////////////
// Function Definitions ////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

void main() {
    int nTagetDropWealth = GetRandomTargetDropWealth(OBJECT_SELF);
    int nRace = GetRacialType(OBJECT_SELF);
    int nGoodEvilAlignment = GetAlignmentGoodEvil(OBJECT_SELF);
    int nLawChaosAlignment = GetAlignmentLawChaos(OBJECT_SELF);
    int nClass1 = GetClassByPosition(1, OBJECT_SELF);
    int nClass2 = GetClassByPosition(2, OBJECT_SELF);
    int nClass3 = GetClassByPosition(3, OBJECT_SELF);
    int nClass4 = GetClassByPosition(4, OBJECT_SELF);
    int nSize = GetCreatureSize(OBJECT_SELF);
    int nIntelligence = GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE, TRUE);

    // Possible approach: Add items without going over the limit, then fill the
    // rest up with gold?

    switch(nRace) {
        case RACIAL_TYPE_ABERRATION:
        break;

        case RACIAL_TYPE_ANIMAL:
            // No random loot for this racial type.
        break;

        case RACIAL_TYPE_BEAST:
            // No random loot for this racial type.
        break;

        case RACIAL_TYPE_CONSTRUCT:
            // No random loot for this racial type.
        break;

        case RACIAL_TYPE_DRAGON:
            // Gems and coins imbedded in its hide.
        break;

        case RACIAL_TYPE_DWARF:
        break;

        case RACIAL_TYPE_ELEMENTAL:
            // No random loot for this racial type.
        break;

        case RACIAL_TYPE_ELF:
        break;

        case RACIAL_TYPE_FEY:
        break;

        case RACIAL_TYPE_GIANT:
        break;

        case RACIAL_TYPE_GNOME:
        break;

        case RACIAL_TYPE_HALFELF:
        break;

        case RACIAL_TYPE_HALFLING:
        break;

        case RACIAL_TYPE_HALFORC:
        break;

        case RACIAL_TYPE_HUMAN:
        break;

        case RACIAL_TYPE_HUMANOID_GOBLINOID:
        break;

        case RACIAL_TYPE_HUMANOID_MONSTROUS:
        break;

        case RACIAL_TYPE_HUMANOID_ORC:
        break;

        case RACIAL_TYPE_HUMANOID_REPTILIAN:
        break;

        case RACIAL_TYPE_MAGICAL_BEAST:
            // No random loot for this racial type.
        break;

        case RACIAL_TYPE_OOZE:
            // No random loot for this racial type.
        break;

        case RACIAL_TYPE_OUTSIDER:
        break;

        case RACIAL_TYPE_SHAPECHANGER:
        break;

        case RACIAL_TYPE_UNDEAD:
        break;

        case RACIAL_TYPE_VERMIN:
            // No random loot for this racial type.
        break;
    }
}
User avatar
ç i p h é r
Retired
Posts: 2904
Joined: Fri Oct 21, 2005 4:12 pm
Location: US Central (GMT - 6)

Post by ç i p h é r »

Are our wealth standards posted anywhere we can link to from here?

As far as random loot drops go, the tables are pretty much defined in the DMG so all we have to do is adjust the values stated in the DMG to match our standards and prune the treasure list to what is/isn't acceptable for ALFA, right?
User avatar
Fionn
Ancient Red Dragon
Posts: 2942
Joined: Sun Jan 04, 2004 7:07 am
Location: Seattle, WA

Post by Fionn »

we also have to deal with a PW paradigm - I wouldn't mind seeing DimRet as a safety net just in case the flee/despawn scripts fail.
PC: Bot (WD)

Code: Select all

     -----          -----          -----          -----
    /     \        /     \        /     \        /     \
   /  RIP  \      /  RIP  \      /  RIP  \      /  RIP  \      /
   |       |      |       |      |       |      |       |      |
  *| *  *  |*    *| *  *  |*    *| *  *  |*    *| *  *  |*    *|
_)/\\_//(/|_)(__)/\\_//(/|_)(__)/\\_//(/|_)(__)/\\_//(/|_)(__)/\\_(
Ronan
Dungeon Master
Posts: 4611
Joined: Sun Feb 20, 2005 9:48 am

Post by Ronan »

They are in the standards forum, and I don't think thats linkable for a lot of people. But the exact content of the wealth standards (represented by acr_wealth_i.nss) shouldn't concern this system. This system should only worry about what to drop within a given wealth limit.

I don't think DMG drop tables really work, they presume a DM deciding everything which is dropped. We've only got scripts, and we can't be having a creature like a dragon, for example, drop something such as a masterwork lute. Or a halfing drop a large-sized greataxe.

Fionn, I'm prefering to leave dimrets up to the wealth standards as well. If T-dawg and crew says he wants them, we can add them. But either way, this system shouldn't know the difference. This system should be able to react to whatever ALFA's wealth standards may change to in the future.
User avatar
Fionn
Ancient Red Dragon
Posts: 2942
Joined: Sun Jan 04, 2004 7:07 am
Location: Seattle, WA

Post by Fionn »

well, one of my ideas would be to cache the %wealth on the PC periodically. Then, if we see a PC at 25% of wealth, the goblins just happen to be 10-25% wealthier. If we see a PC at 300% of wealth, the goblins he kills tend to be poorer than normal. This could be done either in the loot scripts, or by decrementing the loot table used.

What I don't want to see is a system where we trust the DMs to monitor for PGing, and end up with farmable mobs again. We can't force them to use our spawn system, so we can't be sure the mobs will flee the 300th time the same PC hits the same area. If we do this right, PGing won't be against the rules, it'll just be a waste of time. Better yet, it won't be obvious that drops are tapering off for those that don't need them.
PC: Bot (WD)

Code: Select all

     -----          -----          -----          -----
    /     \        /     \        /     \        /     \
   /  RIP  \      /  RIP  \      /  RIP  \      /  RIP  \      /
   |       |      |       |      |       |      |       |      |
  *| *  *  |*    *| *  *  |*    *| *  *  |*    *| *  *  |*    *|
_)/\\_//(/|_)(__)/\\_//(/|_)(__)/\\_//(/|_)(__)/\\_//(/|_)(__)/\\_(
User avatar
ç i p h é r
Retired
Posts: 2904
Joined: Fri Oct 21, 2005 4:12 pm
Location: US Central (GMT - 6)

Post by ç i p h é r »

I don't think DMG drop tables really work, they presume a DM deciding everything which is dropped. We've only got scripts, and we can't be having a creature like a dragon, for example, drop something such as a masterwork lute. Or a halfing drop a large-sized greataxe.
Not as they are, right, and we would need to modify them to fit our project. I was asking b/c we need some specifics here to work from, so if it's not going to be DMG/MM or any other source book tables (as a starting point), then we need to define them.
User avatar
AlmightyTDawg
Githyanki
Posts: 1349
Joined: Sun Sep 26, 2004 12:56 am

Post by AlmightyTDawg »

The "ideal" is for loot to be tied to XP gained. But it's got a lot of logical problems writ large - some creatures giving XP should drop no loot (animals, etc) and some creatures that should drop loot might be DimRet conditions (0-1 xp, but they're still waving a longsword at you).

Now, it's possible people decide to say the hell with logic, but I'm suspecting that's not gonna fly. Plus it's gonna run into the trouble of mixed parties and one guy with DimRet possibly ruining it for the rest and so on. Given that you can't directly match infinite content to a finite XP-loot connection, I think you err somewhat conservatively on the numbers, let the chips fall where they may and let DMs make up the balance.

One thing that has been discussed is the idea of varying value items - mundane weapons and armor for example are, in most cases, just 20% buyback material, if not less in a "junk weapons" system. Take gems, gold, potions, or scrolls, and they're probably "wealth"-wise worth near max of their value. So it's possible to use existing conditions, like DimRet standing, wealth, etc. as a weighting influence in a selection heurisitc. But beyond that, all that's in those standards are just shots in the dark with no in-game testing.
AlmightyTDawg wrote:Wealth from Static Spawns

As the majority of wealth maintenance is intended to be done intelligently at the DM level, adjustments to static content should be considered. Since it seems difficult to tie experience gained to the value of a given creature, and additional factors such as PC level and Diminishing Returns can influence the equation, the preference would be for static content to err on the low side. A timetable for implementation would be at the behest of admin, but the following table should be considered recommendations in the interim. The following definitions apply:
  • Average Value: The weighted average of any particular spawn of a given CR using a loot merchant (or similar random loot system). For spawns dropping what items they carry, this should be considered the maximum value for a given CR. Note that any average value below this is acceptable; this is the “maximum average.”
  • Maximum Value: The highest value that can be dropped from a single loot merchant for a spawn of that CR.
  • Max Gem Value: The highest value of gem that can be placed in a loot merchant for a spawn of that CR.
Table 3: Infispawn Drop Standards

CR/Level........Avg Value........Max Value........Max Gem........Maximum Value Item Notes
......1.....................6....................12....................3................Lvl0 scrolls
......2....................15...................30....................8................Lvl1 scrolls, Greenstone, Malachite
......3....................30...................60...................15...............Lvl1 potions, Fire Agate, 10gp ALFA gems
......4....................51..................102..................26...............Greatsword, Tower shield, Shortbow, +1 skill, Phenalope, Aventurine
......5....................78..................156..................39...............Lvl2 scrolls, MW leather, Heavy Crossbow, Longbow
......6...................111.................222..................56...............MW Chain Shirt, MW Large Shield, Amethyst, Fluorspar, 50 gp ALFA gems
......7...................150.................300..................75...............Lvl2 potions, MW Chainmail, MW Tower Shield
......8...................195.................390..................98...............Lvl3 scrolls
......9...................246.................492.................123..............+2 skill, +1 to single save, Garnet, 100 gp ALFA gems
......10.................303.................606.................152..............MW Bastard Sword, Alexandrite
......11.................366.................732.................183..............All MW Weapons, +2 Mighty Longbow
......12.................435.................870.................218..............Lvl3 potions
......13.................510................1020................255..............Lvl4 scrolls, +3 skill, Topaz
......14.................591................1182................296..............+1 Leather/Studded, +1 Small Shield
......15.................678................1356................339..............+1 Banded Mail, +1 Tower Shield, +1 universal saves, +1 single ability

This table applies to infinitely spawning content only. Any named NPCs whose death will effect a permanent change on a server, and spawns who only appear due to a static or other quest, are exempt from this table. Further, if characters attack static spawns as part of a DM-run event, the DM is free to use the “Wealth Per DM-Run Session” rules, so long as the value of the spawns and the XP gained from defeating them are taken under consideration. The goal is for spawn hunting to be a generally cash-flow-positive experience, but to a slightly lesser extent than it can currently be; only clearly unacceptable levels of farming should lead to excessive wealth values. Players should also be made aware that repeatedly hunting spawns which give zero experience should be avoided at all costs.
For those wondering, the equation is 3CR^2 + 3, max is double, gem is half.
Turquoise bicycle shoe fins actualize radishes greenly!
Save the Charisma - Alter your reactions, even just a little, to at least one CHA-based check a day!

Quasi-retired due to law school
Past PC: Myrilis Te'fer
User avatar
Fionn
Ancient Red Dragon
Posts: 2942
Joined: Sun Jan 04, 2004 7:07 am
Location: Seattle, WA

Post by Fionn »

Thus my suggestion to tie drops to %wealth of the killer. There will be occasions where somebody is poor and grouped with a very wealthy party that takes most of the drops. We may also see a tank give all his stuff to the support during the fight. Hopefully the DMs can handle both of those.

For the most part, decrementing the loot tables (or incrementing if the PC is poor) is exactly what you'd do in PnP. This is a constantly self-correcting system, and reasonably invisible. If we want to get fancy, we intro some fuzzy logic so that even the fabulously wealthy can still get lucky on occasion.

It would be nice to have two loot systems. One for wealth, with the scripts described above, and a second for gear, defined by GetRace() &/or GetClass. If we have the resources, we'd do the latter onSPawn to randomize mob gear. If not, we just replace their inventory onDeath with the random (and cheap) gear, and spawn a purse near them with the wealth.
PC: Bot (WD)

Code: Select all

     -----          -----          -----          -----
    /     \        /     \        /     \        /     \
   /  RIP  \      /  RIP  \      /  RIP  \      /  RIP  \      /
   |       |      |       |      |       |      |       |      |
  *| *  *  |*    *| *  *  |*    *| *  *  |*    *| *  *  |*    *|
_)/\\_//(/|_)(__)/\\_//(/|_)(__)/\\_//(/|_)(__)/\\_//(/|_)(__)/\\_(
Ronan
Dungeon Master
Posts: 4611
Joined: Sun Feb 20, 2005 9:48 am

Post by Ronan »

Fionn wrote:It would be nice to have two loot systems. One for wealth, with the scripts described above, and a second for gear, defined by GetRace() &/or GetClass. If we have the resources, we'd do the latter onSPawn to randomize mob gear. If not, we just replace their inventory onDeath with the random (and cheap) gear, and spawn a purse near them with the wealth.
I don't want to do either of those, because it gives builders a good reason not to use our system. A builder makes the monster, and I don't think he wants us going in there and randomizing its inventory or equiped items. In some cases he might, but others not, and I think it just adds uneeded complexity. If random equipment is desired, that could be a seperate system with no coupling to this one needed at all.

Again, the actual value of the wealth dropped is not decided by this system at all, that all comes from the wealth standards. All this system does is decide how that wealth should be allocated.

And Almighty, I was not planning on having DemRets as a default in NWN2, but just limited populations (over RL-time, not server resets).
User avatar
AlmightyTDawg
Githyanki
Posts: 1349
Joined: Sun Sep 26, 2004 12:56 am

Post by AlmightyTDawg »

Ronan wrote:And Almighty, I was not planning on having DemRets as a default in NWN2, but just limited populations (over RL-time, not server resets).
I think I see in the context why you wouldn't have DimRets, but I guess the same case occurs when people fight under-CR'd mobs. For example, a 10th level goes and beats up five CR 1/2s, not really a challenge, no XP for the lot of them, right?

I should think you'd want some level of "directed" randomness. It's very easy to say that someone's farming when they go to the same zone over and over again. A char hogging the spawns in the name of "pruning," however, is a much sketchier case. Speaking from the AR rules-enforcement side of things. A finite population model would mean that each mob is "meant" to be there, so it's not an exploitation of the medium.

To handle it, I think you'd probably want - and you may already have it in mind - some variable representing spawn probability as some kind of inverse of the number of mobs hunted. Just be careful about the paradigm shift involved.
Turquoise bicycle shoe fins actualize radishes greenly!
Save the Charisma - Alter your reactions, even just a little, to at least one CHA-based check a day!

Quasi-retired due to law school
Past PC: Myrilis Te'fer
Ronan
Dungeon Master
Posts: 4611
Joined: Sun Feb 20, 2005 9:48 am

Post by Ronan »

AlmightyTDawg wrote:To handle it, I think you'd probably want - and you may already have it in mind - some variable representing spawn probability as some kind of inverse of the number of mobs hunted. Just be careful about the paradigm shift involved.
Currently, the model in my mind is that nomad spawn chance more or less proportional to population, and inversly proportional to the amount of area that spawn inhabits.

Technically hopping between spawns is still possible, depending on how the builder sets them up. I'd vastly prefer to handle any sort of needed "dimret" style rewards in the encounter/spawn systems themselves, which would get rid of this the problem of GP rewards without XP.
User avatar
ç i p h é r
Retired
Posts: 2904
Joined: Fri Oct 21, 2005 4:12 pm
Location: US Central (GMT - 6)

Post by ç i p h é r »

But what are the actual drops OnDeath and how would they be computed? That's not clear from the initial spec and it needs to be for anyone to attempt to build this, unless you want it to be completely subjective.

The tables in the DMG I was referring to are the treasure lookups for coins, goods, and items and the lookups for the type of goods (gems or art) or items (mundane or magical). These are EL based random treasure tables which can be influenced by the monster in question (defined in MM) and the location of the treasure (lair or patrol). Clearly, the values in the DMG are not consistent with our own standards so they can't be used unmodified.

The standards ATD reveals above define avg and max values for drops but goes no further. The creature and the circumstances affect the actual gp value chosen from this table. While likely trivial to define, we still need the next set of tables which break down the possibilities into coins, goods, and items (or anything else for that matter). This is where the randomization comes into play and what's missing here. How the listed factors above ultimately affect the drop is also not clear but needs to be.

So for instance, PC kills a CR1 creature. From the standards, we know the treasure drop must fall between 0 and 12 gp in value. This can be in coins, goods, or items. Other factors will weigh into what actual amount is dropped (affects value up or down for simplicity), but we still need the subequent tables to tell what ultimately falls out of the system (ie a silver coin, a painting, a wooden spoon, shiny bracers, etc). I suspect that this is something that falls to the standards team to define....right?
User avatar
AlmightyTDawg
Githyanki
Posts: 1349
Joined: Sun Sep 26, 2004 12:56 am

Post by AlmightyTDawg »

I'm personally not terribly concerned about the system. As it was written, all I knew were NESS loot merchants, which take a supply of items in the merchant and selects one (or possibly two or three) at random. The way that ends up working is the distribution of items equals your odds. Put four CLWs and a longsword in the merchant and 80% of the time the drop will be a CLW. In that context, getting any more particular than average and max seemed a little out of place to me.

The treasure tables are more than a bit pedantic, but that might yet still inspire someone. As far as I'm concerned, make sure the average result - whatever you equation/metric for that might be - doesn't exceed the average and the max can't be exceeded in the best case. As long as you meet those two things, I suspect there's an infinite number of distribution schemes that can be constructed.

Truth be told I'm not terribly interested in building one, but I would help check the feasibility of what someone comes up with.
Turquoise bicycle shoe fins actualize radishes greenly!
Save the Charisma - Alter your reactions, even just a little, to at least one CHA-based check a day!

Quasi-retired due to law school
Past PC: Myrilis Te'fer
Ronan
Dungeon Master
Posts: 4611
Joined: Sun Feb 20, 2005 9:48 am

Post by Ronan »

ç i p h é r wrote:But what are the actual drops OnDeath and how would they be computed? That's not clear from the initial spec and it needs to be for anyone to attempt to build this, unless you want it to be completely subjective.
I've no idea what they are ;) I'm hoping people will discuss options in this thread. I do agree that needs to be defined, but defining it is most of the system. To a large extent I think its easier to code everything out (using constants in place of resrefs for now) and discuss that.

I do think something needs to be changed in the defined parts of the spec though: All items spawned by this system should be spawned OnModuleLoad, and have all their values recorded (or computed, as is the case with items of less "worth" than their retail cost). That way changes to items in the toolset are updated dynamically, and as ALFA's weath standards change (we may decide to value heavier items less, for example).

As far as randomness, I think we'll need to limit that a bit. If we call the wealth the mob already has marked as dropped nDroppedWealth,
nMaxRandom = nAverageWealth - nDroppedWealth;
nTargetWealth = nAverageWealth +/- nMaxRandom.
Since the wealth already marked droppable is a floor, we can't go below it, and too much randomness would raise the mean. All this is handled in the wealth standards however, not the loot system.
Locked