TangerineDog Posted October 6, 2017 Share Posted October 6, 2017 My script can deal with this line ok at first: ((1+MasterCounterInterval.GetValueInt())*pHoursToWait-(NewTime*24-StartTime*24)) It sets a timer to this value, but when it's time for that update, the game just freezes. Is there anything wrong with that line alone? Link to comment Share on other sites More sharing options...
Kapteyn Posted October 6, 2017 Share Posted October 6, 2017 (edited) That algebra means nothing to me without knowing what it's doing and the values of the variables, but a freeze generally suggests that something is recursive. Are you using any while loops based around this? Or if you are using OnUpdate() based on this timer - if it's resulting in a very low number then you're possibly refreshing the function too quickly, like millisecond often. Also, be sure to differentiate between a crash and a freeze; in the case of the latter, the game is still running but is busy doing its eternal thing - just make sure you shut the game down before it runs out of memory and overflows the buffer. Edited October 6, 2017 by Kapteyn Link to comment Share on other sites More sharing options...
TangerineDog Posted October 6, 2017 Author Share Posted October 6, 2017 (edited) This is the whole script: RIght now, it usually sets the timer to 0.41something the first time round.The next time it should update, it freezes - nothing happens, I can't even close the game in the task manager. I'm working on having it show me how long it took to run through the script's main part. if it's more than 0.05, that might confuse things.Edit: it was 0.0000043 - not the reason. It seems that updates after more than 0.4 - the value I've set for pHourstoWait - make the game freeze. ScriptName HungerCounterScript extends activemagiceffectFloat Property pHoursToWait AutoFloat TimerSettingGlobalVariable Property HungerCount AutoGlobalVariable Property HungerCount01 AutoGlobalVariable Property HungerCount02 AutoGlobalVariable Property HungerCount03 AutoMagicEffect Property HungerEffect01 AutoMagicEffect Property HungerEffect02 AutoMagicEffect Property HungerEffect03 AutoSpell Property HungerSpell01 AutoSpell Property HungerSpell02 AutoSpell Property HungerSpell03 AutoFloat NewTimeFloat StartTimeGlobalVariable Property MasterCounterHunger AutoGlobalVariable Property MasterCounterInterval AutoEvent OnUpdateGameTime(); debug.trace(self + "OnUpdateGameTime")Debug.Notification("Update")NewTime = Utility.GetCurrentGameTime()MasterCounterInterval.GetValue()MasterCounterInterval.SetValue(math.floor(math.floor(NewTime*24-StartTime*24)/pHoursToWait))If MasterCounterHunger.GetValueInt() < MasterCounterInterval.GetValueInt()HungerCount.Mod(MasterCounterInterval.GetValueInt()-MasterCounterHunger.GetValueInt())MasterCounterHunger.SetValue(MasterCounterInterval.GetValueInt())EndifDebug.Notification("pHourstoWait has passed" + (math.floor(math.floor(NewTime*24-StartTime*24)/pHoursToWait)) + "whole times since StartTime")Debug.Notification("The next update should happen in" + ((1+MasterCounterInterval.GetValueInt())*pHoursToWait-(NewTime*24-StartTime*24)) + "")If ((1+MasterCounterInterval.GetValueInt())*pHoursToWait-(NewTime*24-StartTime*24)) > 0.05TimerSetting = ((1+MasterCounterInterval.GetValueInt())*pHoursToWait-(NewTime*24-StartTime*24))ElseTimerSetting = ((2+MasterCounterInterval.GetValueInt())*pHoursToWait-(NewTime*24-StartTime*24))HungerCount.Mod(1.0)EndifRegisterForUpdateGameTime(TimerSetting)Debug.Notification("Timer set to" + TimerSetting + "")if HungerCount.GetValue() >= HungerCount03.GetValue()If (Game.GetPlayer().HasMagicEffect(HungerEffect03))elseGame.GetPlayer().AddSpell(HungerSpell03, false)Debug.Notification("You are starving.")endifIf (Game.GetPlayer().HasMagicEffect(HungerEffect02))Game.GetPlayer().RemoveSpell(HungerSpell02)endifIf (Game.GetPlayer().HasMagicEffect(HungerEffect01))Game.GetPlayer().RemoveSpell(HungerSpell01)endifelseif HungerCount.GetValue() >= HungerCount02.GetValue()If (Game.GetPlayer().HasMagicEffect(HungerEffect02))elseGame.GetPlayer().AddSpell(HungerSpell02, false)Debug.Notification("You are hungry.")endifIf (Game.GetPlayer().HasMagicEffect(HungerEffect03))Game.GetPlayer().RemoveSpell(HungerSpell03)endifIf (Game.GetPlayer().HasMagicEffect(HungerEffect01))Game.GetPlayer().RemoveSpell(HungerSpell01)endifelseif HungerCount.GetValue() >= HungerCount01.GetValue()If (Game.GetPlayer().HasMagicEffect(HungerEffect01))elseGame.GetPlayer().AddSpell(HungerSpell01, false)Debug.Notification("You have an appetite.")endifIf (Game.GetPlayer().HasMagicEffect(HungerEffect03))Game.GetPlayer().RemoveSpell(HungerSpell03)endifIf (Game.GetPlayer().HasMagicEffect(HungerEffect02))Game.GetPlayer().RemoveSpell(HungerSpell02)endifelseif HungerCount.GetValue() < HungerCount01.GetValue()If (Game.GetPlayer().HasMagicEffect(HungerEffect01))Game.GetPlayer().RemoveSpell(HungerSpell01)endifIf (Game.GetPlayer().HasMagicEffect(HungerEffect03))Game.GetPlayer().RemoveSpell(HungerSpell03)endifIf (Game.GetPlayer().HasMagicEffect(HungerEffect02))Game.GetPlayer().RemoveSpell(HungerSpell02)endifendifEndEventEvent OnEffectStart(Actor akTarget, Actor akCaster); start timerStartTime = Utility.GetCurrentGameTime()TimerSetting = pHoursToWaitRegisterForUpdateGameTime(TimerSetting)EndEvent ALso, I don't know how to post one of the beautiful, colorful scripts I see aorund here sometimes. Sorry for the block of text. Edited October 6, 2017 by TangerineDog Link to comment Share on other sites More sharing options...
foamyesque Posted October 6, 2017 Share Posted October 6, 2017 Aieee, indent your code, it'll make your life much easier. The colourful formatting you're talking about is done with the [plain][/plain] tags, FYI. I am not certain but I suspect the culprit is some kind of recursion between your adding of spells and your OnEffectStart event. I would try remarking out the entire block of if statements governing what hunger spell should be applicable and seeing what happens. Your internal debug statements should probably be converted from Notification to Trace as well; they're faster and the logfile will give you much more precise timestamps and ordering. You'll probably want to prefix them with "TangerineHunger" or something so that you can find them in all the other junk the logfile can have, though. Link to comment Share on other sites More sharing options...
JonathanOstrus Posted October 6, 2017 Share Posted October 6, 2017 Aieee, indent your code, it'll make your life much easier. The colourful formatting you're talking about is done with the [plain][/plain] tags, FYI. I am not certain but I suspect the culprit is some kind of recursion between your adding of spells and your OnEffectStart event. I would try remarking out the entire block of if statements governing what hunger spell should be applicable and seeing what happens. Your internal debug statements should probably be converted from Notification to Trace as well; they're faster and the logfile will give you much more precise timestamps and ordering. You'll probably want to prefix them with "TangerineHunger" or something so that you can find them in all the other junk the logfile can have, though. It might have been indented. The BB system doesn't handle pasted tab indents properly most of the time. Which is why my editors are all configured (when possible) to convert tabs to spaces. You also forgot to close the code tag in your example. Link to comment Share on other sites More sharing options...
ReDragon2013 Posted October 6, 2017 Share Posted October 6, 2017 RegisterForUpdateGameTime() again and again.. Maybe the next code is useful for you. HungerCounterScript Scriptname HungerCounterScript extends ActiveMagicEffect {rewritten by ReDragon 2017} ; https://forums.nexusmods.com/index.php?/topic/6050258-why-does-my-script-crash/ ; TangerineDog wrote: " ((1+MasterCounterInterval.GetValueInt())*pHoursToWait-(NewTime*24-StartTime*24)) " ; "It sets a timer to this value, but when it's time for that update, the game just freezes." GlobalVariable PROPERTY MasterCounterInterval auto GlobalVariable PROPERTY MasterCounterHunger auto GlobalVariable PROPERTY HungerCount auto GlobalVariable PROPERTY HungerCount01 auto GlobalVariable PROPERTY HungerCount02 auto GlobalVariable PROPERTY HungerCount03 auto Spell PROPERTY HungerSpell01 auto Spell PROPERTY HungerSpell02 auto Spell PROPERTY HungerSpell03 auto MagicEffect PROPERTY HungerEffect01 auto MagicEffect PROPERTY HungerEffect02 auto MagicEffect PROPERTY HungerEffect03 auto Float PROPERTY pHoursToWait auto Float StartTime ; -- EVENTs -- 3 EVENT OnEffectStart(Actor akTarget, Actor akCaster) ;IF (akCaster == Game.GetPlayer()) Debug.Trace("HungerME: OnEffectStart() - target = " +akTarget+ ", caster = " +akCaster) ; info only StartTime = Utility.GetCurrentGameTime() RegisterForSingleUpdateGameTime(pHoursToWait) ; single update here, keep in mind !!! ;ENDIF ENDEVENT EVENT OnEffectFinish(Actor akTarget, Actor akCaster) Debug.Trace("HungerME: OnEffectFinish() - target = " +akTarget+ ", caster = " +akCaster) ; info only ENDEVENT EVENT OnUpdateGameTime() float f = myF_Timer() myF_Hunger() RegisterForSingleUpdateGameTime(f) ; register again for gametime update ENDEVENT ; -- FUNCTIONs -- 2 ;------------------------- Float FUNCTION myF_Timer() ;------------------------- float fCurrent = Utility.GetCurrentGameTime() ; fCurrent = NewTime float fTimer = (fCurrent - StartTime) * 24 ; fTimer = TimerSetting float f = fTimer / pHoursToWait MasterCounterInterval.SetValue(f) ; from here: f == MasterCounterInterval.GetValue() IF (MasterCounterHunger.GetValue() < f) HungerCount.Mod(f - MasterCounterHunger.GetValue()) MasterCounterHunger.SetValue(f) ENDIF IF ( ((1+f)*pHoursToWait - fTimer) > 0.05 ) fTimer = ((1+f)*pHoursToWait - fTimer) ELSE fTimer = ((2+f)*pHoursToWait - fTimer) HungerCount.Mod(1.0) ENDIF Debug.Trace("HungerME: OnUpdateGameTime() - HungerCount = " +HungerCount.GetValue()) Debug.Notification("Timer = " +fTimer) RETURN fTimer ENDFUNCTION ;-------------------- FUNCTION myF_Hunger() ;-------------------- actor Player = Game.GetPlayer() float f = HungerCount.GetValue() ; take it once, store the value IF (f >= HungerCount03.GetValue()) IF Player.HasMagicEffect(HungerEffect03) ; HungerSpell03 already here ELSE Player.AddSpell(HungerSpell03, False) Debug.Notification("You are starving.") ; 03 starving ENDIF Player.RemoveSpell(HungerSpell01) Player.RemoveSpell(HungerSpell02) RETURN ; - STOP - ENDIF ;--------------------- IF (f >= HungerCount02.GetValue()) IF Player.HasMagicEffect(HungerEffect02) ; HungerSpell02 already here ELSE Player.AddSpell(HungerSpell02, False) Debug.Notification("You are hungry.") ; 02 hungry ENDIF Player.RemoveSpell(HungerSpell01) Player.RemoveSpell(HungerSpell03) RETURN ; - STOP - ENDIF ;--------------------- IF (f >= HungerCount01.GetValue()) IF Player.HasMagicEffect(HungerEffect01) ; HungerSpell01 already here ELSE Player.AddSpell(HungerSpell01, False) Debug.Notification("You have an appetite.") ; 01 appetite ENDIF Player.RemoveSpell(HungerSpell02) Player.RemoveSpell(HungerSpell03) RETURN ; - STOP - ENDIF ;--------------------- ;IF (f < HungerCount01.GetValue()) Player.RemoveSpell(HungerSpell01) Player.RemoveSpell(HungerSpell02) Player.RemoveSpell(HungerSpell03) ;ENDIF ENDFUNCTION Link to comment Share on other sites More sharing options...
TangerineDog Posted October 6, 2017 Author Share Posted October 6, 2017 (edited) RegisterForUpdateGameTime() again and again.. Maybe the next code is useful for you. HungerCounterScript Scriptname HungerCounterScript extends ActiveMagicEffect {rewritten by ReDragon 2017} ; https://forums.nexusmods.com/index.php?/topic/6050258-why-does-my-script-crash/ ; TangerineDog wrote: " ((1+MasterCounterInterval.GetValueInt())*pHoursToWait-(NewTime*24-StartTime*24)) " ; "It sets a timer to this value, but when it's time for that update, the game just freezes." GlobalVariable PROPERTY MasterCounterInterval auto GlobalVariable PROPERTY MasterCounterHunger auto GlobalVariable PROPERTY HungerCount auto GlobalVariable PROPERTY HungerCount01 auto GlobalVariable PROPERTY HungerCount02 auto GlobalVariable PROPERTY HungerCount03 auto Spell PROPERTY HungerSpell01 auto Spell PROPERTY HungerSpell02 auto Spell PROPERTY HungerSpell03 auto MagicEffect PROPERTY HungerEffect01 auto MagicEffect PROPERTY HungerEffect02 auto MagicEffect PROPERTY HungerEffect03 auto Float PROPERTY pHoursToWait auto Float StartTime ; -- EVENTs -- 3 EVENT OnEffectStart(Actor akTarget, Actor akCaster) ;IF (akCaster == Game.GetPlayer()) Debug.Trace("HungerME: OnEffectStart() - target = " +akTarget+ ", caster = " +akCaster) ; info only StartTime = Utility.GetCurrentGameTime() RegisterForSingleUpdateGameTime(pHoursToWait) ; single update here, keep in mind !!! ;ENDIF ENDEVENT EVENT OnEffectFinish(Actor akTarget, Actor akCaster) Debug.Trace("HungerME: OnEffectFinish() - target = " +akTarget+ ", caster = " +akCaster) ; info only ENDEVENT EVENT OnUpdateGameTime() float f = myF_Timer() myF_Hunger() RegisterForSingleUpdateGameTime(f) ; register again for gametime update ENDEVENT ; -- FUNCTIONs -- 2 ;------------------------- Float FUNCTION myF_Timer() ;------------------------- float fCurrent = Utility.GetCurrentGameTime() ; fCurrent = NewTime float fTimer = (fCurrent - StartTime) * 24 ; fTimer = TimerSetting float f = fTimer / pHoursToWait MasterCounterInterval.SetValue(f) ; from here: f == MasterCounterInterval.GetValue() IF (MasterCounterHunger.GetValue() < f) HungerCount.Mod(f - MasterCounterHunger.GetValue()) MasterCounterHunger.SetValue(f) ENDIF IF ( ((1+f)*pHoursToWait - fTimer) > 0.05 ) fTimer = ((1+f)*pHoursToWait - fTimer) ELSE fTimer = ((2+f)*pHoursToWait - fTimer) HungerCount.Mod(1.0) ENDIF Debug.Trace("HungerME: OnUpdateGameTime() - HungerCount = " +HungerCount.GetValue()) Debug.Notification("Timer = " +fTimer) RETURN fTimer ENDFUNCTION ;-------------------- FUNCTION myF_Hunger() ;-------------------- actor Player = Game.GetPlayer() float f = HungerCount.GetValue() ; take it once, store the value IF (f >= HungerCount03.GetValue()) IF Player.HasMagicEffect(HungerEffect03) ; HungerSpell03 already here ELSE Player.AddSpell(HungerSpell03, False) Debug.Notification("You are starving.") ; 03 starving ENDIF Player.RemoveSpell(HungerSpell01) Player.RemoveSpell(HungerSpell02) RETURN ; - STOP - ENDIF ;--------------------- IF (f >= HungerCount02.GetValue()) IF Player.HasMagicEffect(HungerEffect02) ; HungerSpell02 already here ELSE Player.AddSpell(HungerSpell02, False) Debug.Notification("You are hungry.") ; 02 hungry ENDIF Player.RemoveSpell(HungerSpell01) Player.RemoveSpell(HungerSpell03) RETURN ; - STOP - ENDIF ;--------------------- IF (f >= HungerCount01.GetValue()) IF Player.HasMagicEffect(HungerEffect01) ; HungerSpell01 already here ELSE Player.AddSpell(HungerSpell01, False) Debug.Notification("You have an appetite.") ; 01 appetite ENDIF Player.RemoveSpell(HungerSpell02) Player.RemoveSpell(HungerSpell03) RETURN ; - STOP - ENDIF ;--------------------- ;IF (f < HungerCount01.GetValue()) Player.RemoveSpell(HungerSpell01) Player.RemoveSpell(HungerSpell02) Player.RemoveSpell(HungerSpell03) ;ENDIF ENDFUNCTION That doesn't freeze!I do not yet see what's the difference in function between my chaotic script and your elegant work of art, but I'll get there after some sleep and/ or more caffeine. I made some changes however:first, in function myF_Timer, I added a floor: float f = math.floor(fTimer / pHoursToWait), because the master counter should only count how many whole times the interval has passed.second, in funktion myF_timer, I added MasterCounterHunger.Mod(1.0) below HungerCount.Mod(1.0) to prevent redundancy. RIght now, it seems to work peachily (is that a word?). It shall have to be playtested tomorrow. For now, thank you! edited to fix typo Edited October 6, 2017 by TangerineDog Link to comment Share on other sites More sharing options...
Kapteyn Posted October 8, 2017 Share Posted October 8, 2017 The general rule with the update function is that the recurring updates often need a way out. If you don't have an exit for it, you essentially have an infinite loop which is not always a bad thing if the updates are occurring with enough time between them, but you sometimes still want that option available to exit. This is why a single update, followed by another single update in the update function itself, is the way to go. You then use a global variable which can be flipped either in the MCM or using the console (set <variable> to <float>) - so you have a condition in the script insomuch that if the variable is zero then the update will not occur. I hope that makes sense, it's kinda difficult to explain without enough, like you say, caffeine. Link to comment Share on other sites More sharing options...
cdcooley Posted October 8, 2017 Share Posted October 8, 2017 ALso, I don't know how to post one of the beautiful, colorful scripts I see aorund here sometimes. Sorry for the block of text.You need to use the CODE tag not just the SPOILER tag. You can nest code tags inside of the spoiler tag when you want both. The code tag is what keeps the spacing and gives the pretty colors. The spoiler tag isn't really even that important here. Hiding big blocks of text in spoiler tags is useful in general threads, but when the entire thread is about a particular script it makes sense to just post that script and only use the code tag. Link to comment Share on other sites More sharing options...
Recommended Posts