Jump to content

[SOLVED] How to make a character lose sanity over time when hungry?


Recommended Posts

Hi! I'm pretty new to modding, but I've been making good progress with my first character mod! I was playtesting him, and I wanted to add this feature for balancing purposes.

His basic idea is that he doesn't lose sanity in the dark, since he can see just fine in the dark, but his sanity is naturally very low (100). Whenever he kills a prey animal or consumes raw meat, he loses a lot of sanity. But, on the flip side, consuming raw meat gives much more hunger back than cooked meat. He also gains more sanity from picking flowers, lots more!

I wanted him to be a balancing act with his sanity. But I hardly ever had any difficulty dealing with that, even when I pretty much never cooked any meat. It was just too easy to deal with. So I wanted to make it so that when his hunger level is, say, under 30 points, he loses 1 sanity point every 5 seconds.

Ideally, this should make the raw meat consumption more of a gamble. It will stop his sanity from ticking down continuously, but will still take a toll. It should also make it so there's more of a need to cook meat and build campfires, since he has a normal hunger rate.

However, as you can imagine, I'm having a hard time implementing this mechanic. I've been pouring over the game data and I've found myself overwhelmed with trying to find a way to get this to work. Help would be appreciated!

Edited by PuzzlePeace
Link to comment
Share on other sites

there is a common trick with overwriting a function cleanly:

local DoDelta = inst.components.sanity.DoDelta 
inst.components.sanity.DoDelta = function(sanity, delta, ...)
	-- your bit here, for exmaple: 
  	if sanity.inst.components.hunger and delta < 0 then 
    	sanity.inst.components.hunger:DoDelta(delta * TUNING.HUNGER_SANITY_MULTIPLIER_FOR_MY_CUSTOM_CHARACTER)
    end
  	return DoDelta(sanity, delta, ...)
end 

you can overwrite, for example, the do delta function of the sanity component (which i believe the sanity on update function calls but you should check), by saving the old do delta in a local function, and then overwriting the old do delta function with a new function that includes the old function

Edited by Bad Willow
Link to comment
Share on other sites

On 11/8/2021 at 2:18 AM, Bad Willow said:

there is a common trick with overwriting a function cleanly:


local DoDelta = inst.components.sanity.DoDelta 
inst.components.sanity.DoDelta = function(sanity, delta, ...)
	-- your bit here, for exmaple: 
  	if sanity.inst.components.hunger and delta < 0 then 
    	sanity.inst.components.hunger:DoDelta(delta * TUNING.HUNGER_SANITY_MULTIPLIER_FOR_MY_CUSTOM_CHARACTER)
    end
  	return DoDelta(sanity, delta, ...)
end 

you can overwrite, for example, the do delta function of the sanity component (which i believe the sanity on update function calls but you should check), by saving the old do delta in a local function, and then overwriting the old do delta function with a new function that includes the old function

By "overwrite" do you mean taking the do delta function from the sanity component, and then re-writing it into my mod, while adding in that new function you gave me? Because when I tried to do that, it said that the "sanity" variable was not defined. Maybe I'm reading your instructions wrong, but something just isn't clicking for me.

Link to comment
Share on other sites

Back again, I decided to take another crack at this. I was hoping that maybe someone would have an easier time dictating why something doesn't work than trying to essentially make something from nothing. So with the limited knowledge I have, I made a few lines of code to see if I can get this feature to work. (I didn't, obviously, lol) This is what I ended up making:

local function OnHungerDelta(inst, data)
    CurrentHunger = inst.components.hunger:GetPercent()
    if CurrentHunger <= 0.5 then
        inst.components.sanity.dapperness = -1
    elseif CurrentHunger >= 0.6 then
        inst.components.sanity.dapperness = 0
    end
end

It doesn't cause any crashes, but it also doesn't do anything. The idea is that when my character's hunger is equal to or below 50%, he loses one point of sanity per second. And if it's above or equal to 60%, he no longer loses or gains sanity (for that reason).

It probably should be obvious why this isn't working, but I'm still learning how to mod this game, sooo if anyone could tell me why this doesn't work I'd very much appreciate it!

Link to comment
Share on other sites

I figured it out!! I had the right idea a while back, I was trying to copy Wolfgang's "manliness" mechanic, but I neglected one little detail. Here's what I did, in case anyone else wants a feature like this:

--Put this outside of the master_postinit, I placed it directly above my character's stats. You can change the number values at your discretion, but this makes it so when your character's hunger is beneath a value of 50, you begin losing one sanity point per second. And when it's above hunger, they stop losing sanity over time.


local function onhungerchange(inst, data, forcesilent)
    if inst.components.hunger.current < 50 then
    inst.components.sanity.dapperness = -1
    elseif inst.components.hunger.current > 50 then
    inst.components.sanity.dapperness = 0
    end
end

--Then, place THIS in the master_postinit. I just put it on the bottom. This is the little detail I forgot before and the entire reason it didn't work lol.

inst:ListenForEvent("hungerdelta", onhungerchange)

Good luck out there y'all, thanks for the help, and much love from me <3

Edited by PuzzlePeace
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...