I’m setting up a custom XP reward system for my module - I need one more thing to finalize it: a formula to calculate the party ECL. I tried to find the exact script this site uses, but failed… Anyone?

Power grows geometrically in D&D, so, if I had to guess, I’d say the square root of the sum of the squares of the individual member ECLs. (Anything below 1 gets treated as 1.) A party of one 9 and two 8 ECL members would be: sqrt(81 + 64 + 64) = 14.5 ECL.

Shouldn’t Party ECL be an average of the ECL of the characters?

If you have a party of 9 and 2 8s, you would expect them to get the proper exp from monsters of level 8 or 9, not from enemies of level 14-15.

Also, from the website the OP linked, the note that defines Party ECL states the following:

- This is the average ECL of a four-member party of characters. The party level for a group of
fewerthan four characters will belowerthan the average ECL. The party level for a group ofmorethan four characters will behigherthan the average ECL. See Challenge Ratings and Encounter Levels on page 48 of the Dungeon Master’s Guide.

So, I suppose you want a script that considers an average party size of 4 to calculate the party ECL.

In that case, it would be something like this:

```
//Returns the ECL of oTARGET.
int GetTargetECL(object oTARGET)
{
string sSUB = Get2DAString("racialsubtypes", "ECL", GetSubRace(oTARGET));
int nECL = GetHitDice(oTARGET) + StringToInt(sSUB);
if (nECL < 1) nECL = 1; //Fail-safe.
return nECL;
}
//Returns the average ECL of the party of oPC. Depending on the average size of party.
//nASSOCIATE if set to TRUE, familiars, animal companions, henchmen, ecc.. will also count.
//fAVARAGE is a float that will assume the average size of the party (4.0 by default).
float GetPartyECL(object oPC, int nASSOCIATE = FALSE, float fAVERAGE = 4.0)
{
int nECL = 0;
int nCACHE = GetNum2DAColumns("racialsubtypes");
object oPARTY = GetFirstFactionMember(oPC, FALSE);
while (oPARTY != OBJECT_INVALID)
{
if (nASSOCIATE == TRUE) nECL = nECL + GetTargetECL(oPARTY);
else if (GetAssociateType(oPARTY) == ASSOCIATE_TYPE_NONE) nECL = nECL + GetTargetECL(oPARTY);
oPARTY = GetNextFactionMember(oPC, FALSE);
}
float fECL = IntToFloat(nECL) / fAVERAGE;
if (fECL < 1.0) fECL = 1.0; //Fail-safe.
return fECL;
}
```

I also added a few options to the second subroutine if you want to consider associates (animal companions, familiars, ecc) in the calculation or not and an option to change the avarage size of party if it’s not meant for a party of 4.

I’m not looking for scripts - I’ll do it myself, I just need the mathematical formula.

I’m ignoring the companions/summons in this. I wanna stick to the idea that ECL x is a 4-player party, each one level x. The site I linked calculates the ECL of a party based on the individual ECLs and party size, but it’s not the average ECL.

I’ve seen a suggestion online to add up all the PC levels (including race) and divide by 4, but that’s not even close… Same goes for adding up all levels and diving the result by the number of party members. I’ve also seen adding up all squares, rooting the result and diving it by 2, which is closer, but still far off at higher levels…

E.g.: A party of 3 lvl 15 humans, according to the online calculators, has an ECL of 14.2. How’d they calculate that?

That’s just saying that one 9 ECL and 2 8 ECL’s should be an even match for a single 14 ECL opponent.

I don’t think that’s correct, going by your original formula this would mean that a 6man party with 2 characters being level 9 and 4 being level 8 would be an event match for a single level 20 ECL opponent (I’m pretty sure that they would wipe).

I’ve checked it and it’s not a mean of any kind (not aritmethic, not geometric, not harmonic), this means that they used a custom formula for it. Or it could just be an error in their calculator…

Every single online ECL calculator I’ve checked gives the exact same results - I’m pretty sure they all have the same formula, but what is it…?

Well sure, if you take any formula to corner-case extremes it’s going to break. But for rough parity I’d expect it would work.