Jump to content

Differences in Setting of Variables in Dialogues classic/EE (title edited)


jastey

Recommended Posts

Turns out this is just a blocked action queue of the interjecting NPC in question, not a difference between the game engines. It works in both cases if the NPC is not walking to a destination when the dialogue triggers.

As far as my test case goes, this is a difference in how the engines treat the action queue. I could not reproduce this error in th classic engine, regardless whether the interjecting NPC is still walking when the dialogue is triggered or not.

In the EE, the variable is not set for the end of the dialogue if the interjecting NPC was still walking.

---

I have a basic dialogue scripted with CHAINs and stuff. In the classic engine, this works. In the EE, the path where it says "leads to a NVROL" leads to an NVROL error. Does anyone know why? I don't even see a difference in the two instances. In both cases, the variable gets set in a transition back to the original speaker who then says two more lines before the variable gets checked the first time. It's even the same states! But the bolded line leads to an NVROL error in BG:SoD, reproducibly. After the dialogue (after the error), the variable is set if I check for it.

I have a faint recall that in the EE there exists a flag so that variables get evaluated instantly. Would this help me here and how would I do that?

Spoiler

CHAIN
IF WEIGHT #-1
~Global("C#Brando_SoD_QuestBookQuarrel","GLOBAL",1)~ THEN bdrayphu book_quarrel
~[Rayphus]This is Rayphus' first line. Yadda.~
END
IF ~OR(2) InParty("C#Brandock") Global("C#BrandockJoined","GLOBAL",2)
InMyArea("C#Brandock") !StateCheck("C#Brandock",CD_STATE_NOTVALID)~ THEN EXTERN c#brandj book_quarrel_brando

APPEND c#brandj

IF ~~ THEN book_quarrel_brando
SAY ~Brandock says a line.~
++ ~This line ends the first dialogue so PC can talk to Rayphus.~ DO ~SetGlobal("C#Brando_SoD_QuestBookQuarrel","GLOBAL",3)~ EXIT
++ ~This answer sets the variable but leads to a NVROL.~ DO ~SetGlobal("C#Brando_SoD_TestTest","GLOBAL",4)~ EXTERN bdrayphu book_quarrel_06  
END

IF ~~ THEN book_quarrel_brando_04
SAY ~Blabla~
++ ~This line sets the variable and works.~ DO ~SetGlobal("C#Brando_SoD_TestTest","GLOBAL",4)~ EXTERN bdrayphu book_quarrel_06
END
END //APPEND


APPEND bdrayphu

IF WEIGHT #-1
~Global("C#Brando_SoD_QuestBookQuarrel","GLOBAL",3) Global("C#Brando_BookInterrogation","LOCALS",0)~ THEN book_quarrel_03
SAY ~Yadda?~
++ ~Brandock says a line.~ EXTERN c#brandj book_quarrel_brando_04
END
END //APPEND bdrayphu


APPEND bdrayphu
IF ~~ THEN book_quarrel_06
SAY ~Also one line blabla.~
IF ~~ THEN + book_quarrel_08
END
END //APPEND

BEGIN c#brsqu1

CHAIN
IF ~~ THEN bdrayphu book_quarrel_08
~Another line blabla.~
== c#brsqu1 IF ~Global("C#Brando_SoD_TestTest","GLOBAL",4)~ THEN ~This line should always run.~ //here is the NVROL error
END
IF ~Global("C#Brando_SoD_TestTest","GLOBAL",4)~ THEN DO ~SetGlobal("C#Brando_SoD_QuestBookQuarrel","GLOBAL",6)~ EXIT

 

Link to comment

I expanded my testcase and tried to trigger this dialogue while the interjecting NPC is still walking for classic engine, too. The line in question always run.

For the EE, the NVLOR error occurres if the action queue of the interjecting NPC is still full with his "walk to" command, i.e. if the dialogue starts while the NPC is still walking.

Has anyone insight into this difference in processing the action queue? Or is the EEs not interrupting NPCs' actions when a dialogue starts or whatever?

And can someone give me the flag for instant execution of variable setting and how it is used?

Link to comment

Anyone who wants to replicate this:

Install the attached version of my Brandock mod to BGII:EE or BGII.

Load the appropriate attached save for the game.

