ttiww Posted June 5 Posted June 5 Hello, I'm new to scripting, and I tried to create one with a function, but it doesn't work, or at least the variable doesn't. Here's how I did it: I created a new quest and from the Script tab, I created a new script. Then, in Miscellaneous --> Global, I created a new global with a value of 0 in short and not a constant. Then I added my global to my script's properties. Finally, still in the same quest, I created dialogs with an NPC that executes the function of my script. Here's my script: GlobalVariable Property Var_A Auto Function Start_T() Var_A.SetValueInt(1) Debug.notification(Var_A.GetValueInt()) EndFunction The message I receive in-game is always 0; the variable is never modified, even though my script is very simple. I've tried other methods, such as the GetValue command along with other commands in case there's just a problem with the Debug.Notification command, but nothing works. I've also tried modifying the variable via a script in one of the dialogs, and ironically, it works. However, despite this, the Start_T function doesn't modify the variable, and the debug command always displays 0. I could simply write the function in a script in one of the dialogs. However, for the sake of simplicity, there will be many dialogs to execute the function, and it will be much longer. I've tried to find solutions online, but nothing has been conclusive, and I admit I'm stuck. Something else: I wanted to know if it's possible to create formulas with variables, for example: Var_A = Var_B + Var_C * Var_D - 5 I could really use your help, if you don't mind.
IsharaMeradin Posted June 5 Posted June 5 Your function needs to be called in order to run. If the dialog is within the same quest and assuming that you gave your quest script the following name (myQuestScript): myQuestScript myQS = GetOwningQuest() as myQuestScript myQS.Start_T() What this does is creates a local "script type" variable (myQS) within the dialog fragment that is given the value of the parent quest cast into an attached script. The local variable can then be used to call any function of the script as well as access any properties on that script. And yes, you can create formulas with variables. Though you will want to utilize () to ensure correct calculations.
scorrp10 Posted June 5 Posted June 5 If the notification message is displayed, it means the function is being called. However, because of the way Papyrus engine operates, there may be a slight delay between calling SetValueInt and the global's value actually being updated. So when you make the GetValueInt() call, the update has not yet been applied. Try following: After Start_T is called, and you get the notification that global is still 0, open console and use command 'help Var_A' (assuming that is your Global's EditorID) to check if its value is still 0 or has, in fact, been updated by now. Or, try adding Utility.Wait(0.5) between SetValueInt call and printing the value in the function. In general, you should not treat a GlobalVariable property like a local variable. If you immediately want to use the updated value, it is best to do something like this: int var_a_value = Var_A.GetValueInt() var_a_value += 1 Var_A.SetValueInt(var_a_value) if var_a_value > something ; use var_a_value through the rest of function rather than Var_A.GetValueInt() ... About your other question regarding formulas - please clarify. If you simply want to have a line like that in your script in order to calculate Var_A, then sure, you can do that. However if you want to set up a kind of automated formula like in Excel, such that Var_A will get automatically updated if Var_B, Var_C or Var_D is changed, then I am afraid not.
ttiww Posted June 5 Author Posted June 5 Thank you for your replies. My function was already called for execution via a dialog. I inserted the Utility.Wait(0.5) command between the Var_A.SetValueInt(1) and Debug.notification(Var_A.GetValueInt()) commands, but the result is the same. The variable doesn't change, and the notification confirms it. So, I changed the way I handle the property by modifying it as scorprp10 recommended: int var_a_value = Var_A.GetValueInt() var_a_value += 1 Var_A.SetValueInt(var_a_value) However, the problem persists. If I modify the global variable beforehand with a dialog box like this: (GetOwningQuest() as _000_Ar_Main_Script_01).Start_T() Var_A.SetValueInt(5) Debug.notification(Var_A) And the script runs with the function: Function Start_T() Debug.notification(Var_A.GetValueInt()) int var_a_value = Var_A.GetValueInt() var_a_value += 1 Var_A.SetValueInt(var_a_value) Utility.Wait(0.5) Debug.notification(Var_A.GetValueInt()) Debug.notification(var_a_value) EndFunction Here's the result in the game: 5 0 0 1 Regarding the formulas for calculating variables between themselves, that was just to know if it was possible, thank you.
scorrp10 Posted June 5 Posted June 5 Ok, something there is extremely off. Are you saying that in the fragment attached to the dialogue, the script is: (GetOwningQuest() as _000_Ar_Main_Script_01).Start_T() Var_A.SetValueInt(5) Debug.notification(Var_A) Or those lines are actually in different order? You are saying that you 'modify it beforehand'? Even supposing that the fragment actually looks like this: Var_A.SetValueInt(5) Debug.notification(Var_A) (GetOwningQuest() as _000_Ar_Main_Script_01).Start_T() So you set the value, you print it out, it shows 5. But then, after you have JUST printed that global, and it showed 5, the first line in your function is to print it again, and it now shows 0? Are you SURE the property (in the quest script) is indeed filled? Do you have Papyrus logging enabled? Cause here, I just did a little experiment - I added a script fragment to a quest stage. Relevant part of the script looks like this: Scriptname QF_dxSigrid_0C05BA6A Extends Quest Hidden GlobalVariable Property VAR_A Auto Function Fragment_0() Debug.Trace("Sigrid quest stage 20") Debug.Trace("VAR_A value is " + VAR_A.GetValueInt()) VAR_A.SetValueInt(5) Debug.Trace("VAR_A new value is " + VAR_A.GetValueInt()) EndFunction And in game, I just use 'setstage dxSigrid 20' to force this stage. Caveat: VAR_A property is not filled in the Script properties: The output I get [06/05/2025 - 01:42:28PM] Sigrid quest stage 20 [06/05/2025 - 01:42:28PM] Error: Cannot call GetValueInt() on a None object, aborting function call stack: [dxSigrid (2D05BA6A)].QF_dxSigrid_0C05BA6A.Fragment_0() - "QF_dxSigrid_0C05BA6A.psc" Line 30 [06/05/2025 - 01:42:28PM] Warning: Assigning None to a non-object variable named "::temp0" stack: [dxSigrid (2D05BA6A)].QF_dxSigrid_0C05BA6A.Fragment_0() - "QF_dxSigrid_0C05BA6A.psc" Line 30 [06/05/2025 - 01:42:28PM] VAR_A value is 0 [06/05/2025 - 01:42:28PM] Error: Cannot call SetValueInt() on a None object, aborting function call stack: [dxSigrid (2D05BA6A)].QF_dxSigrid_0C05BA6A.Fragment_0() - "QF_dxSigrid_0C05BA6A.psc" Line 32 [06/05/2025 - 01:42:28PM] Error: Cannot call GetValueInt() on a None object, aborting function call stack: [dxSigrid (2D05BA6A)].QF_dxSigrid_0C05BA6A.Fragment_0() - "QF_dxSigrid_0C05BA6A.psc" Line 34 [06/05/2025 - 01:42:28PM] Warning: Assigning None to a non-object variable named "::temp0" stack: [dxSigrid (2D05BA6A)].QF_dxSigrid_0C05BA6A.Fragment_0() - "QF_dxSigrid_0C05BA6A.psc" Line 34 [06/05/2025 - 01:42:28PM] VAR_A new value is 0 The important part to notice is that even though 'GetValueInt' on an unfilled property fails, it still returns a 0 for Debug.Trace to print - just like it happens in your case. Then I went back, and actually filled the property. Now, I get: [06/05/2025 - 01:57:56PM] Sigrid quest stage 20 [06/05/2025 - 01:57:56PM] VAR_A value is 0 [06/05/2025 - 01:57:56PM] VAR_A new value is 5 As expected.
Qvorvm Posted June 5 Posted June 5 Don't forget to fill your properties! That's in the CK, open your quest, "scripts" tab, double click on your script file, then click "Autofill". You need to do it for your quest script, and you dialogue TIF script, and then start a new game.
PeterMartyr Posted June 6 Posted June 6 (edited) On 6/5/2025 at 4:47 PM, ttiww said: Regarding the formulas for calculating variables between themselves, that was just to know if it was possible, thank you. Expand Yes it is LOL this a test for your logic, your allowed to use three line code to solve to solve it, it is called swap the variables the game is limited to 2 time 32 bits of memory allocation, of value of two ints in the memory, no extra int C int A = 10 int B = 20 debug.notification("A = " + A) debug.notification("B = " + B) ; 1 ; 2 ; 3 debug.notification("A = " + A) debug.notification("B = " + B) that not all the random tests in the creation kit will teach you to think like a programmer.. BTW google it or using an AI is admitting defeat, so it also a test of character I have seen experienced dev's get it wrong, there is no shame in not solving it My point is a Skyrim Global Variable is just a data point, practice with that problem to develop your programming skills and what is possible on a PC EDIT the beauty of this, is you can just do on paper.... then test solution once. DO NOT USE PAPYRUS, AND LAUNCHING THE GAME FOR EACH TEST!! Your not thinking like a programmer out of the gate, If your really good it is just a thought experiment. Edited June 6 by PeterMartyr extra detail
ttiww Posted June 6 Author Posted June 6 Okay, so I checked the Papyrus.0.log file, and I get the same result as scorprp10 when he didn't fill in his property. The problem seems to be with the property, but it's already filled in. I've tried enabling and disabling my property, creating a new global variable, or even creating a new global, but the result is always the same. Is it possible that a quest or something else can't recognize a property? Another thing now that I think about it: in the script, at one point, I deleted the global variable, the line GlobalVariable Property Var_A Auto, I saved it, and then later I rewrote that same line again. Could this be related? On 6/6/2025 at 3:31 AM, PeterMartyr said: EDIT the beauty of this, is you can just do on paper.... then test solution once. DO NOT USE PAPYRUS, AND LAUNCHING THE GAME FOR EACH TEST!! Your not thinking like a programmer out of the gate, If your really good it is just a thought experiment. Expand Interesting, thank you. I'll take note; it will be very useful for me in the future.
Qvorvm Posted June 6 Posted June 6 You need to start a new game! Properties get baked into the save file (well, there are various cases where they do and others where they don't, but properties on quests do get baked in). If you don't want to start a new game to test this, then rename the property and adjust your code accordingly. But really, starting a new game is the proper way to test this.
scorrp10 Posted June 6 Posted June 6 On 6/6/2025 at 8:12 AM, ttiww said: Okay, so I checked the Papyrus.0.log file, and I get the same result as scorprp10 when he didn't fill in his property. The problem seems to be with the property, but it's already filled in. I've tried enabling and disabling my property, creating a new global variable, or even creating a new global, but the result is always the same. Is it possible that a quest or something else can't recognize a property? Another thing now that I think about it: in the script, at one point, I deleted the global variable, the line GlobalVariable Property Var_A Auto, I saved it, and then later I rewrote that same line again. Could this be related? Expand If you had a game in progress where that quest was already running, so the script instance was already in memory/save then yes, adding a new property to it would be problematic.
Recommended Posts