Skip to content

NPC Scaling

One of the first introductions of a native scaling system includes Global Base NPC Scaling, profile based is planned for a later release but for now we will be covering the global system.

Global Base NPC Scaling

  • Traditionally when scaling an entire zone whether it is for custom content or for PEQ's purposes, we start with a blank slate of the zone or NPCs that have been transplanted. Every individual NPC needs to be tweaked by hand to handle stat / combat scaling for content unless you are using custom scripted solutions. We needed an easier way to at least handle the base scaling

Introduction and Data Structure

  • Take a look at the table below, imagine that this data drives all of the stats for every NPC that you'd like to scale. In order to understand this a bit more we need to break a few things down.

Type

Type Description Determination
0 Trash No special flags set
1 Named Has flag rare_spawn set in npc_types to 1 - or - name has # in the beginning - or - first character in name is capitalized
2 Raid Has flag rare_spawn set in npc_types to 1
  • This data is simply an example of Levels 50-52, but has data from every Type
select * from npc_scale_global_base where level >= 50 and level <= 52 order by type;

How Attributes are Loaded

  • The stats in the table will apply to an NPC when their original stat or attribute is 0 in the database, so to let an NPC be completely handled by this table you would set all the following stats to 0 in the npc_types table
  • As alluded to before, each NPC is keyed off of type and level, so if an NPC is flagged as a named and is level 52, it will inherit the values from the row of type 1 and level 52 which has an hp value of 16080, this happens immediately upon spawn / repop
*type *level ac hp accuracy slow_mitigation attack strength stamina dexterity agility intelligence wisdom charisma magic_resist cold_resist fire_resist poison_resist disease_resist corruption_resist physical_resist min_dmg max_dmg hp_regen_rate attack_delay spell_scale heal_scale special_abilities
0 50 245 10000 50 0 50 194 194 194 194 194 194 194 26 26 26 26 26 41 10 74 204 50 21 100 100
0 51 249 11700 53 0 53 197 197 197 197 197 197 197 27 27 27 27 27 42 11 78 231 51 20 100 100
0 52 253 13400 56 0 56 200 200 200 200 200 200 200 27 27 27 27 27 43 12 81 258 52 20 100 100
1 50 294 12000 60 0 60 233 233 233 233 233 233 233 31 31 31 31 31 49 12 89 245 60 21 100 100 13,114,121,1
1 51 299 14040 64 0 64 236 236 236 236 236 236 236 32 32 32 32 32 50 13 94 277 61 20 100 100 13,114,121,1
1 52 304 16080 67 0 67 240 240 240 240 240 240 240 32 32 32 32 32 52 14 97 310 62 20 100 100 13,114,121,1
2 50 368 100000 75 0 75 291 291 291 291 291 291 291 100 100 100 100 100 100 15 111 306 75 21 100 100 1,12,18,113,114,115,116,117,121,1^31,1
2 51 374 130000 80 0 80 296 296 296 296 296 296 296 102 102 102 102 102 102 17 117 347 77 20 100 100 1,12,18,113,114,115,116,117,121,1^31,1
2 52 380 140000 84 0 84 300 300 300 300 300 300 300 104 104 104 104 104 104 18 122 387 78 20 100 100 1,12,18,113,114,115,116,117,121,1^31,1

Special Abilities

  • For special abilities we load things slightly differently, we don't just look for having "no special abilities" on the NPC before we apply the template to them. In this implementation, we check to see if all of the base stats are actually zero value before we consider this NPC an auto scaled npc before deciding to apply Special Abilities from the database table template
bool NpcScaleManager::IsAutoScaled(NPC *npc)
{
    return
        (npc->GetHP() == 0 &&
         npc->GetMaxDMG() == 0 &&
         npc->GetMinDMG() == 0 &&
         npc->GetSTR() == 0 &&
         npc->GetSTA() == 0 &&
         npc->GetDEX() == 0 &&
         npc->GetAGI() == 0 &&
         npc->GetINT() == 0 &&
         npc->GetWIS() == 0 &&
         npc->GetCHA() == 0 &&
         npc->GetMR() == 0 &&
         npc->GetFR() == 0 &&
         npc->GetCR() == 0 &&
         npc->GetPR() == 0 &&
         npc->GetDR() == 0);
}

Scaling Commands

  • scale [static/dynamic] (With targeted NPC)
  • scale [npc_name_search] [static/dynamic] (To make zone-wide changes)
  • scale all [static/dynamic]

With the above commands, static essentially going to take the scaling profile from the table above and applied it directory to the npc_types data on the NPC itself

Example: #scale static

Example: #scale dynamic

Similarly, the static and dynamic commands work based on a name search filter

You must click before actually pushing the changes to make sure it is the change you want to make

Zonewide

To simply change everything in the zone you can use #scale all [static/dynamic] - just like name search it will ask for confirmation before applying

