Properties queried from other scripts occasionally fail to b

Post » Mon Nov 19, 2012 2:28 am

So, lately with Frostfall, I've been getting some bug reports that all read something like the following:

Hey, Chesko, love / hate your mod, I have a bug to report. Everything was hunky-dory for (10 - 50) hours of gameplay. Then, suddenly, I started losing all of my exposure points really fast and I don't know why. Can you help?

(background primer for those that might not play Frostfall; Exposure Points are my method for tracking player condition from exposure to the elements. The primary reason it goes down is from being in a cold place. Equipping warm clothing slows the rate of exposure down.)

So I did some digging and asked a user to run a debug command I had left in the script files. This debug command allows me to return the value of what Frostfall thinks their clothing "value" should be, which is the largest contributor to keeping exposure rates low. Lo and behold... the value was 0, even though the player was fully clothed. This value is obtained by reading another script's property that runs asynchronously to my primary script.

There are only two explanations for this that I can see:
  • The clothing variables in the Clothing Script suddenly and mysteriously reset themselves to 0. (Extremely unlikely, never seen anything like that happen before. Also, this script does not operate on an OnUpdate loop; it only runs when OnObjectEquipped() events fire. The times this happens for players is while running around, not equipping or unequipping stuff. Which leads me to believe that this isn't the problem.)
  • The main script attempted to read the clothing script and it failed to do so.
My question is: what could cause something like that to happen? I used properties in an attempt to cut down on the number of Globals I use, but now it would seem that I can't trust properties to work 100% of the time. There doesn't seem to be a catalyst for causing this to occur that I've found, it just seems to happen for some users suddenly and randomly, many hours into playing. I haven't been able to reproduce it myself, mainly because of how random it is and how long i'd have to play to (possibly, maybe) see it occur.

I went on a long development cycle of "Wow properties are great!", and now I'm having to go back and reanolyze all of those decisions. Any ideas?
User avatar
BrEezy Baby
 
Posts: 3478
Joined: Sun Mar 11, 2007 4:22 am

Post » Mon Nov 19, 2012 2:44 am

Are we talking about an Auto property here? In how many places in your code is the property set and what is its initial value?

Cipscis
User avatar
Harinder Ghag
 
Posts: 3405
Joined: Wed Jan 17, 2007 11:26 am

Post » Sun Nov 18, 2012 11:36 pm

Auto properties, yes.

float property fBody = 1.5 autofloat property fHands = 0.25 autofloat property fFeet = 0.25 autofloat property fHead = 0.5 autofloat property fAux = 0.0 auto

The values are only set as a result of a single function in the Clothing Script that runs once each time an object is equipped.

Spoiler
function WEAREquip(Form akBaseObject)		if akBaseObject.HasKeyword(ArmorCuirass) || akBaseObject.HasKeyword(ClothingBody)		;The player equipped a piece of body armor.		if _DE_Setting_Armor.GetValueInt() != 2			fBody = 1.5		else			bool bodyfound = false			if ArrayHasForm(_DE_ArmorBodyFull, akBaseObject as Armor)				fBody = 2.0				bodyfound = true				_DE_WearBodyFull.Show()			endif						if bodyfound == false				if ArrayHasForm(_DE_ArmorBodyLimited, akBaseObject as Armor)					fBody = 1.0					bodyfound = true					_DE_WearBodyLimited.Show()				endif			endif						if bodyfound == false				fBody = 1.5				_DE_WearBodyStandard.Show()			endif		endif		elseif akBaseObject.HasKeyword(ArmorGauntlets) || akBaseObject.HasKeyword(ClothingHands)		;conditions for hands		;The player equipped a piece of hand armor.		if _DE_Setting_Armor.GetValueInt() != 2			fHands = 0.25		else			bool handsfound = false			if ArrayHasForm(_DE_ArmorHandsFull, akBaseObject as Armor)				fHands = 0.25				handsfound = true				_DE_WearHandsFull.Show()			endif						if handsfound == false				if ArrayHasForm(_DE_ArmorHandsLimited, akBaseObject as Armor)					fHands = 0.05					handsfound = true					_DE_WearHandsLimited.Show()				endif			endif						if handsfound == false				fHands = 0.12				_DE_WearHandsStandard.Show()			endif		endif	elseif akBaseObject.HasKeyword(ArmorHelmet) || akBaseObject.HasKeyword(ClothingHead)		;conditions for head		;The player equipped a piece of head armor.		if _DE_Setting_Armor.GetValueInt() != 2			fHead = 0.50		else			bool headfound = false			if ArrayHasForm(_DE_ArmorHeadFull, akBaseObject as Armor)				fHead = 0.50				headfound = true				_DE_WearHeadFull.Show()			endif						if headfound == false				if ArrayHasForm(_DE_ArmorHeadLimited, akBaseObject as Armor)					fHead = 0.15					headfound = true					_DE_WearHeadLimited.Show()				endif			endif						if headfound == false				fHead = 0.35				_DE_WearHeadStandard.Show()			endif		endif	elseif akBaseObject.HasKeyword(ArmorBoots) || akBaseObject.HasKeyword(ClothingFeet)		;conditions for feet		;The player equipped a piece of feet armor.		if _DE_Setting_Armor.GetValueInt() != 2			fFeet = 0.25		else			int index = 0			bool Feetfound = false			if ArrayHasForm(_DE_ArmorFeetFull, akBaseObject as Armor)				fFeet = 0.25				Feetfound = true				_DE_WearFeetFull.Show()			endif						if Feetfound == false				if ArrayHasForm(_DE_ArmorFeetLimited, akBaseObject as Armor)					fFeet = 0.05					index = _DE_Armor_Feet_Limited.GetSize()	;Causes loop to break here					Feetfound = true					_DE_WearFeetLimited.Show()				endif			endif						if Feetfound == false				fFeet = 0.13				_DE_WearFeetStandard.Show()			endif		endif		elseif (akBaseObject.HasKeyword(ArmorMaterialLeather) || akBaseObject.HasKeyword(ArmorMaterialHide)) && akBaseObject.HasKeyword(VendorItemClothing) && akBaseObject.HasKeyword(ArmorClothing) && akBaseObject.HasKeyword(ClothingNecklace)		;Cloaks of Skyrim!		if !(Game.GetPlayer().HasSpell(_DE_CloakState_Spell))			Game.GetPlayer().AddSpell(_DE_CloakState_Spell, false)		endif		fAux = 0.1		_DE_WearCloak.Show()	endifendFunction
User avatar
aisha jamil
 
Posts: 3436
Joined: Sun Jul 02, 2006 11:54 am

Post » Mon Nov 19, 2012 10:55 am

I am using external property and cross script access without issue so far... I hope this will continue on that way...^^
how are you reading those properties from your main script?
User avatar
Charlotte Buckley
 
Posts: 3532
Joined: Fri Oct 27, 2006 11:29 am

Post » Mon Nov 19, 2012 8:12 am

Ok, maybe something else is going on. Here's the deal. I have this event that fires when items are unequipped in the Clothing Script:

Spoiler

Event OnObjectUnequipped(Form akBaseObject, ObjectReference akReference)	;notification("I just unequipped something!")	if akBaseObject as Armor		if akBaseObject.HasKeyword(ArmorCuirass) || akBaseObject.HasKeyword(ClothingBody)			;notification("Unequipped body armor!")			if bIsBeast == true				fBody = 3.0				;_DE_Werewolf_Transform.Show()			else				fBody = 0.1			endif		elseif akBaseObject.HasKeyword(ArmorGauntlets) || akBaseObject.HasKeyword(ClothingHands)			;notification("Unequipped gloves!")			fHands = 0.0		elseif akBaseObject.HasKeyword(ArmorHelmet) || akBaseObject.HasKeyword(ClothingHead)			;notification("Unequipped helmet!")			fHead = 0.0		elseif akBaseObject.HasKeyword(ArmorBoots) || akBaseObject.HasKeyword(ClothingFeet)			;notification("Unequipped boots!")			fFeet = 0.0		elseif (akBaseObject.HasKeyword(ArmorMaterialLeather) || akBaseObject.HasKeyword(ArmorMaterialHide)) && akBaseObject.HasKeyword(VendorItemClothing) && akBaseObject.HasKeyword(ArmorClothing) && akBaseObject.HasKeyword(ClothingNecklace)			;notification("Unequipped cloak!")			if Game.GetPlayer().HasSpell(_DE_CloakState_Spell)				Game.GetPlayer().RemoveSpell(_DE_CloakState_Spell)			endif			fAux = 0.0		endif	endifendEvent

Note the line, fBody = 0.1. That's the minimum value that the sum of the clothing properties can be. I put that in place because this number is used as a denominator and wanted to avoid divide-by-zero errors. I thought that this check was present in my primary script if the value was 0, but, it's not. And I see now from the user's output that he's getting back 0.1, meaning he had to have read this property correctly.

This is really perplexing because it means that this OnObjectUnequipped event fired at some point when it wasn't supposed to and set all of these values down to 0 (or 0.1). There's a problem, but it's not with the property. Anyhow, thanks everyone for being helpful :smile:
User avatar
Alyna
 
Posts: 3412
Joined: Wed Aug 30, 2006 4:54 am

Post » Mon Nov 19, 2012 11:41 am

...

This is really perplexing because it means that this OnObjectUnequipped event fired at some point when it wasn't supposed to and set all of these values down to 0 (or 0.1). There's a problem, but it's not with the property. Anyhow, thanks everyone for being helpful :smile:
Any chance that, somewhere in one of your scripts, you are using fBody ==0 ?

(that is, without the trailing .0)

That might turn the float into an int ... and you would lose your safety net of not zero

... just a thought ... I don't see anything wrong with what you posted ... if it works for 50-hours it's got to be something weird. If lots of your players are reporting it, then it can't be some weird coincidence that no one else will ever get,

I also can't see how any of the currently-reported bugs would effect you.

Oddness ...
User avatar
leigh stewart
 
Posts: 3415
Joined: Mon Oct 23, 2006 8:59 am


Return to V - Skyrim