jastey Posted April 26, 2022 Share Posted April 26, 2022 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 Quote Link to comment
jastey Posted April 28, 2022 Author Share Posted April 28, 2022 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. Quote Link to comment
jastey Posted April 28, 2022 Author Share Posted April 28, 2022 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? Quote Link to comment
jastey Posted April 28, 2022 Author Share Posted April 28, 2022 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 Quote Link to comment
Bubb Posted April 29, 2022 Share Posted April 29, 2022 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). Quote Link to comment
jastey Posted April 29, 2022 Author Share Posted April 29, 2022 @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. Quote Link to comment
Awachi Posted April 29, 2022 Share Posted April 29, 2022 I hope this gets resolved to Jastey's satisfaction, because I am using her mods to learn npc dialog interactions. Quote Link to comment
jastey Posted April 29, 2022 Author Share Posted April 29, 2022 I think it's the first time I encountered a problem, but it has so much potential to break things. @Awachi as long as you don't use my older mods, Ajantis especially is not good scripting style. Quote Link to comment
Graion Dilach Posted April 29, 2022 Share Posted April 29, 2022 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. Quote Link to comment
jastey Posted April 29, 2022 Author Share Posted April 29, 2022 @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. Quote Link to comment
Graion Dilach Posted April 29, 2022 Share Posted April 29, 2022 (edited) 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 April 29, 2022 by Graion Dilach Quote Link to comment
jastey Posted April 29, 2022 Author Share Posted April 29, 2022 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. Quote Link to comment
Recommended Posts
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.