Jump to content

Custom Quest Variables Won't Save


neocatzeo

Recommended Posts

I'm having a problem with a custom quest script I wrote for a custom quest. The quest variables for this quest appear to be reset to 0 when loading the game. If I save and quick load they dont appear to reset to 0.

 

This is a quest that controlls a group of monsters that will spawn in Tamriel at a specific location and traverse the game world to the player when the player is in the open world. The MyStage variable controls their overall behavior whether it be resetting the creatures, moving them to a temporary cell for storage, pausing them, or activating them.

 

The problem is when I freshly load the game this scripts MyStage variable never retains it's old value. It's reset to 0 and these monsters hunting the player always get reset as a result.

scn aaaHuntMobQuest01Script

Float fQuestDelayTime
int MyStage

Begin GameMode

	Set fQuestDelayTime to 5

        ;MyState
	;0 - move everything to testzone and refresh and turn off finding set to 10
	;10 - deactivated and ready
	;20 - Activation - move to world marker set to 30
	;30 - finding active
	;40 - finding paused

	;Disabling State
	If (MyStage == 0)
		;Move group to test zone
		aaaHuntMobMother.MoveTo aaaSinHuntTestMarker
		aaaHuntMobOgre1.MoveTo aaaSinHuntTestMarker
		aaaHuntMobOgre2.MoveTo aaaSinHuntTestMarker
		aaaHuntMobOgre3.MoveTo aaaSinHuntTestMarker
		aaaHuntMobOgre4.MoveTo aaaSinHuntTestMarker
		;disable any combat
		aaaHuntMobMother.StopCombat
		aaaHuntMobOgre1.StopCombat
		aaaHuntMobOgre2.StopCombat
		aaaHuntMobOgre3.StopCombat
		aaaHuntMobOgre4.StopCombat
		Set MyStage to 10
		SetStage aaaHuntMobQuest 10
	EndIf

	;Activating State
	If (MyStage == 20)
		;heal everyone - reset them
		aaaHuntMobMother.ResurrectActor 1
		aaaHuntMobOgre1.ResurrectActor 1
		aaaHuntMobOgre2.ResurrectActor 1
		aaaHuntMobOgre3.ResurrectActor 1
		aaaHuntMobOgre4.ResurrectActor 1
		aaaHuntMobMother.Enable
		aaaHuntMobOgre1.Enable
		aaaHuntMobOgre2.Enable
		aaaHuntMobOgre3.Enable
		aaaHuntMobOgre4.Enable
		;Move group to world marker
		aaaHuntMobMother.MoveTo MS12PalePassRuinsMarker
		aaaHuntMobOgre1.MoveTo MS12PalePassRuinsMarker
		aaaHuntMobOgre2.MoveTo MS12PalePassRuinsMarker
		aaaHuntMobOgre3.MoveTo MS12PalePassRuinsMarker
		aaaHuntMobOgre4.MoveTo MS12PalePassRuinsMarker
		;disable any combat
		aaaHuntMobMother.StopCombat
		aaaHuntMobOgre1.StopCombat
		aaaHuntMobOgre2.StopCombat
		aaaHuntMobOgre3.StopCombat
		aaaHuntMobOgre4.StopCombat
		Set MyStage to 30
		SetStage aaaHuntMobQuest 30
        EndIf

	;Pause Mob Hunting if player leaves the outdoor world.
	If (MyStage == 30)
		If ( Player.GetInWorldspace Tamriel == 0 )
			Set MyStage to 40
			SetStage aaaHuntMobQuest 40
		EndIf
	EndIf

	;Unpause Mob Hunting if player enters tamriel world space.
	If (MyStage == 40)
		If ( Player.GetInWorldspace Tamriel == 1 )
			Set MyStage to 30
			SetStage aaaHuntMobQuest 30
		EndIf
	EndIf

End
;<CSEBlock>
;<CSECaretPos> 138 </CSECaretPos>
;</CSEBlock>

I don;t know what I need to do. Maybe offload the quest variables to global variables? Maybe there's something I missed?

Edited by neocatzeo
Link to comment
Share on other sites

Try changing "int" to "short", as I never heard about "int" in Oblivion, but only "short", "long" and "float".

If "int" compile, then it's either a discarded/unsupported type recognized but poorly implemented, or a fully functioning type that do exactly what it need to do: reset itself when game is closed.

 

Or use "Edit -> Find text" in the CS menu and search for "MyStage".

- Maybe another script or quest could reset that variable.

- Maybe an object has a FormID like that variable, so the compiler mess up everything.

Edited by forli
Link to comment
Share on other sites

Try changing "int" to "short", as I never heard about "int" in Oblivion, but only "short", "long" and "float".

If "int" compile, then it's either a discarded/unsupported type recognized but poorly implemented, or a fully functioning type that do exactly what it need to do: reset itself when game is closed.

 

Or use "Edit -> Find text" in the CS menu and search for "MyStage".

- Maybe another script or quest could reset that variable.

- Maybe an object has a FormID like that variable, so the compiler mess up everything.

Thanks for the reply.

 

I changed "int" to "short" as you suggested. It did work for this script, but didn't fix the problem for other quest scripts I have. The Finder didnt find anything other than where I used "MyStage".

 

In other quest scripts where the problem remains, quest variables will retain their values if I save and then reload. If I return to menu or restart the game their quest variables are zeroed.

 

For Example, one quest script has "Day" as a variable that stores gamedayspassed plus a few days. It reads 82 in game. I save. I reload. "Day" is still 82. I reload from Main Menu. "Day" is now 0. Nowhere is it ever set to 0. And this is a quest script. So none of this items re-equipping / resetting scripts stuff happening. I tried changing "Day" to "oDay" to get a unique variable nope no effect. Changed "Day" to short which solved the problem for the other script I posted, nope no effect. Didn't solve the problem.

