Jump to content

ARE 9.1 (IWD2) Difficulty info


Recommended Posts

I was looking into this after remembering someone saying somewhere that area difficulty is, due to an engine bug, always set to 1. I found some other things too.

In the main structure:

0x54 looks to be the Actor Level override (or maybe adder) for Hard difficulty

0x55 looks to be the Actor Level override (or maybe adder) for Insane difficulty

0x56 is only updated at run-time and seems to always be set to 1. if this is indeed "Current Difficulty Level" or similar, then that might be the bug I was remembering.

 

In the Actor structure:

0x2F seems to be Required Difficulty, where 0 (all bits cleared) is the run-time value apparently meaning "Requirement Met" or something similar, while the other observed values apparently are: Bit 0 = Requires Easiest/Easy/Core Difficulty, Bit 1 = Requires Hard Difficulty, and Bit 2 = Requires Insane Difficulty

 

Observed Behaviors:

- Actors that do not have Bit 0 set will always be deleted from the ARE when it is loaded, regardless of Difficulty Setting in game options. I had to set Bit 0 (Actor 0x2F) on a goblin which was only enabled for Hardest and Insane in AR1000 in order for it to remain in the save game ARE on any difficulty setting I tested.

- As expected, changing difficulty while in-game does not restore deleted actors.

- When I say "deleted" I mean gone, as in the Actor entry is completely non-existent in the saved ARE.

- Nightmare Mode didn't seem to have any affect on these fields as far as I could see; behaviors remained the same.

What does this do for game play? Well, according to my tests in AR1000, the actor count drops from 55 (observed in BIFF archive via NI) to 34 in the saved ARE, meaning 21 enemies (a mix of melee and archer goblins) are always being removed, regardless of difficulty setting.

Edit: I also checked to be sure scripts weren't removing actors.

Edit 2: Giving this some thought, it looks like these flags in IWD2 were supposed to make it easier/faster to control which enemies were spawned based on the player's selected difficulty. In IWD this is managed by scripts (primarily EFDELA, EFDELDEF, EFDELEAS, EFDELHRD, EFDELINS, and ELDELNOR) which are attached to selected area actors.

Edited by Endurium
Clarification
Link to comment

I can confirm much of this — I was looking into it in 2013 apparently and we haven't changed our implementation since. I would not call those first fields level overrides though; or do you have some result that they actually change the levels of creatures?

Currently we just treat them as an oddly saved bitfield for matching against the actor difficulty margin at 0x2f. Seems to have worked quite fine — before, of course, all actors were there, so there were many too many, especially visible in the early orc maps. What we don't do is look at the game difficulty at all yet. I thought perhaps the levels had something to do with nightmare and HoF mode, but good to know that it's actually for the normal range. I also wonder why they used so many fields, when one in the actor structure would suffice.

Link to comment
1 hour ago, lynx said:

I can confirm much of this — I was looking into it in 2013 apparently and we haven't changed our implementation since. I would not call those first fields level overrides though; or do you have some result that they actually change the levels of creatures?

I had another look at my save, and tried another without Nightmare Mode enabled.

Nightmare Mode off - goblin appears unaffected by difficulty settings. Level 1, 4 HP - easy.

Nightmare Mode on - goblin scary. Level 13, CR 11, 90+ HP.

Maybe the devs, since they only had within a year to complete the game if I remember, left Nightmare Mode to cover extra difficulty, and disabled the other fields rather than fix/complete their functionality. Josh Sawyer commented about development in retrospect (he posted a youtube vid in 2014 about it).

As it is, if  you want to have max number of enemies to fight, you'll have to run a WeiDU script to ensure Bit 0 of Actor 0x2F is enabled for all actors. Imagine that + Nightmare Mode!

Link to comment

Alright, with coffee in hand I did some testing using an area script for trigger checking and trying all difficulty settings/Nightmare.

I set Area 0x54 to 31, Area 0x55 to 15, and Area 0x56 to 7 just to see if anything changed. Nothing did, and the game always sets 0x56 to 1 in the saves.

The trigger CheckAreaDiffLevel() always returned 1 regardless of what I tried.

The trigger Difficulty() returned a value of 1 (Easiest) through 5 (Insane) indicating which difficulty I selected, and updated as I changed it in-game.

Nightmare Mode is only visible in the game UI by checking the difficulty slider - the button will be solid light gray and the slider permanently set to Insane. To go along with this, both IsHeartOfFuryModeOn() and Difficulty(5,EQUAL) will be true.