Walk with the PC and Brandock alongside the group of commoners who are in sight. Make sure Brandock is still walking while the dialogue gets initiated.

Chose the reply option "This answer sets the variable but leads to a NVROL." when Brandock has his first interjection.

For BG2, the dialogue ends with a line from one of the commoners saying "This line should always run.".

For BGII:EE, this line doesn't show but the dialogue bugs out with an NVLOR.

The dialogue in question is in c#brandock/dialogue/brandock_sod_quest_test.d

000000001-NVLOR_Test.zip 000000035-NVLOR_Test_BGIIEE.zip

Brandock_NVLOR_Testcase_220428.zip

Link to comment

Seems like all the engines handle dialog slightly differently...

But yes, when an NPC interjects in oBG2 the engine clears their action queue. The EE doesn't do this.

6 hours ago, jastey said:

And can someone give me the flag for instant execution of variable setting and how it is used?

Response flag 0x200 executes queued instant actions, though non-instant actions still block evaluation.

Setting flag 0x400 on the "This answer sets the variable but leads to a NVROL." response fixes things. It clears the action queue, which almost mimics oBG2's behavior, (clearing on interjection vs on reply).

Link to comment

@Bubb thank you! Adding the FLAGS 0x400 did the trick indeed.

So this is a well known difference in the engines, intended by the devs?

It makes me very nervous seeing how mod added NPC interjections work: they move the transactions to the NPC's interjection line. This has a huge potential that original game dialogues break if mods interject into them. The only reason we do not see this often is because most of the times for original dialogues, they are not initiated while the group is still walking and variables are not checked inside the dialogue but only matter after it ended.

For all other cases, this behavior introduces bugs where the old engine works fine. This is Sch**ß, to say it frankly.

Link to comment

Call me blunt, but implicitly breaking the action queue sounds more risky to me, because the queue can have something (say, an action setting a local variable getting dropped) which can cause a bug. Banter interjections triggered during spellcasting comes to my mind as one of such edge cases because this sounds like that the interjector loses the spell being casted for no reason. Having to explicitly define that breaking the action queue is permitted for the action is IMO a good thing because that way you have a clearer knowledge what's going on and you don't end up with wacky side-effects because the break in the action queue ends up implicit and you have no control of it.

Link to comment

@Graion DilachI agree and maybe this was the devs' thinking. But: the old engine works that way so for compatibility's sake they couldn't just change this. It Is mere luck this doesn't lead to problems in original dialogues. There is just no good reason setting a variable by an interjecting NPC should lead to an NVORL inside a dialogue due to the NPC's queue still being busy executing actions they started before the dialogue started. Maybe I'm barking against the wrong tree but it breaks compatibility for some cases, that's a fact.

Also, this isn't mod friendly at all. It basically means that every I_C_T should also include a FLAGS 0x400 or the mod could break things - in the EE - which worked fine on classic. So basically we need to simulate the classic engine's behavior because the EE's changed it.

Link to comment

Not changing something because the "old engine works that way" is a dangerous and blind reasoning because you can cite that against any of the changes/bugfixes/whatnot. Explicitly defining implicit aspects of the engine is obviously part of Beamdog's modus operandii though and we already are aware that EE regressions can easily happen with the "moving targets" claim in the readmes. Additionally, this improves mod code quality via the explicit attributes (relying on undefined behaviour is bad).

If you ask me, the issue here isn't that this was changed but the fact that the behaviour isn't documented well (you can say Beamdog didn't documented this change properly but this is the first time I hear about oBG2 handling these as complete interrupts deleting the activity queue).

If I get it right, the I_C_T can still have the checks for the empty action queue as well and you can put additional checks to ensure your change.

Edited by Graion Dilach
Link to comment
30 minutes ago, Graion Dilach said:

If I get it right, the I_C_T can still have the checks for the empty action queue as well and you can put additional checks to ensure your change.

I'll be thrilled to do that for all my NPC and other mods for all I_C_Ts they contain. Not...

32 minutes ago, Graion Dilach said:

Not changing something because the "old engine works that way"

Well, changing behavior just because it seems a good idea while it can break things is dangerous as well imho.

All in all, I'd be grateful if we could stop discussing whether the changes were a good idea or not, because that's not the point; this thread is about how we'll best deal with it.

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...