Edited by neocatzeo
Link to comment
Share on other sites

No all of my quests are setup with "Start Game Enabled" and "Allow repeated stages" checked. There is no code to manually start or stop them.

 

I originally wrote everything thinking I could control things with Quest Stages. Big mistake. "Allow repeated stages" is a lie. Only the highest ever attained stage is reported and it NEVER resets. Through all of this the actual are persistent and never reset. So since these stages need to go up and down to control things, "MyStage" variable was rewritten in to handle this functionality since actual quest stages don't ever go down.

 

The big problem with this has been that variables aren't being saved. Short is now used on all of the variables. Only in some cases did switching miraculously cause the cariable to retain its value after completely reloading.

 

The fact the game has different behaviour from reloading "ingame" from reloading "from main menu" is really sketchy. At lot of this seems really inconsistent.

Edited by neocatzeo
Link to comment
Share on other sites

Allow repeatable stages simply allow the stages to fire again (their "result" script can run again)

If you read the CSWiki:

GetStage always return the highest stage set. If you do "SetStage 40", GetStage return 40. Then you do "SetStage 30". GetStage still return 40, as it's the highest one.

GetStageDone instead return 1 if the stage ever fired, 0 otherwise.

There's no way to detect the last "SetStage X" used, unless you use a variable like you do.

 

As for your script: the script is never supposed to reset the quest variables, unless you use "ResetAllVariables" (not advised) or use "StartQuest" when the given quest is already running.

Do you already tested this mod, then saved with it? My guess is that you added/removed/switched some variables, but your savegame still remember the old ones (it happens rarely) and try to load "MyStage" as (example) a ref variable, but figure out it's not right then leave it at 0.

Don't worry, you won't lose your save. Just disable the esp. load your savegame, SAVE ON A NEW SLOT, close the game, enable the esp and test if the problem still happens.

 

Another test is: BACKUP YOUR MOD. Now, take your quests (the bugged ones), remove the scripts, create new quests and assign them the scripts. Test.

 

 

EDIT: Reloading while in game is not the best idea, as the game doesn't correctly reload some internal variables, but it correctly reload scripts (your problem is not caused by this). Exit to the main menu and load from there is the correct way.

Edited by forli
Link to comment
Share on other sites

Glad it works! It's a problem which happens sometimes:

 

The game doesn't remember the variable names, just the order (the first variable is a short, the second one is a ref, the third one is a string, etc ... )

If you save your game with that script, then alter the variables and (example) switch the ref and the string variables, the game won't detect the change and when it load the values from the savegame into the variable it fails (because a ref can't hold a string and vice versa), so it start throwing errors or causing problems like this one.

Link to comment
Share on other sites

Yes the issue very much seemed to be some kind of glitch. My impression is that the savegame creates a profile or a structure for the quest variables when the quest is started. Then even though the script can change, it doesn't update the data structure to store new variables or changes in data types.

 

I was using INT as a data type since a lot of custom scripts I looked over appear to use it. I wasn't aware it was a non standard data type. I have OBSE installed and have been working with mods that make use of it. So I am aware I probably assume some functionality that isn't completely supported.

 

This particular script is part of a larger custom mod I made which tracks damage on a magical sword and the game will spawn mobs of creatures into the game world to hunt down the player depending on the damage level. There's a few other versions of this script running which handle different mobs. And there's a separate master quest+script controlling these scripts, since these scripts just manage the mobs depending on their "MyState". I reverse engineered part of the "Break Undies" mod (most pointlessly pervy name ever) so that I can have visual damage on the weapon, track damage, and interface it with my custom scripts. (English programming + Japanese comments = nightmare)

 

This is just a thing to make my latest stab at this game a little more interesting. Anyway I didn't want to be that guy that doesn't provide a followup after getting help.

 

Thanks again.

Link to comment
Share on other sites

You're close. Take a script like this:

scn MyQuestScript

Short myInteger
Float myFloat1
Float myFloat2
Ref myReference
Array_Var myArray
...

You test your mod, the variables get some values, then you save the game.
The game save the data structure, but it doesn't do associations like this

myInteger -> 54
myFloat1 -> 2.61
myFloat2 -> 95.532
myReference -> SuperMario
...

Instead, it does something like this:

var#1 -> short, 54
var#2 -> float, 2.61
var#3 -> float 95.532
var#4 -> ref, SuperMario
...
  • If you simply rename a variable (rename "myShort" to "myShortValue") the game doesn't care, because in that place there's still a Short.
  • If you switch the lines "Float myFloat1" and "Float myFloat2", the game load fine, but SOMETIMES the variables value is switched (myFloat2 contains the values which was stored from myFloat1 and vice versa).
  • Instead, if you switch "Float myFloat2" with "Ref myRef", SOMETIMES, the variables get corrupted, because the data structure says the third variable must be a float, but it's now a ref, while the fourth variable must be a ref, but it's now a float. So it can't load the third and fourth variables, which remain "not initialized". For some reason, even if you save again, the game keep the old data structure and the problem "survive".
  • It seems that (again, SOMETIMES) adding or removing a variable force the game to recheck all variables and update the data structure, thus fixing the problem.

I heard in Skyrim is even worse, because the savegame remember the whole script, not only the variables. If you alter a single character in the script you need to use an external tool to delete or update the savegame with the updated version of the script, else it keep using the old one... if it's really true, then modding Skyrim makes you crazy!

Edited by forli
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...