Jump to content

Can scripts just stop working for a particular save game?


mattrk

Recommended Posts

Hi all,

 

I have PRUFEI and Elementary Smelting working pretty well.

 

However, I have encountered a bug that has me stumped, but that I need to fix rapidly because people are using the mod -- thus my (grovelling) request for help.

 

For one of my saved games the main PRUFEI script seems to have stopped running. For my other character, the script works fine. I'm a bit stumped as to why this is. I am also worried that another user, ninjaNoe, may have the same problem.

 

So, I have three related questions:

1) Can scripts just stop working for a particular save game?

2) If I update the script, will it update the script being run for the saved games or do they keep a copy of the earlier script?

3) Is it possible to 'reboot' stopped scripts?

 

The script itself is here:

 

 

 

Scriptname PRUFIScript Extends Quest

; Both 'mrpwn' and 'IsharaMeradin' have played major parts in the construction of this script.
; The script was integrated/modified by quixotic-cynic (quixoticynic on Nexusmods)

; 'mrpwn' (on Nexusmods) constructed the initial script.
; 'IsharaMeradin' (on Nexusmods) designed an event that blocked access to the smelter whilst the UpdateFavorites() function was running. 
; 'IsharaMeradin' fixed an annoying bug with the addition of an 'If kForm' check in the original UpdateFavorites().
; 'mrpwn' pointed out that my modified script neglected game pad users.
; 'mrpwn' suggested a resource-saving modification to OnCrosshairRefChange().
; 'quixoticynic' provided a somewhat more efficient (but more ugly) UpdateFavorites().
; 'IsharaMeradin' solved a problem with OnKeyDown() by registering a key check within OnInit() and then checking if the UI is open when the key is pressed.
; The idea for the isEquippable()/isEquippableAndFav() functions came from http://forums.nexusmods.com/index.php?/topic/1115396-mod-script-issue-requesting-diagonstic-help/
; 'mrpwn' suggested using perks instead of blocking activation of the smelter (this feature was implemented by quixoticynic)

Actor Property PlayerRef Auto
ObjectReference Property prufeiChest Auto ;Points at the container in the isolated cell
Perk Property PRUFEICrafting Auto

Bool bUpdateFavorites

Event OnInit()
	PlayerRef.AddPerk(PRUFEICrafting)
	RegisterForMenu("InventoryMenu")
	;RegisterforCrosshairRef()
	RegisterForKey(Input.GetMappedKey("Toggle POV")) ;The DX Scan Code for 'F'
	RegisterForKey(Input.GetMappedKey("Jump")) ;Y button on X-Box 360 Controller
	Utility.Wait(1)
	UpdateFavorites()
EndEvent

Event OnKeyDown(Int aiKey)
	If UI.IsMenuOpen("InventoryMenu")
		Debug.Notification("Key or button pressed.")
		bUpdateFavorites = True
		PlayerRef.RemovePerk(PRUFEICrafting)
	EndIf
EndEvent

Event OnMenuClose(String asMenuName)
	If(bUpdateFavorites)
		UpdateFavorites()
	EndIf
EndEvent 

Function UpdateFavorites()
	If (PlayerRef.GetNumItems() < 36)
		UpdateFavoritesFine()
	Else
		UpdateFavoritesCoarse()
	EndIf
	Debug.Notification("Updated favorites.")
	PlayerRef.AddPerk(PRUFEICrafting)
EndFunction

Function UpdateFavoritesFine()
	Int iSize = PlayerRef.GetNumItems()
	While(iSize >= 0)
		Form kForm = PlayerRef.GetNthForm(iSize)
		If isEquippable(kForm)
			Int iCount = prufeiChest.GetItemCount(kForm)
			Bool bFavorited = Game.IsObjectFavorited(kForm)
			If((bFavorited) && (iCount == 0))
				prufeiChest.AddItem(kForm)
			ElseIf((!bFavorited) && (iCount > 0))
				prufeiChest.RemoveItem(kForm, iCount)
			EndIf
		EndIf
		iSize -= 1
	EndWhile
	bUpdateFavorites = False
EndFunction

Bool Function isEquippable(Form kForm)
	Return ((kForm as Armor) || (kForm as Weapon) || (kForm as Ammo) || (kForm as Ingredient) || (kForm as Potion) || (kForm as Scroll))
EndFunction

Function UpdateFavoritesCoarse()
	prufeiChest.RemoveAllItems()
	Int iSize = PlayerRef.GetNumItems()
	While(iSize >= 0)
		Form kForm = PlayerRef.GetNthForm(iSize)
		If isEquippableAndFav(kForm)
			prufeiChest.AddItem(kForm)
		EndIf
		iSize -= 1
	EndWhile
	bUpdateFavorites = False
EndFunction

Bool Function isEquippableAndFav(Form kForm)
	Return (((kForm as Armor) || (kForm as Weapon) || (kForm as Ammo) || (kForm as Ingredient) || (kForm as Potion) || (kForm as Scroll)) && Game.IsObjectFavorited(kForm))
EndFunction

 

 

 

