Wonderlarr Posted July 28, 2020 Share Posted July 28, 2020 I'm currently trying to implement a mechanic into my custom character. When they are above a certain amount of sanity, they get an effect, when below but not insane, get a weaker effect, and remove completely when insane. I've successfully implemented it, but I feel like it's inefficient to be running a whole string of 4+ elseif statements every frame. How would I do this more efficiently? Here is the if statement string for context local function OnSanityDelta(inst, data) CurrentSanity = inst.components.sanity:GetPercent() if CurrentSanity ~= nil then if CurrentSanity >= 0.5 then -- If sanity is greater than 50%, set sanity aurarate to 100% inst.components.sanityaura.aura = TUNING.HATKID_AURARATE print("sanityaura 1") elseif CurrentSanity <=0.15 then --if insane, set sanity aurarate to 0 inst.components.sanityaura.aura = TUNING.HATKID_AURARATE * 0 print("sanityaura remove") else-- if in between 15% and 50% sanity, set sanity rate to 50% inst.components.sanityaura.aura = TUNING.HATKID_AURARATE * 0.5 print("sanityaura 0.5") end end end This entire function runs every frame Link to comment https://forums.kleientertainment.com/forums/topic/120511-efficently-dealing-with-deltas/ Share on other sites More sharing options...
Developer zarklord_klei Posted July 28, 2020 Developer Share Posted July 28, 2020 I can't remember the eventname off the top of my head, but there is an event thats pushed whenever sanity changes, you could have that code only run after that event, so your only updating the effect when sanity changes, beyond that, keeping track of the current effect range your in, and returning immediately if the new sanity value is still inside the current range could be a nice optimization. 1 Link to comment https://forums.kleientertainment.com/forums/topic/120511-efficently-dealing-with-deltas/#findComment-1358100 Share on other sites More sharing options...
CarlZalph Posted July 28, 2020 Share Posted July 28, 2020 3 hours ago, Zarklord said: I can't remember the eventname off the top of my head, but there is an event thats pushed whenever sanity changes, you could have that code only run after that event, so your only updating the effect when sanity changes, beyond that, keeping track of the current effect range your in, and returning immediately if the new sanity value is still inside the current range could be a nice optimization. Looks like the OP's already listening for sanitydelta event there, and this is the callback for it. And yes, I'd also advise using a stored state to know when it changes rather than continuously applying the effects of the state. 4 hours ago, DocterRedstone said: I'm currently trying to implement a mechanic into my custom character. When they are above a certain amount of sanity, they get an effect, when below but not insane, get a weaker effect, and remove completely when insane. I've successfully implemented it, but I feel like it's inefficient to be running a whole string of 4+ elseif statements every frame. How would I do this more efficiently? Here is the if statement string for context This entire function runs every frame To optimize for speed, you'd use a lookup table. Since your value ranges are quite a lot it would not be memory efficient at all and not advisable. The check for if CurrentSanity ~= nil is not needed here, as GetPercent is guaranteed to return a number. If another mod changes this assumption, then that other mod is in fault and should be changed. Also to keep logic in a step ladder, I'd advise rearranging it to: local function OnSanityDelta(inst, data) CurrentSanity = inst.components.sanity:GetPercent() if CurrentSanity <= 0.15 then inst.components.sanityaura.aura = TUNING.HATKID_AURARATE * 0 print("sanityaura remove") elseif CurrentSanity <= 0.5 then inst.components.sanityaura.aura = TUNING.HATKID_AURARATE * 0.5 print("sanityaura 0.5") else inst.components.sanityaura.aura = TUNING.HATKID_AURARATE print("sanityaura 1") end end That way the logical size of CurrentSanity is maintained from top to bottom with top being least to bottom most. With how you arranged it hops over ranges and is not intuitive, making a mess for adding in more states later etc. But a couple of if statements should ultimately be the least of your concerns in terms of performance. It's very negligible compared to pretty much everything else you could be doing. Link to comment https://forums.kleientertainment.com/forums/topic/120511-efficently-dealing-with-deltas/#findComment-1358133 Share on other sites More sharing options...
Wonderlarr Posted July 29, 2020 Author Share Posted July 29, 2020 7 hours ago, CarlZalph said: Looks like the OP's already listening for sanitydelta event there, and this is the callback for it. And yes, I'd also advise using a stored state to know when it changes rather than continuously applying the effects of the state. To optimize for speed, you'd use a lookup table. Since your value ranges are quite a lot it would not be memory efficient at all and not advisable. The check for if CurrentSanity ~= nil is not needed here, as GetPercent is guaranteed to return a number. If another mod changes this assumption, then that other mod is in fault and should be changed. Also to keep logic in a step ladder, I'd advise rearranging it to: local function OnSanityDelta(inst, data) CurrentSanity = inst.components.sanity:GetPercent() if CurrentSanity <= 0.15 then inst.components.sanityaura.aura = TUNING.HATKID_AURARATE * 0 print("sanityaura remove") elseif CurrentSanity <= 0.5 then inst.components.sanityaura.aura = TUNING.HATKID_AURARATE * 0.5 print("sanityaura 0.5") else inst.components.sanityaura.aura = TUNING.HATKID_AURARATE print("sanityaura 1") end end That way the logical size of CurrentSanity is maintained from top to bottom with top being least to bottom most. With how you arranged it hops over ranges and is not intuitive, making a mess for adding in more states later etc. But a couple of if statements should ultimately be the least of your concerns in terms of performance. It's very negligible compared to pretty much everything else you could be doing. Thanks for the organization suggestion, that was definitely needed considering the current state of it. Is there any way of only getting the Sanity Delta when the whole number changes? Speed isn't really needed here, since it's just a minor perk that changes the state of a sanity aura. Link to comment https://forums.kleientertainment.com/forums/topic/120511-efficently-dealing-with-deltas/#findComment-1358247 Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now