Logging

To see stats being loaded on NPC's during a repop or spawn, under the NPC Scaling logging category you can see attributes that are being applied to the NPC. The below is a snippet from a #repop in Griegs End

[NPC Scaling] (a shrouded willsapper) level: 54 type: 0 Auto: true Setting: ac: 261 max_hp: 16800 accuracy: 62 slow_mitigation: 10 atk: 62 str: 206 sta: 206 dex: 206 agi: 206 int: 206 wis: 206 cha: 206 mr: 28 cr: 44 fr: 28 pr: 14 dr: 28 cr: 44 pr: 14 min_hit: 48 max_hit: 169 hp_regen: 54 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a shrouded willsapper) level: 53 type: 0 Auto: true Setting: ac: 257 max_hp: 15100 accuracy: 59 slow_mitigation: 0 atk: 59 str: 203 sta: 203 dex: 203 agi: 203 int: 203 wis: 203 cha: 203 mr: 28 cr: 43 fr: 28 pr: 13 dr: 28 cr: 43 pr: 13 min_hit: 46 max_hit: 154 hp_regen: 53 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a shrouded willsapper) level: 53 type: 0 Auto: true Setting: ac: 257 max_hp: 15100 accuracy: 59 slow_mitigation: 0 atk: 59 str: 203 sta: 203 dex: 203 agi: 203 int: 203 wis: 203 cha: 203 mr: 28 cr: 43 fr: 28 pr: 13 dr: 28 cr: 43 pr: 13 min_hit: 46 max_hit: 154 hp_regen: 53 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a shrouded willsapper) level: 54 type: 0 Auto: true Setting: ac: 261 max_hp: 16800 accuracy: 62 slow_mitigation: 10 atk: 62 str: 206 sta: 206 dex: 206 agi: 206 int: 206 wis: 206 cha: 206 mr: 28 cr: 44 fr: 28 pr: 14 dr: 28 cr: 44 pr: 14 min_hit: 48 max_hit: 169 hp_regen: 54 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a shrouded willsapper) level: 55 type: 0 Auto: true Setting: ac: 266 max_hp: 18500 accuracy: 65 slow_mitigation: 10 atk: 65 str: 210 sta: 210 dex: 210 agi: 210 int: 210 wis: 210 cha: 210 mr: 29 cr: 45 fr: 29 pr: 15 dr: 29 cr: 45 pr: 15 min_hit: 50 max_hit: 184 hp_regen: 55 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a shrouded willsapper) level: 53 type: 0 Auto: true Setting: ac: 257 max_hp: 15100 accuracy: 59 slow_mitigation: 0 atk: 59 str: 203 sta: 203 dex: 203 agi: 203 int: 203 wis: 203 cha: 203 mr: 28 cr: 43 fr: 28 pr: 13 dr: 28 cr: 43 pr: 13 min_hit: 46 max_hit: 154 hp_regen: 53 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a defiled dreamweaver) level: 54 type: 0 Auto: true Setting: ac: 261 max_hp: 16800 accuracy: 62 slow_mitigation: 10 atk: 62 str: 206 sta: 206 dex: 206 agi: 206 int: 206 wis: 206 cha: 206 mr: 28 cr: 44 fr: 28 pr: 14 dr: 28 cr: 44 pr: 14 min_hit: 60 max_hit: 212 hp_regen: 54 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a deadly dreamweaver) level: 54 type: 0 Auto: true Setting: ac: 261 max_hp: 16800 accuracy: 62 slow_mitigation: 10 atk: 62 str: 206 sta: 206 dex: 206 agi: 206 int: 206 wis: 206 cha: 206 mr: 28 cr: 44 fr: 28 pr: 14 dr: 28 cr: 44 pr: 14 min_hit: 48 max_hit: 169 hp_regen: 54 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a shadowy figure) level: 58 type: 0 Auto: true Setting: ac: 278 max_hp: 23600 accuracy: 74 slow_mitigation: 10 atk: 74 str: 219 sta: 219 dex: 219 agi: 219 int: 219 wis: 219 cha: 219 mr: 30 cr: 47 fr: 30 pr: 18 dr: 30 cr: 47 pr: 18 min_hit: 137 max_hit: 551 hp_regen: 58 attack_delay: 19 spell_scale: 100 heal_scale: 100 special_abilities: 8,1
[NPC Scaling] (a tormented pugilist) level: 55 type: 0 Auto: true Setting: ac: 266 max_hp: 18500 accuracy: 65 slow_mitigation: 10 atk: 65 str: 210 sta: 210 dex: 210 agi: 210 int: 210 wis: 210 cha: 210 mr: 29 cr: 45 fr: 29 pr: 15 dr: 29 cr: 45 pr: 15 min_hit: 118 max_hit: 430 hp_regen: 55 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a tormented pugilist) level: 55 type: 0 Auto: true Setting: ac: 266 max_hp: 18500 accuracy: 65 slow_mitigation: 10 atk: 65 str: 210 sta: 210 dex: 210 agi: 210 int: 210 wis: 210 cha: 210 mr: 29 cr: 45 fr: 29 pr: 15 dr: 29 cr: 45 pr: 15 min_hit: 118 max_hit: 430 hp_regen: 55 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a shrouded minion) level: 75 type: 2 Auto: true Setting: ac: 572 max_hp: 1850000 accuracy: 330 slow_mitigation: 75 atk: 310 str: 342 sta: 342 dex: 342 agi: 342 int: 342 wis: 342 cha: 342 mr: 150 cr: 150 fr: 150 pr: 80 dr: 150 cr: 150 pr: 80 min_hit: 1024 max_hit: 3816 hp_regen: 1500 attack_delay: 13 spell_scale: 100 heal_scale: 100 special_abilities: 1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1
[NPC Scaling] (a shrouded minion) level: 75 type: 2 Auto: true Setting: ac: 572 max_hp: 1850000 accuracy: 330 slow_mitigation: 75 atk: 310 str: 342 sta: 342 dex: 342 agi: 342 int: 342 wis: 342 cha: 342 mr: 150 cr: 150 fr: 150 pr: 80 dr: 150 cr: 150 pr: 80 min_hit: 1024 max_hit: 3816 hp_regen: 1500 attack_delay: 13 spell_scale: 100 heal_scale: 100 special_abilities: 1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1
[NPC Scaling] (an ancient necromantic shade) level: 80 type: 2 Auto: true Setting: ac: 608 max_hp: 2100000 accuracy: 380 slow_mitigation: 85 atk: 360 str: 362 sta: 362 dex: 362 agi: 362 int: 362 wis: 362 cha: 362 mr: 160 cr: 160 fr: 160 pr: 100 dr: 160 cr: 160 pr: 100 min_hit: 490 max_hit: 1905 hp_regen: 2000 attack_delay: 13 spell_scale: 100 heal_scale: 100 special_abilities: 1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1
[NPC Scaling] (a shrouded minion) level: 75 type: 2 Auto: true Setting: ac: 572 max_hp: 1850000 accuracy: 330 slow_mitigation: 75 atk: 310 str: 342 sta: 342 dex: 342 agi: 342 int: 342 wis: 342 cha: 342 mr: 150 cr: 150 fr: 150 pr: 80 dr: 150 cr: 150 pr: 80 min_hit: 1024 max_hit: 3816 hp_regen: 1500 attack_delay: 13 spell_scale: 100 heal_scale: 100 special_abilities: 1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1
[NPC Scaling] (a shrouded minion) level: 75 type: 2 Auto: true Setting: ac: 572 max_hp: 1850000 accuracy: 330 slow_mitigation: 75 atk: 310 str: 342 sta: 342 dex: 342 agi: 342 int: 342 wis: 342 cha: 342 mr: 150 cr: 150 fr: 150 pr: 80 dr: 150 cr: 150 pr: 80 min_hit: 1024 max_hit: 3816 hp_regen: 1500 attack_delay: 13 spell_scale: 100 heal_scale: 100 special_abilities: 1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1
[NPC Scaling] (a tormented pugilist) level: 54 type: 0 Auto: true Setting: ac: 261 max_hp: 16800 accuracy: 62 slow_mitigation: 10 atk: 62 str: 206 sta: 206 dex: 206 agi: 206 int: 206 wis: 206 cha: 206 mr: 28 cr: 44 fr: 28 pr: 14 dr: 28 cr: 44 pr: 14 min_hit: 113 max_hit: 395 hp_regen: 54 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a tormented mercenary) level: 54 type: 0 Auto: true Setting: ac: 261 max_hp: 16800 accuracy: 62 slow_mitigation: 10 atk: 62 str: 206 sta: 206 dex: 206 agi: 206 int: 206 wis: 206 cha: 206 mr: 28 cr: 44 fr: 28 pr: 14 dr: 28 cr: 44 pr: 14 min_hit: 113 max_hit: 395 hp_regen: 54 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:
[NPC Scaling] (a mangled clairvoyant) level: 55 type: 0 Auto: true Setting: ac: 266 max_hp: 18500 accuracy: 65 slow_mitigation: 10 atk: 65 str: 210 sta: 210 dex: 210 agi: 210 int: 210 wis: 210 cha: 210 mr: 29 cr: 45 fr: 29 pr: 15 dr: 29 cr: 45 pr: 15 min_hit: 50 max_hit: 184 hp_regen: 55 attack_delay: 20 spell_scale: 100 heal_scale: 100 special_abilities:

DevTools

You can also see which attributes are applied to an NPC using the DevTools mob info display window (Targeting an NPC). Any stat that has been loaded from the global scale system has an asterisk next to it