Jump to content

Efficently dealing with Delta's


Recommended Posts

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
Share on other sites

  • Developer

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.

  • Like 1
Link to comment
Share on other sites

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
Share on other sites

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
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...