The script will allow smelter recipes if the item is not equipped, is not a favorite (i.e. is in the prufeiChest), there is at least one of the items to smelt, and the player has the PRUFEICrafting perk or if there are 2+ items of that particular item type in the player inventory. This requires 8 conditional rules:

 

 

 

      PL    GetItemCount    Armor:'ArmorDwarvenBoots'    >     1.00    OR
      PL    GetItemCount    Armor:'ArmorDwarvenBoots'    >     0.00    AND
      PL    GetItemCount    Armor:'ArmorDwarvenBoots'    >     1.00    OR
      R     GetItemCount    Armor:'ArmorDwarvenBoots'    ==    0.00    AND
      PL    GetItemCount    Armor:'ArmorDwarvenBoots'    >     1.00    OR
      PL    GetEquipped     Armor:'ArmorDwarvenBoots'    ==    0.00    AND
      PL    GetItemCount    Armor:'ArmorDwarvenBoots'    >     1.00    OR
      PL    HasPerk         Perk: 'PRUFEICrafter'        ==    1.00    AND

 

 

 

Any help would be much appreciated. I did make clear that the files were a beta version, but I am worried about users -- whilst I tested a lot (for every recipe, multiple times) I had no idea such 'long run' bugs were possible.

 

Edit: I should probably mention that I have debugging enabled in my skyrim.ini file and I'm not getting any errors showing up in the log files.

 

Thanks & regards, --QC

Link to comment
Share on other sites

1. Yes. I have had totally unreproducible bugs occur with mods where a script appears to have simply stopped for no reason, despite the mod not being updated or edited in any way. Then it never happened again on any other game. I have no idea what causes it but I have heard that aliases can be spontaneously emptied and cause a script to stop working.

 

2. I don't know with 100% certainty but I believe the answer is that the script is updated. I believe this because one suggested workaround for removing vanilla scripts is to simply add an empty copy of the script to your mod. The game will then check the empty script and nothing will happen. Note that the deleted properties will still be retained by the game and may cause crashes to desktop.

 

3. I don't know. When I had my issue I just started a new game.

Edited by lofgren
Link to comment
Share on other sites

Thank you for the fast reply, Iofgren. I'm not sure if the fact that the bug may be a freak occurence is good or bad (probably bad, because addressing it is harder). Still, I appreciate knowing (I don't want to be the person placed in a circular room who is told there is food in the corner).

 

Knowing the answer to 2 with some degree of certainty is also useful.

 

Thanks again, --QC

Link to comment
Share on other sites

You do have a fragile script. If the time isn't given for it to process fully before going on to the next step you can accidentally break it. Should the player pull an item out of their inventory during the update process, it will break. I had this happen myself. I was cycling the player inventory to transfer specific objects. However, when the object was removed the count was thrown off and that section of script seemed to cease functioning.

 

I suggest you inform users not to tamper with the inventory while the update process is taking place.

 

#2

If the script is one that does not constantly run, it will first try to finish the version stored in the save. Then the next time it is called it will use the new version.

If the script is one that does constantly run, it will first try to finish the event/function it is on based on what is stored in the save. Any new calls to the function/event should use the new version.

 

#3

There is a console command to force the game to reload a specified script. That may cause a stalled script to restart. ReloadScript

Link to comment
Share on other sites

Hello IsharaMeradin,

 

Thank you for the reply (once again). I'll inform users and also try to work out how to block the inventory when the favorites script is updating... or something like that.

 

Thank you also for pointing out the existence of ReloadScript -- could be very useful.

 

I should really be doing other things now, but I've been trying to deliberately break a saved game by altering inventory contents whilst the script is updating favorites. I haven't managed to do it yet. I think GetNthForm() will return 'None' if a player removes an inventory item, but this is caught by the proceeding "If isEquippable(kForm)" line, thereby not causing serious issues. I will have to investigate more later.

 

Best regards, --QC

Edited by quixoticynic
Link to comment
Share on other sites

Hello all,

 

Sadly, using ReloadScript did not manage to re-boot the script.

 

I have found that removing the mod, making a clean save, and re-enabling the mod fixes the problem.

 

However, I have been reading Save File Notes (Papyrus) and Old Versions of Mods Conflicting With Newer Ones and am worried that doing the above might decrease the health of the savegames in question &/or increase overhead + bugs. Is doing this OK or is it inadvisable?

 

Thanks & regards, --QC

Link to comment
Share on other sites

It depends on the mod. If the mod does a lot of stuff and the user has already participated in most of the content there is probably a greater risk of harm in that scenario. If what the mod does is minor and doesn't rely on an explicit load order, chances are you can get away with it without any harm. Only way to really know is to play the game under such a situation and see what happens. Still, not all game setups are the same. Some are more fragile than others, who can say what will really happen.

Link to comment
Share on other sites

OK, thanks. I realise that if you have physical items in your mod, or similar, removing the mod would be a big problem. It seems it works OK for PRUFEI. I'll test a bit more.

 

Edit: @IsharaMeradin -- OK, I see what you mean about the script being fragile, since an item can be being added and removed to the container at the same time by two different calls to UpdateFavorites().

 

Regards,

--QC

Link to comment
Share on other sites

  • Recently Browsing   0 members

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