The only time actor stats are modified is when Nightmare Mode is active. They get Level +12, HP according to level, Attacks/Round +2,  CR +10, Attributes (STR, DEX, etc.) +10 each, and the special attribute Mental Fortitude is enabled. This can be observed in the Actor records of a save game ARE. Apparently stats are recalculated on area load after actors lacking Bit 0 in Actor 0x2F are deleted

 

Edited by Endurium
typos
Link to comment

First, I made a mistake up there: nightmare mode is HoF mode (toggled in config.exe, saved to ini). I was hoping it would just swap out the creatures, either all being in the area already or doing it when looking them up. But for eg. 10gobd, there are no such beefed up versions shipped. Your confirmation here helps again, thanks. :)

CheckAreaDiffLevel is interesting. It's used for either harsher AI or scaled up scripted spawning, so it'd be odd if it had a static outcome (something for an iwd2 unfinished business mod). The fact that the same area scripts check for all three levels shows that the level was set by the engine. Did you read this thread? It says it's unreliable, but based on party level:

 

Link to comment

Thanks for that link; My mind was so stuck in the solo character mode from the last few months that I'd forgotten the game was designed to assume a party of six.

Further testing confirms average party level is compared against the requirements in ARE fields 0x54 and 0x55, then actors are (potentially) removed if either of both of those fields' requirements are not met. interestingly, this is done regardless of Difficulty, so scaling vs. party level is handled separately, apparently.

Level 1 party six characters (all level 1) - Area Level requirements not met so all actors requiring those levels were deleted.

Level 2 party six characters (all level 2) - Area Level 2 requirement met so only actors requiring Area Level 3 were deleted.

Level 3 party six characters (all level 3) - Area Level 2 & 3 requirements met so all actors spawned.

Level 30 party six characters - Area Level 2 & 3 requirements met so all actors spawned.

Level 1 solo character - Area Level 2 & 3 requirements not met so all actors requiring them were deleted.

Level 2 solo character - Area Level 2 requirement met so only actors requiring Area Level 3 were deleted.

Level 3 solo character - Area Level 2 & 3 requirements met so all actors spawned.

Level 30 solo character - Area Level 2 & 3 requirements met so all actors spawned.

I was shooting myself in the foot by setting the Area Level reqs to 31 and 15 for testing. Heh.

And, as Devsin confirmed 9 years ago, CheckAreaDiffLevel() does indeed only return true on a value of 1 regardless of the above. Thankfully there are only 78 instances of it in scripts (according to NI) and they mostly deal with minor things like drum count in goblin warrens, rest spawn probability, spell casting options, combat decision making, and other relatively minor adjustments.

Edited by Endurium
Link to comment

The "Current Difficulty Level" field is bugged. The engine populates this field with the average party level, which is found by calculating the average CLASSLEVELSUM stat value across the party. This value is updated whenever an area goes from being unloaded to loaded. However, on initial savegame load the engine doesn't yet have the party initialized - it ends up populating 1 as a fail safe in this instance.

Try loading a savegame, transitioning to another area, and then checking that new area's current difficulty field, (at offset 0x56). I've observed it holding the correct value.

Also, I've investigated CheckAreaDiffLevel()'s asm; here's some equivalent pseduocode:

if (trigger_int_1 == 1)
{
	return current_are_diff < area_diff_2;
}
else if (trigger_int_1 == 2)
{
	return current_are_diff >= area_diff_2 && current_are_diff < area_diff_3;
}
else if (trigger_int_1 == 3)
{
	return current_are_diff >= area_diff_3;
}

trigger_int_1 being the trigger parameter, area_diff_2 being the byte at 0x54, and area_diff_3 being the byte at 0x55.

The trigger seems to work as expected after an area transition has occurred, (because the current difficulty field finally gets populated).

Edited by Bubb
Link to comment

Thanks for the clarification  - it makes sense because all my testing was done by creating new parties/characters that spawned on the starting map, thus no populating of the current area level at that time, if I read correctly.

I checked the area INI files as well, and they use labels "area_diff_1" and "area_diff_2" for the two area level fields (pertaining to Goblin Warrens and Enchanted Forest), but these are always set to zero in the non-modded game. Of course, scripts can also control what is spawned by means of INI variables, the "old fashioned" way.

Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...