Jump to content

Help with modifying existing character, Tamamo


Recommended Posts

So, since a month and some ago I have been making a mod which modifies existing mod characters when detected. It mostly worked for all characters, but today I found an issue with the character Tamamo by @rons0n, it doesn't work no matter what I do or try, mostly for clients. And rons0n if you are reading this, please insight on why your character breaks all logic in this world because I have been at it for 2 days now.

 

Tamamo's mod page

My mod page

 

 

Please note before reading any of my code that it probably varies from the release on the workshop since everything is moved around to try and make Tamamo worked. I would recommend downloading my modmain.lua from the workshop too. The objective is to add a "Feral" mode to Tamamo, which modifies her stats, and to modify other stats no matter of what mode she is in.

 

Now as for Tamamo's prefab code:

local MakePlayerCharacter = require "prefabs/player_common"local assets = {        Asset( "ANIM", "anim/player_basic.zip" ),        Asset( "ANIM", "anim/player_idles_shiver.zip" ),        Asset( "ANIM", "anim/player_actions.zip" ),        Asset( "ANIM", "anim/player_actions_axe.zip" ),        Asset( "ANIM", "anim/player_actions_pickaxe.zip" ),        Asset( "ANIM", "anim/player_actions_shovel.zip" ),        Asset( "ANIM", "anim/player_actions_blowdart.zip" ),        Asset( "ANIM", "anim/player_actions_eat.zip" ),        Asset( "ANIM", "anim/player_actions_item.zip" ),        Asset( "ANIM", "anim/player_actions_uniqueitem.zip" ),        Asset( "ANIM", "anim/player_actions_bugnet.zip" ),        Asset( "ANIM", "anim/player_actions_fishing.zip" ),        Asset( "ANIM", "anim/player_actions_boomerang.zip" ),        Asset( "ANIM", "anim/player_bush_hat.zip" ),        Asset( "ANIM", "anim/player_attacks.zip" ),        Asset( "ANIM", "anim/player_idles.zip" ),        Asset( "ANIM", "anim/player_rebirth.zip" ),        Asset( "ANIM", "anim/player_jump.zip" ),        Asset( "ANIM", "anim/player_amulet_resurrect.zip" ),        Asset( "ANIM", "anim/player_teleport.zip" ),        Asset( "ANIM", "anim/wilson_fx.zip" ),        Asset( "ANIM", "anim/player_one_man_band.zip" ),        Asset( "ANIM", "anim/shadow_hands.zip" ),        Asset( "SOUND", "sound/sfx.fsb" ),        Asset( "SOUND", "sound/wilson.fsb" ),        Asset( "ANIM", "anim/beard.zip" ),        Asset( "ANIM", "anim/tamamo.zip" ),        Asset( "ANIM", "anim/ghost_tamamo_build.zip" ),		Asset( "ANIM", "anim/tamamo_ball.zip" )}local prefabs = {}local start_inv = {	-- Custom starting items}local function OnKeyPressed(inst, data)    if data.inst == ThePlayer then        if data.key == KEY_Z then            print("KEY_Z has been pressed.")             if TheWorld.ismastersim then                BufferedAction(inst, inst, ACTIONS.BALL):Do()                -- Since we are the server, do the action on the server.            else                SendRPCToServer(RPC.DoWidgetButtonAction, ACTIONS.BALL.code, inst, ACTIONS.BALL.mod_name)            end        end    endend -- This initializes for both clients and the hostlocal common_postinit = function(inst) 	-- Minimap icon	inst.MiniMapEntity:SetIcon( "tamamo.tex" )	inst.transformed = false 	inst:AddComponent("keyhandler")    inst:ListenForEvent("keypressed", OnKeyPressed)end-- This initializes for the host onlylocal master_postinit = function(inst)	-- choose which sounds this character will play	inst.soundsname = "willow"	-- Stats		inst.components.health:SetMaxHealth(150)	inst.components.hunger:SetMax(150)	inst.components.sanity:SetMax(150)	inst.components.sanity.dapperness = (TUNING.DAPPERNESS_SMALL)	inst:AddTag('<span class="searchlite">birdwhisperer</span>')		local eater = inst.components.eater	eater.ignoresspoilage = true			inst.components.eater.Eat_orig = inst.components.eater.Eatfunction inst.components.eater:Eat( food )	if self:CanEat(food) then		if food.components.edible.sanityvalue < 0 then		food.components.edible.sanityvalue = 1	end		if food.components.edible.healthvalue < 0 then		food.components.edible.healthvalue = 3	endendreturn inst.components.eater:Eat_orig(food)end	inst:RemoveTag("scarytoprey")	inst:ListenForEvent("equip", function(inst, data)        print("I'm wearing something.")        inst.AnimState:ClearOverrideSymbol("swap_body")    end)endreturn MakePlayerCharacter("tamamo", prefabs, assets, common_postinit, master_postinit, start_inv)

 

 

And my modmain.lua code as of right now:

local require = GLOBAL.requirelocal STRINGS = GLOBAL.STRINGSlocal MOD_NAME = "Mod Character Rebalancing"---------------------------------- Load Starting Items config ----------------------------------local enableStartingItems = GetModConfigData("ENABLE_STARTING_ITEMS")	local amountOfFlint = GetModConfigData("AMOUNT_OF_FLINT")	local amountOfGrass = GetModConfigData("AMOUNT_OF_GRASS")	local amountOfLogs = GetModConfigData("AMOUNT_OF_LOGS")	local amountOfMeat = GetModConfigData("AMOUNT_OF_MEAT")	local amountOfTwigs = GetModConfigData("AMOUNT_OF_TWIGS")	local giveThermalStone = GetModConfigData("GIVE_THERMAL_STONE")		local startingItems = {}		--------------------------------------- Load Character Balancing config ---------------------------------------local modBalancingEnabled = GetModConfigData("MOD_BALANCING_ENABLED")	local crashBandicootBalanced = GetModConfigData("CRASHBANDICOOT_BALANCED")	local darkSakuraBalanced = GetModConfigData("DARKSAKURA_BALANCED")	--local devonBalanced = GetModConfigData("DEVON_BALANCED")	local drokBalanced = GetModConfigData("DROK_BALANCED")	local endiaBalanced = GetModConfigData("ENDIA_BALANCED")	local farozBalanced = GetModConfigData("FAROZ_BALANCED")	local filiaBalanced = GetModConfigData("FILIA_BALANCED")	--local fionnaBalanced = GetModConfigData("FIONNA_BALANCED")	local freeSpiritBalanced = GetModConfigData("FREESPIRIT_BALANCED")	--local gabenBalanced = GetModConfigData("GABEN_BALANCED")	--local girBalanced = GetModConfigData("GIR_BALANCED")	local haruzBalanced = GetModConfigData("HARUZ_BALANCED")	--local hellaMerdurialBalanced = GetModConfigData("HELLAMERDURIAL_BALANCED")	local luffyBalanced = GetModConfigData("LUFFY_BALANCED")	local madeleineBalanced = GetModConfigData("MADELEINE_BALANCED")	local michaelTheFoxBalanced = GetModConfigData("MICHAELTHEFOX_BALANCED")	local mikuHatsuneBalanced = GetModConfigData("MIKUHATSUNE_BALANCED")	local mitsuruBalanced = GetModConfigData("MITSURU_BALANCED")	--local neptuniaBalanced = GetModConfigData("NEPTUNIA_BALANCED")	local serasBalanced = GetModConfigData("SERAS_BALANCED")	local sollyzBalanced = GetModConfigData("SOLLYZ_BALANCED")	local shovelKnightBalanced = GetModConfigData("SHOVELKNIGHT_BALANCED")	local tamamoBalanced = GetModConfigData("TAMAMO_BALANCED")	--local thanaBalanced = GetModConfigData("THANA_BALANCED")	--local theMedicBalanced = GetModConfigData("THEMEDIC_BALANCED")	local warkBalanced = GetModConfigData("WARK_BALANCED")	local wolfBalanced = GetModConfigData("WOLF_BALANCED")	local woodieBalanced = GetModConfigData("WOODIE_BALANCED")	--local zimBalanced = GetModConfigData("ZIM_BALANCED")		--------------------------------------------------------------------------- Load Leveling System config and assign base max levels difficulties ---------------------------------------------------------------------------local levelSetting = GetModConfigData("LEVEL_SETTING")if levelSetting then	if levelSetting == 1 then levelDifficulty = 30		elseif levelSetting == 2 then levelDifficulty = 50			elseif levelSetting == 3 then levelDifficulty = 75			elseif levelSetting == 4 then levelDifficulty = 100		end	end		--------------------------------- Load Special Modes config ---------------------------------local nerfSpeed = GetModConfigData("NERF_SPEED")local hardcoreMode = GetModConfigData("HARDCORE_MODE")---------------------------------------------------------------- Printing to console functions with mod name and prefixes ----------------------------------------------------------------local function printDebug(message)		if message then	print("[".. (MOD_NAME).. "] ".. "[DEBUG] ".. (message))	end	endlocal function printError(message)		if message then	print("[".. (MOD_NAME).. "] ".. "[ERROR] ".. (message))	end	endlocal function printFatal(message)		if message then	print("[".. (MOD_NAME).. "] ".. "[FATAL] ".. (message))	end	endlocal function printInfo(message)		if message then	print("[".. (MOD_NAME).. "] ".. "[INFO] ".. (message))	end	endlocal function printWarn(message)	if message then	print("[".. (MOD_NAME).. "] ".. "[WARN] ".. (message))	end	end------------------------------------------------------ Check config settings and add items to a table ------------------------------------------------------if enableStartingItems == 1 then -- If starting items is enabled		printInfo("Starting Items enabled")		for _= 1, amountOfFlint do -- For the amount of flint specified in the config		table.insert(startingItems, "flint") -- Insert it into the table "startingItems"	end	for _= 1, amountOfGrass do		table.insert(startingItems, "cutgrass")	end	for _= 1, amountOfLogs do		table.insert(startingItems, "log")	end	for _= 1, amountOfMeat do		table.insert(startingItems, "meat")	end	for _= 1, amountOfTwigs do		table.insert(startingItems, "twigs")	end		if giveThermalStone == 1 then		table.insert(startingItems, "heatrock")	end	else		printInfo("Starting Items disabled")	end---------------------------------------------------- Put starting items in the player's inventory ----------------------------------------------------AddPlayerPostInit(function(inst) -- Add to every player    if inst.OnNewSpawn then -- Store old function        inst.old_OnNewSpawn = inst.OnNewSpawn    end         inst.OnNewSpawn = function(inst) -- On spawn, do the following function	        if inst.components.inventory ~= nil then		            inst.components.inventory.ignoresound = true            for i, v in ipairs(startingItems) do -- For each value inserted above into the table                inst.components.inventory:GiveItem(GLOBAL.SpawnPrefab(v)) -- Give that amount of items to the player            end            inst.components.inventory.ignoresound = false			        end		        if inst.old_OnNewSpawn then		            return inst:old_OnNewSpawn(inst)			        end    endend)---------------------------------------------------- Delete and add items to a player's inventory ----------------------------------------------------local function changeStartingInventory(inst, start_inv)	local oldSpawn = inst.OnNewSpawn	start_inv = start_inv or {}	for _,v in pairs(startingItems) do -- Load starting items too since this deletes inventories		table.insert(start_inv, v)	end	inst.OnNewSpawn = function()		if oldSpawn ~= nil then oldSpawn() end		if inst.components.inventory ~= nil then		inst.components.inventory.ignoresound = true		for i = 1, inst.components.inventory:GetNumSlots() do			inst.components.inventory:RemoveItemBySlot(i) -- Remove all items		end		for _, v in ipairs(start_inv) do			inst.components.inventory:GiveItem(GLOBAL.SpawnPrefab(v)) -- Give new items		end		inst.components.inventory.ignoresound = false	end	endend--local function modifyPrefab(inst, stats)--end------------------------------------------------------------------------- Add a leveling system to a character or plainly modify it's stats -------------------------------------------------------------------------local function modifyStats(inst, stats)	-- Load the given stats	if nerfSpeed == 0 then		health = stats.health		hunger = stats.hunger		sanity = stats.sanity		damage = stats.damage		insulation = stats.insulation		walkSpeed = stats.walkSpeed		runSpeed = stats.runSpeed		dapperness = stats.dapperness		nightDrain = stats.nightDrain		monsterDrain = stats.monsterDrain		strongStomach = stats.strongStomach		hungerRate = stats.hungerRate	elseif nerfSpeed == 1 then		health = stats.healthNerf		hunger = stats.hungerNerf		sanity = stats.sanityNerf		damage = stats.damageNerf		insulation = stats.insulationNerf		walkSpeed = stats.walkSpeedNerf		runSpeed = stats.runSpeedNerf		dapperness = stats.dappernessNerf		nightDrain = stats.nightDrainNerf		monsterDrain = stats.monsterDrainNerf		strongStomach = stats.strongStomachNerf		hungerRate = stats.hungerRateNerf	end    	if hardcoreMode == 0 then levelNerf = stats.levelNerf	elseif hardcoreMode == 1 then levelNerf = stats.hardcoreMode end	local foodType = stats.foodType	local foodPrefab1 = stats.foodPrefab1	local foodPrefab2 = stats.foodPrefab2	local foodPrefab3 = stats.foodPrefab3	local foodPrefab4 = stats.foodPrefab4	local foodPrefab5 = stats.foodPrefab5		local levelPerFood1 = stats.levelPerFood1		local levelPerFood2 = stats.levelPerFood2		local levelPerFood3 = stats.levelPerFood3		local levelPerFood4 = stats.levelPerFood4		local levelPerFood5 = stats.levelPerFood5	if nerfSpeed == 0 then		initialHealth = stats.initialHealth		initialHunger = stats.initialHunger		initialSanity = stats.initialSanity		initialDamage = stats.initialDamage		initialInsulation = stats.initialInsulation		initialWalk = stats.initialWalk		initialRun = stats.initialRun		finalHealth = stats.finalHealth		finalHunger = stats.finalHunger		finalSanity = stats.finalSanity		finalDamage = stats.finalDamage		finalInsulation = stats.finalInsulation		finalWalk = stats.finalWalk		finalRun = stats.finalRun	elseif nerfSpeed == 1 then		initialHealth = stats.initialHealthNerf		initialHunger = stats.initialHungerNerf		initialSanity = stats.initialSanityNerf		initialDamage = stats.initialDamageNerf		initialInsulation = stats.initialInsulationNerf		initialWalk = stats.initialWalkNerf		initialRun = stats.initialRunNerf		finalHealth = stats.finalHealthNerf		finalHunger = stats.finalHungerNerf		finalSanity = stats.finalSanityNerf		finalDamage = stats.finalDamageNerf		finalInsulation = stats.finalInsulationNerf		finalWalk = stats.finalWalkNerf		finalRun = stats.finalRunNerf	end		if levelSetting > 0 and initialHealth or initialHunger or initialSanity or initialDamage or initialInsulation or initialWalk or initialRun then				if not levelNerf then			levelNerf = 0		end				maxUpgrades = levelDifficulty+levelNerf				function applyUpgrades(inst)			local upgrades = math.min(inst.level, maxUpgrades)	 			local hunger_percent = inst.components.hunger:GetPercent()			local health_percent = inst.components.health:GetPercent()			local sanity_percent = inst.components.sanity:GetPercent()									if initialHealth and finalHealth and upgrades and maxUpgrades then			inst.components.health.maxhealth = math.ceil (initialHealth + upgrades * (finalHealth - initialHealth) / maxUpgrades)					end						if initialHunger and finalHunger and upgrades and maxUpgrades then			inst.components.hunger.max = math.ceil (initialHunger + upgrades * (finalHunger - initialHunger) / maxUpgrades)			end						if initialSanity and finalSanity and upgrades and maxUpgrades then			inst.components.sanity.max = math.ceil (initialSanity + upgrades * (finalSanity - initialSanity) / maxUpgrades)			end						if initialDamage and finalDamage and upgrades and maxUpgrades then			inst.components.combat.damagemultiplier = math.ceil (initialDamage + upgrades * (finalDamage - initialDamage) / maxUpgrades)			end						if initialInsulation and finalInsulation and upgrades and maxUpgrades then			inst.components.temperature.inherentinsulation = math.ceil (initialInsulation + upgrades * (finalInsulation - initialInsulation) / maxUpgrades)			end						if initialWalk and finalWalk and initialRun and finalRun and upgrades and maxUpgrades then			inst.components.locomotor.walkspeed =  math.ceil (TUNING.WILSON_WALK_SPEED * (initialWalk + upgrades * (finalWalk - initialWalk) / maxUpgrades))			inst.components.locomotor.runspeed = math.ceil (TUNING.WILSON_RUN_SPEED * (initialRun + upgrades * (finalRun - initialRun) / maxUpgrades))			end						inst.components.talker:Say("Level : ".. (inst.level))						if inst.level > math.ceil (maxUpgrades-1) then				inst.components.talker:Say("Level : Max!")			end						inst.components.hunger:SetPercent(hunger_percent)			inst.components.health:SetPercent(health_percent)			inst.components.sanity:SetPercent(sanity_percent)		end				if foodType then			local function oneat(inst, food)							if food and food.components.edible and food.components.edible.foodtype=="foodType" then					inst.level = inst.level + 1					applyUpgrades(inst)					inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup")				end							end		end				function oneat(inst, food)			if foodPrefab1 and levelPerFood1 then -- If the variables exist				if food and food.components.edible and food.prefab == foodPrefab1 then -- If its a food, edible and has the specified prefab					inst.level = inst.level + levelPerFood1 -- Level up according to the variable levelPerFood					applyUpgrades(inst) -- Set the stats					inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup") -- Play a sound				end			end			if foodPrefab2 and levelPerFood2 then				if food and food.components.edible and food.prefab == foodPrefab2 then					inst.level = inst.level + levelPerFood2					applyUpgrades(inst)					inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup")				end			end			if foodPrefab3 and levelPerFood3 then				if food and food.components.edible and food.prefab == foodPrefab3 then					inst.level = inst.level + levelPerFood3					applyUpgrades(inst)					inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup")				end			end			if foodPrefab4 and levelPerFood4 then				if food and food.components.edible and food.prefab == foodPrefab4 then					inst.level = inst.level + levelPerFood4					applyUpgrades(inst)					inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup")				end			end			if foodPrefab5 and levelPerFood5 then				if food and food.components.edible and food.prefab == foodPrefab5 then					inst.level = inst.level + levelPerFood5					applyUpgrades(inst)					inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup")				end			end		end					local function onpreload(inst, data)			if data then				if data.level then					inst.level = data.level					applyUpgrades(inst)					if data.health and data.health.health then inst.components.health.currenthealth = data.health.health end					if data.hunger and data.hunger.hunger then inst.components.hunger.current = data.hunger.hunger end					if data.sanity and data.sanity.current then inst.components.sanity.current = data.sanity.current end					inst.components.health:DoDelta(0)					inst.components.hunger:DoDelta(0)					inst.components.sanity:DoDelta(0)				end			end		end				local function onsave(inst, data)			data.level = inst.level			data.charge_time = inst.charge_time		end				inst.level = 0		inst.components.eater:SetOnEatFn(oneat)		applyUpgrades(inst)					inst.OnSave = onsave		inst.OnPreLoad = onpreload	end		if health then			inst.components.health:SetMaxHealth(health)		end				if hunger then			inst.components.hunger:SetMax(hunger)		end				if sanity then			inst.components.sanity:SetMax(sanity)		end				if damage then			inst.components.combat.damagemultiplier = damage		end				if insulation then			inst.components.temperature.inherentinsulation = insulation		end				if walkSpeed and runSpeed then			inst.components.locomotor.walkspeed = TUNING.WILSON_WALK_SPEED * walkSpeed			inst.components.locomotor.runspeed = TUNING.WILSON_RUN_SPEED * runSpeed		end				if dapperness then			inst.components.sanity.dapperness = dapperness		end				if nightDrain then			inst.components.sanity.night_drain_mult = nightDrain		end				if monsterDrain then			inst.components.sanity.neg_aura_mult = monsterDrain		end				if strongStomach then			inst.components.eater.strongstomach = strongStomach		end				if hungerRate then			inst.components.hunger:SetRate(TUNING.WILSON_HUNGER_RATE * hungerRate)		end	end------------------------------------------- Function to add modes to characters -------------------------------------------local function CRAddMode(inst, CRKey, CRAction)  local function OnKeyPressed(inst, data)		if data.inst == GLOBAL.ThePlayer then			if data.key == CRKey then --Welcome to GLOBAL ville				if GLOBAL.TheWorld.ismastersim then					GLOBAL.BufferedAction(inst, inst, GLOBAL.ACTIONS[CRAction]):Do()				else					GLOBAL.SendRPCToServer(GLOBAL.RPC.DoWidgetButtonAction, GLOBAL.ACTIONS[CRAction].code, inst, GLOBAL.ACTIONS[CRAction].mod_name)				end			end		end	end	inst:AddComponent("CRkeyhandler")	inst:ListenForEvent("CRkeypressed", OnKeyPressed)end---------------------------------------------------------------------------------- Component to make certain items undroppable when given the tag undroppable ----------------------------------------------------------------------------------AddComponentPostInit("inventory", function(self) -- Add the function to the component inventory	local DropItem_base = self.DropItem	function self:DropItem(item, ...)		if item:HasTag("undroppable") then -- Check for the tag			return false -- Can't be dropped		else			return DropItem_base(self, item, ...)		end	endend)-------------------------------------------------- Component to make items character specific --------------------------------------------------AddComponentPostInit("inventory", function(self)	local old_Equip = self.Equip -- Store old function	function self:Equip(item, ...)		-- Checks if item is character specific, and if the player isn't the owner, make it say so		if item.components.characterspecific and item.components.characterspecific.character ~= self.inst.prefab then			self.inst.components.talker:Say("This isn't mine")			self:DropItem(item)			return false -- Prevents item from being obtained		end		return old_Equip(self, item, ...) -- Normal function execution	endend)--[[Add the characterspecific component to the items:inst:AddComponent("characterspecific")inst.components.characterspecific:SetOwner(inst.prefab)]]------------------------------------------------------- Make functions to change each character's stats -------------------------------------------------------local function balanceCrashBandicootStats(inst)	local crashBandicootStats = {									levelNerf = 50,									levelNerfHardcore = 250,																		foodPrefab1 = "wumpa",									foodPrefab2 = "wumpa_cooked",									foodPrefab3 = "carrot",									levelPerFood1 = 2,									levelPerFood2 = 2,									levelPerFood3 = 1,																		initialHealth = 75,									initialHunger = 75,									initialSanity = 100,									initialWalkNerf = 1,									initialRunNerf = 1,																		finalHealth = 100,									finalHunger = 125,									finalSanity = 150,									finalRunNerf = 1,									finalWalkNerf = 1,								}		modifyStats(inst, crashBandicootStats)	endlocal function balanceDarkSakuraStats(inst)	local darkSakuraStats =	{								health = 75,								hunger = 100,							}	modifyStats(inst, darkSakuraStats)end--local function balanceDevonStats(inst)--endlocal function balanceDrokStats(inst)	local drokStats =	{							health = 175,							hunger = 200,							damage = 1.5,						}		modifyStats(inst, drokStats)	endlocal function balanceEndiaStats(inst)	local endiaStats =	{							health = 75,							hunger = 100,							sanity = 75,						}							modifyStats(inst, endiaStats)	endlocal function balanceFarozStats(inst)	local farozStats =	{							dapperness = -0.25,							nightDrain = 1.25,							monsterDrain = 1.25,						}							modifyStats(inst, farozStats)	endlocal function balanceFarozGlasses(inst)	inst:AddTag("undroppable")		inst:AddComponent("characterspecific")	inst.components.characterspecific:SetOwner("faroz")	endlocal function balanceFiliaStats(inst)		local filiaStats =	{							health = 75,							hunger = 100,							sanity = 150,							damage = 1.5,							walkSpeed = 1.5,							runSpeed = 1.5,						}							modifyStats(inst, filiaStats)	end--local function balanceFionnaStats(inst)--endlocal function balanceFreeSpiritStats(inst)	local freeSpiritStats =	{								health = 150,								hunger = 100,								sanity = 150,							}		modifyStats(inst, freeSpiritStats)	end--local function balanceGabenStats(inst)--end--local function balanceGirStats(inst)--endlocal function balanceHaruzStats(inst)	inst.components.sanity.dapperness = TUNING.DAPPERNESS_TINY*-1if levelSetting > 0 then	local oldPreLoad = inst.OnPreLoad	local oldEat = inst.components.eater.oneatfn		local levelNerf = 25		local initialHealth = 75	local initialHunger = 75	local initialSanity = 75		local finalHealth = 150	local finalHunger = 200	local finalSanity = 125		inst.components.health:SetMaxHealth(initialHealth)	inst.components.hunger:SetMax(initialHunger)	inst.components.sanity:SetMax(initialSanity)							local function newUpg(inst)		max_upgrades = levelDifficulty+levelNerf				local upgrades = math.min(inst.level, max_upgrades) 		local hunger_percent = inst.components.hunger:GetPercent()		local health_percent = inst.components.health:GetPercent()		local sanity_percent = inst.components.sanity:GetPercent()				inst.components.health.maxhealth = math.ceil (initialHealth + upgrades * (finalHealth - initialHealth) / max_upgrades)				inst.components.hunger.max = math.ceil (initialHunger + upgrades * (finalHunger - initialHunger) / max_upgrades)		inst.components.sanity.max = math.ceil (initialSanity + upgrades * (finalSanity - initialSanity) / max_upgrades)				inst.components.talker:Say("Level : ".. (inst.level))		if inst.level > math.ceil (max_upgrades-1) then			inst.components.talker:Say("Level : Max!")		end			inst.components.hunger:SetPercent(hunger_percent)		inst.components.health:SetPercent(health_percent)		inst.components.sanity:SetPercent(sanity_percent)	end		local function newEat(inst, food)		oldEat(inst, food)	if food and food.components.edible and food.components.edible.foodtype=="MEAT" then		newUpg(inst)	endend		local function newPreLoad(inst, data)		oldPreLoad(inst, data)		newUpg(inst)		inst.components.health:DoDelta(0)		inst.components.hunger:DoDelta(0)		inst.components.sanity:DoDelta(0)	end		inst.components.eater:SetOnEatFn(newEat)	inst.OnPreLoad = newPreLoadendend--local function balanceHellaMerdurialStats(inst)--endlocal function balanceLuffyStats(inst)	local luffyStats =	{							health = 100,							sanity = 100,							hungerRate = 2.0,						}							modifyStats(inst, luffyStats)endlocal function balanceMadeleineStats(inst)	changeStartingInventory(inst, {"goldnugget", "redgem", "redgem", "bluegem", "bluegem", "purplegem"})endlocal function balanceMichaelTheFoxStats(inst)	local michaelTheFoxStats =	{									health = 75,									hunger = 125,									sanity = 75,									damage = 0.75,									nightDrain = 1.25,									monsterDrain = 1.25,									dapperness = TUNING.DAPPERNESS_TINY*-1,																		healthNerf = 100,									hungerNerf = 150,									sanityNerf = 100,									damageNerf = 0.85,									nightDrainNerf = 1.10,									monsterDrainNerf = 1.10,									dappernessNerf = TUNING.DAPPERNESS_TINY*0.5,									walkSpeedNerf = 1.25,									runSpeedNerf = 1.25,								}	modifyStats(inst, michaelTheFoxStats)	inst:AddTag("insomniac")endlocal function balanceMikuHatsuneStats(inst)	local mikuHatsuneStats =	{									health = 100,									hunger = 100,									sanity = 100,									damage = 0.75,								}									modifyStats(inst, mikuHatsuneStats)endlocal function balanceMitsuruStats(inst)	inst.components.sanity.dapperness = TUNING.DAPPERNESS_TINY*-1if levelSetting > 0 then	local oldPreLoad = inst.OnPreLoad	local oldEat = inst.components.eater.oneatfn		local levelNerf = 50		local initialHealth = 75	local initialHunger = 75	local initialSanity = 50	local initialDamage = 1.0	local initialInsulation = 0		local finalHealth = 100	local finalHunger = 150	local finalSanity = 125	local finalDamage = 1.5	local finalInsulation = 75		inst.components.health:SetMaxHealth(initialHealth)	inst.components.hunger:SetMax(initialHunger)	inst.components.sanity:SetMax(initialSanity)		local function newUpg(inst)			max_upgrades = levelDifficulty+levelNerf					local upgrades = math.min(inst.level, max_upgrades) 		local hunger_percent = inst.components.hunger:GetPercent()		local health_percent = inst.components.health:GetPercent()		local sanity_percent = inst.components.sanity:GetPercent()				inst.components.health.maxhealth = math.ceil (initialHealth + upgrades * (finalHealth - initialHealth) / max_upgrades)				inst.components.hunger.max = math.ceil (initialHunger + upgrades * (finalHunger - initialHunger) / max_upgrades)		inst.components.sanity.max = math.ceil (initialSanity + upgrades * (finalSanity - initialSanity) / max_upgrades)				inst.components.combat.damagemultiplier = math.ceil (initialDamage + upgrades * (finalDamage - initialDamage) / max_upgrades)		inst.components.temperature.inherentinsulation = math.ceil (initialInsulation + upgrades * (finalInsulation - initialInsulation) / max_upgrades)		inst.components.talker:Say("Level : ".. (inst.level))				if inst.level > math.ceil (max_upgrades-1) then			inst.components.talker:Say("Level : Max!")		end			inst.components.hunger:SetPercent(hunger_percent)		inst.components.health:SetPercent(health_percent)		inst.components.sanity:SetPercent(sanity_percent)	end		local function newEat(inst, food)		oldEat(inst, food)	if food and food.components.edible and food.prefab == "corn" or food.prefab == "carrot" or food.prefab == "eggplant" or food.prefab == "dragonfruit" then			newUpg(inst)		end	end		local function newPreLoad(inst, data)		oldPreLoad(inst, data)		newUpg(inst)		inst.components.health:DoDelta(0)		inst.components.hunger:DoDelta(0)		inst.components.sanity:DoDelta(0)	end		inst.components.eater:SetOnEatFn(newEat)	inst.OnPreLoad = newPreLoadendend--local function balanceNeptuniaStats(inst)--endlocal function balanceSerasStats(inst)	changeStartingInventory(inst, {"smallmeat", "smallmeat"})	endlocal function balanceShovelKnightStats(inst)endlocal function balanceShovelKnightBlades(inst)	    inst:AddTag("undroppable")		inst:AddComponent("characterspecific")	inst.components.characterspecific:SetOwner("winston")	endlocal function balanceSollyzStats(inst)if levelSetting > 0 then	local oldPreLoad = inst.OnPreLoad	local oldEat = inst.components.eater.oneatfn		local levelNerf = 0		local initialHealth = 50	local initialHunger = 75	local initialSanity = 50		local finalHealth = 100	local finalHunger = 150	local finalSanity = 90		inst.components.health:SetMaxHealth(initialHealth)	inst.components.hunger:SetMax(initialHunger)	inst.components.sanity:SetMax(initialSanity)		local function newUpg(inst)		max_upgrades = levelDifficulty+levelNerf				local upgrades = math.min(inst.level, max_upgrades) 		local hunger_percent = inst.components.hunger:GetPercent()		local health_percent = inst.components.health:GetPercent()		local sanity_percent = inst.components.sanity:GetPercent()				inst.components.health.maxhealth = math.ceil (initialHealth + upgrades * (finalHealth - initialHealth) / max_upgrades)				inst.components.hunger.max = math.ceil (initialHunger + upgrades * (finalHunger - initialHunger) / max_upgrades)		inst.components.sanity.max = math.ceil (initialSanity + upgrades * (finalSanity - initialSanity) / max_upgrades)				inst.components.talker:Say("Level : ".. (inst.level))		if inst.level > math.ceil (max_upgrades-1) then			inst.components.talker:Say("Level : Max!")		end			inst.components.hunger:SetPercent(hunger_percent)		inst.components.health:SetPercent(health_percent)		inst.components.sanity:SetPercent(sanity_percent)	end		local function newEat(inst, food)		oldEat(inst, food)	if food and food.components.edible and food.prefab == "fish"  then			newUpg(inst)		end	end		local function newPreLoad(inst, data)		oldPreLoad(inst, data)		newUpg(inst)		inst.components.health:DoDelta(0)		inst.components.hunger:DoDelta(0)		inst.components.sanity:DoDelta(0)	end		inst.components.eater:SetOnEatFn(newEat)	inst.OnPreLoad = newPreLoadendendlocal function balanceTamamoStats(inst)		local DefaultEater = require("components/eater")	local FERAL = GLOBAL.Action()	FERAL.str = "Feral"	FERAL.id = "FERAL"	FERAL.fn = function(act)		local silent = true		--act.target.Light:Enable(true) --inst. -> not assigned act.target is.		if act.target.transformed then			--act.target.Light:Enable(false)			local tamamoStats =	{								health = 125,								damage = 1,								walkSpeed = 1,								runSpeed = 1,								dapperness = 0,								hungerRate = 1,							}						modifyStats(act.target, tamamoStats)		else			--act.target.Light:Enable(true)			local tamamoStats =	{								health = 125,								damage = 1.5,								walkSpeed = 1.5,								runSpeed = 1.5,								dapperness = -2*TUNING.DAPPERNESS_LARGE,								hungerRate = 1.5,							}										modifyStats(act.target, tamamoStats)		end		act.target.transformed = not act.target.transformed		return true	end		AddAction(FERAL)		--local tamamoStats =	{							--health = 125,							--walkSpeed = 1,							--runSpeed = 1,							--damage = 1,							--dapperness = 0,							--hungerRate = 1,						--}			--modifyStats(inst, tamamoStats)			CRAddMode(inst, GLOBAL.KEY_X, "FERAL")		--inst:RemoveTag('<span class="searchlite">birdwhisperer</span>')	--inst:AddTag("scarytoprey")		--inst.components.eater.ignorespoilage = false	--function inst.components.eater:Eat(food)		--return DefaultEater.Eat(self, food)	--end	end--local function balanceThanaStats(inst)--end--local function balanceTheMedicStats(inst)--endlocal function balanceWarkStats(inst)	local warkStats =	{							health = 125,							hunger = 150,							damage = 0.8,														healthNerf = 150,							hungerNerf = 150,							damageNerf = 1,							walkSpeedNerf = 1,							runSpeedNerf = 1,						}		modifyStats(inst, warkStats)	endlocal function balanceWolfStats(inst)	inst.components.sanity.dapperness = TUNING.DAPPERNESS_TINY*-0.75	endlocal function balanceWoodieStats(inst)	local woodieStats = {							levelNerf =  0,							foodPrefab1 =  "butterflymuffin",							levelPerFood1 = 1,															initialHealth = 75,							initialHunger = 100,							initialSanity = 100,							finalHealth = 175,							finalHunger = 200,							finalSanity = 175,						}	modifyStats(inst, woodieStats)	endlocal function balanceWoodieAxe(inst)	    inst:AddTag("undroppable")		inst:AddComponent("characterspecific")	inst.components.characterspecific:SetOwner("woodie")	end--[[local function balanceZimStats(inst)end]]----------------------------------------------------------------------------------- Add the previously set functions to each character or character item prefab -----------------------------------------------------------------------------------if modBalancingEnabled == 1 then -- TODO: Replace with a function		printInfo("Mod Balancing enabled")			if GLOBAL.KnownModIndex:IsModEnabled("workshop-382501575") then		if crashBandicootBalanced == 1 then			AddPrefabPostInit("crashbandi", balanceCrashBandicootStats)			printInfo("Balancing Crash Bandicoot")		else			printInfo("Ignoring Crash Bandicoot")		end	end			if GLOBAL.KnownModIndex:IsModEnabled("workshop-384048428") then		if devonBalanced == 1 then			AddPrefabPostInit("devon", balanceDarkSakuraStats)			printInfo("Balancing Dark Sakura Matou")		else			printInfo("Ignoring Dark Sakura Matou")		end	end			--[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-366048578") then		if devonBalanced == 1 then			AddPrefabPostInit("devon", balanceDevonStats)			printInfo("Balancing Devon")		else			printInfo("Ignoring Devon")		end	end]]			if GLOBAL.KnownModIndex:IsModEnabled("workshop-373622746") then		if drokBalanced == 1 then			AddPrefabPostInit("drok", balanceDrokStats)			printInfo("Balancing Drok the Caveman")		else			printInfo("Ignoring Drok the Caveman")		end	end			if GLOBAL.KnownModIndex:IsModEnabled("workshop-363966651") then			if endiaBalanced == 1 then				AddPrefabPostInit("endia", balanceEndiaStats)				printInfo("Balancing Endia")				--printInfoToConsole(info, "Balancing Endia")			end		end	if GLOBAL.KnownModIndex:IsModEnabled("workshop-364491382") then		if farozBalanced == 1 then			AddPrefabPostInit("faroz", balanceFarozStats)			AddPrefabPostInit("faroz_gls", balanceFarozGlasses)			printInfo("Balancing Faroz")		else			printInfo("Ignoring Faroz")		end	end			if GLOBAL.KnownModIndex:IsModEnabled("workshop-398833909") then		if filiaBalanced == 1 then			AddPrefabPostInit("filia", balanceFiliaStats)			printInfo("Balancing Filia")		else			printInfo("Ignoring Filia")		end	end		--[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-374341561") then		if fionnaBalanced == 1 then			AddPrefabPostInit("fionna", balanceFionnaStats)			printInfo("Balancing Fionna")		else			printInfo("Ignoring Fionna")		end	end]]			if GLOBAL.KnownModIndex:IsModEnabled("workshop-359318959") then		if freeSpiritBalanced == 1 then			AddPrefabPostInit("freebre", balanceFreeSpiritStats)			printInfo("Balancing FreeSpirit the Umbreon")		else			printInfo("Ignoring FreeSpirit the Umbreon")		end	end			--[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-381660473") then		if gabenBalanced == 1 then			AddPrefabPostInit("gbe", balanceGabenStats)			printInfo("Releasing HL3")		else			printInfo("Delaying HL3")		end	end]]				--[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-363819976") then		if girBalanced == 1 then			AddPrefabPostInit("gir", balanceGirStats)			printInfo("Balancing Gir")		else			printInfo("Ignoring Gir")		end	end]]		if GLOBAL.KnownModIndex:IsModEnabled("workshop-359821133") then		if haruzBalanced == 1 then				AddPrefabPostInit("haruz", balanceHaruzStats)			printInfo("Balancing Haruz")		else			printInfo("Ignoring Haruz")		end	end		--[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-369898161") then		if hellaMerdurialBalanced == 1 then				AddPrefabPostInit("hella", balanceHellaMerdurialStats)			printInfo("Balancing Hella")		else			printInfo("Ignoring Hella")		end	end]]			if GLOBAL.KnownModIndex:IsModEnabled("workshop-380079744") then		if luffyBalanced == 1 then			AddPrefabPostInit("luffy", balanceLuffyStats)			printInfo("Balancing Luffy")		else			printInfo("Ignoring Luffy")		end	end					if GLOBAL.KnownModIndex:IsModEnabled("workshop-369228986") then		if madeleineBalanced == 1 then				AddPrefabPostInit("madeleine", balanceMadeleineStats)			printInfo("Balancing Madeleine")		else			printInfo("Ignoring Madeleine")		end	end		if GLOBAL.KnownModIndex:IsModEnabled("workshop-357013795") then		if michaelTheFoxBalanced == 1 then				AddPrefabPostInit("fox", balanceMichaelTheFoxStats)			printInfo("Balancing Michael the Fox")		else			printInfo("Ignoring Michael the Fox")		end	end			if GLOBAL.KnownModIndex:IsModEnabled("workshop-368321978") then		if mikuHatsuneBalanced == 1 then			AddPrefabPostInit("miku", balanceMikuHatsuneStats)			printInfo("Balancing Miku Hatsune")		else			printInfo("Ignoring Miku Hatsune")		end	end		if GLOBAL.KnownModIndex:IsModEnabled("workshop-364189966") then		if mitsuruBalanced == 1 then				AddPrefabPostInit("mitsuru", balanceMitsuruStats)			printInfo("Balancing Mitsuru")		else			printInfo("Ignoring Mitsuru")		end	end			--[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-351877222") then		if neptuniaBalanced == 1 then			AddPrefabPostInit("nep", balanceNeptuniaStats)			printInfo("Balancing Neptunia")		else			printInfo("Ignoring Neptunia")		end	end]]					if GLOBAL.KnownModIndex:IsModEnabled("workshop-360319890") then		if serasBalanced == 1 then				AddPrefabPostInit("seras", balanceSerasStats)			printInfo("Balancing Seras")		else			printInfo("Ignoring Seras")		end	end			if GLOBAL.KnownModIndex:IsModEnabled("workshop-359479220") then		if sollyzBalanced == 1 then				AddPrefabPostInit("sollyz", balanceSollyzStats)			printInfo("Balancing Sollyz")		else			printInfo("Ignoring Sollyz")		end	end			if GLOBAL.KnownModIndex:IsModEnabled("workshop-369544255") then		if shovelKnightBalanced == 1 then			AddPrefabPostInit("winston", balanceShovelKnightStats)			AddPrefabPostInit("skweaponshovelbladebasic", balanceShovelKnightBlades)			AddPrefabPostInit("skweaponshovelbladechargehandle", balanceShovelKnightBlades)			AddPrefabPostInit("skweaponshovelbladetrenchblade", balanceShovelKnightBlades)			AddPrefabPostInit("skweaponshovelbladedropspark", balanceShovelKnightBlades)			printInfo("Balancing Shovel Knight")		else			printInfo("Ignoring Shovel Knight")		end	end		if GLOBAL.KnownModIndex:IsModEnabled("workshop-399799824") then		if tamamoBalanced == 1 then				AddPrefabPostInit("tamamo", balanceTamamoStats)			printInfo("Balancing Tamamo")		else			printInfo("Ignoring Tamamo")		end	end		--[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-368541793") then		if thanaBalanced == 1 then				AddPrefabPostInit("thana", balanceThanaStats)			printInfo("Balancing Thana")		else			printInfo("Ignoring Thana")		end	end]]			--[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-379628839") then		if theMedicBalanced == 1 then			AddPrefabPostInit("medic", balanceTheMedicStats)			printInfo("Balancing The Medic")		else			printInfo("Ignoring The Medic")		end	end]]						if GLOBAL.KnownModIndex:IsModEnabled("workshop-369518979") then		if warkBalanced == 1 then				AddPrefabPostInit("wark", balanceWarkStats)			printInfo("Balancing Wark")		else			printInfo("Ignoring Wark")		end	end			if GLOBAL.KnownModIndex:IsModEnabled("workshop-369435452") then		if wolfBalanced == 1 then				AddPrefabPostInit("wolft", balanceWolfStats)			printInfo("Balancing Wolf")		else			printInfo("Ignoring Wolf")		end	end			if GLOBAL.KnownModIndex:IsModEnabled("workshop-384633033") then		if woodieBalanced == 1 then				AddPrefabPostInit("woodie", balanceWoodieStats)			AddPrefabPostInit("lucy", balanceWoodieAxe)			printInfo("Balancing PrzemoLSZ's Woodie")		else			printInfo("Ignoring PrszemoLSZ's Woodie")		end	end			--[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-357209437") then		if zimBalanced == 1 then				AddPrefabPostInit("izim", balanceZimStats)			printInfo("Balancing Zim")		else			printInfo("Ignoring Zim")		end	end]]		else		printInfo("Mod Balancing disabled")	end

 

 

 

And my keyhandler:

local CRKeyHandler = Class(function(self, inst)	self.inst = inst	self.handler = TheInput:AddKeyHandler(function(key, down) self:OnRawKey(key, down) end )end)function CRKeyHandler:OnRawKey(key, down)	local player = ThePlayer  	if (key and not down) and not IsPaused() then      	player:PushEvent("CRkeypressed", {inst = self.inst, player = player, key = key})    elseif key and down and not IsPaused() then      	player:PushEvent("CRkeydown", {inst = self.inst, player = player, key = key})  	endendreturn CRKeyHandler

 

And my modinfo.lua:

-- This information tells other players more about the modname = "Mod Character Balancing"description = "Configure everything! Balance your characters, new leveling systems, items for new players, customize your experience. Basically GregTech."author = "DrSmugleaf"version = "2.0.0"priority = -100-- This is the URL name of the mod's thread on the forum; the part after the ? and before the first & in the urlforumthread = ""-- This lets other players know if your mod is out of date, update it to match the current version in the gameapi_version = 10dst_compatible = truedont_starve_compatible = falsereign_of_giants_compatible = trueall_clients_require_mod = falseicon_atlas = "modicon.xml"icon = "modicon.tex"server_filter_tags = {"mod character rebalancing"}configuration_options ={	{        name = "TEST_OF_TESTIES_OF_USELESS_PLACEHOLDER_PANCAKES",        label = "Hover over me!",		hover = "Hover over any config option for details!",        options =        {            {description = "And me!", data = 1, hover = "You can hover over these for information too!"},            {description = "hey", data = 0, hover = "Do you want to build a snoowmaan"},        },        default = 1,    },		{		name = "MOD_BALANCING_ENABLED",		label = "Balance Mod Characters",		hover = "Balance modded characters",		options =	{						{description = "Enabled", data = 1},						{description = "Disabled", data = 0},					},		default = 1,	},		{		name = "LEVEL_SETTING",		label = "Character leveling",		hover = "Needs balance mod characters enabled. New leveling or not, and difficulty",		options =	{						{description = "Disabled", data = 0, hover = "Keeps all leveling systems as is"},						{description = "Easy", data = 1, hover = "Keeps all leveling systems as is, and adds more"},						{description = "Normal", data = 2, hover = "Adds more leveling systems, 50 max lvl base"},						{description = "Hard", data = 3, hover = "Adds more leveling systems, 75 max lvl base"},						{description = "Very Hard", data = 4, hover = "Adds more leveling systems, 100 max lvl base"},					},		default = 2,	},		{		name = "HARDCORE_MODE",		label = "Ultrahard Mode",		hover = "Make everything terrible. Will override most config settings",		options =	{						{description = "No", data = 0, hover = "Don't turn on ultrahard mode, I preffer living"},						{description = "Yes", data = 1, hover = "HOLD ONTO YOUR PANTS"},					},		default = 0,	},		{		name = "NERF_SPEED",		label = "Nerf speed",		hover = "Nerf characters speed to be more default. NOTE: Will buff other stats",		options =	{						{description = "No", data = 0, hover = "Don't nerf speed"},						{description = "Yes", data = 1, hover = "Nerf speed but buff other stats to compensate"},					},		default = 0,	},		{		name = "ENABLE_STARTING_ITEMS",		label = "Starting Items",		hover = "Enable Starting Items for new players",		options =	{						{description = "Yes", data = 1, hover = "Enable spawning with resources"},						{description = "No", data = 0, hover = "Disable spawning with resources"},					},		default = 1,	},		{		name = "AMOUNT_OF_FLINT",		label = "Amount of flint",		hover = "Amount of flint new players spawn with",		options =	{						{description = "Disabled", data = 0, hover = "Disable spawning with flint"},						{description = "1", data = 1},						{description = "2", data = 2},						{description = "3", data = 3},						{description = "4", data = 4},						{description = "5", data = 5},						{description = "6", data = 6},						{description = "7", data = 7},						{description = "8", data = 8},						{description = "9", data = 9},						{description = "10", data = 10},					},		default = 5,	},		{		name = "AMOUNT_OF_GRASS",		label = "Amount of grass",		hover = "Amount of grass new players spawn with",		options =	{						{description = "Disabled", data = 0, hover = "Disable spawning with grass"},						{description = "1", data = 1},						{description = "2", data = 2},						{description = "3", data = 3},						{description = "4", data = 4},						{description = "5", data = 5},						{description = "6", data = 6},						{description = "7", data = 7},						{description = "8", data = 8},						{description = "9", data = 9},						{description = "10", data = 10},					},		default = 5,	},		{		name = "AMOUNT_OF_LOGS",		label = "Amount of logs",		hover = "Amount of logs new players spawn with",		options =	{						{description = "Disabled", data = 0, hover = "Disable spawning with logs"},						{description = "1", data = 1},						{description = "2", data = 2},						{description = "3", data = 3},						{description = "4", data = 4},						{description = "5", data = 5},						{description = "6", data = 6},						{description = "7", data = 7},						{description = "8", data = 8},						{description = "9", data = 9},						{description = "10", data = 10},					},		default = 5,	},		{		name = "AMOUNT_OF_MEAT",		label = "Amount of meat",		hover = "Amount of meat new players spawn with",		options =	{						{description = "Disabled", data = 0, hover = "Disable spawning with meat"},						{description = "1", data = 1},						{description = "2", data = 2},						{description = "3", data = 3},						{description = "4", data = 4},						{description = "5", data = 5},						{description = "6", data = 6},						{description = "7", data = 7},						{description = "8", data = 8},						{description = "9", data = 9},						{description = "10", data = 10},					},		default = 5,	},		{		name = "AMOUNT_OF_TWIGS",		label = "Amount of twigs",		hover = "Amount of twigs new players spawn with",		options =	{						{description = "Disabled", data = 0, hover = "Disable spawning with twigs"},						{description = "1", data = 1},						{description = "2", data = 2},						{description = "3", data = 3},						{description = "4", data = 4},						{description = "5", data = 5},						{description = "6", data = 6},						{description = "7", data = 7},						{description = "8", data = 8},						{description = "9", data = 9},						{description = "10", data = 10},					},		default = 5,	},		{		name = "GIVE_THERMAL_STONE",		label = "Give thermal stone",		hover = "Whether or not to give new players a thermal stone",		options =	{						{description = "Yes", data = 1, hover = "Give new players a thermal stone"},						{description = "No", data = 0, hover = "Don't give new players a thermal stone"},					},		default = 1,	},		{		name = "CRASHBANDICOOT_BALANCED",		label = "Crash Bandicoot",		hover = "Balance Crash Bandicoot, the Experiment",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "DARKSAKURA_BALANCED",		label = "Dark Sakura",		hover = "Balance Dark Sakura Matou",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		--[[{		name = "DEVON_BALANCED",		label = "Devon",		hover = "Balance Devon, the Hunter",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},]]		{		name = "DROK_BALANCED",		label = "Drok",		hover = "Balance Drok, the Caveman",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "ENDIA_BALANCED",		label = "Endia",		hover = "Balance Endia, the Paranoid Elf",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "FAROZ_BALANCED",		label = "Faroz",		hover = "Balance Faroz, the Little Scholar",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "FILIA_BALANCED",		label = "Filia",		hover = "Balance Filia, the forgetful schoolgirl",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		--[[{		name = "FIONNA_BALANCED",		label = "Fionna",		hover = "Balance Fionna",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},]]		{		name = "FREESPIRIT_BALANCED",		label = "FreeSpirit",		hover = "Balance Umbreon, the FreeSpirit",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		--[[{		name = "GABEN_BALANCED",		label = "Gaben",		hover = "Release HL3",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},]]	--[[{		name = "GIR_BALANCED",		label = "Gir",		hover = "Balance Purswader's Gir",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},]]	{		name = "HARUZ_BALANCED",		label = "Haruz",		hover = "Balance Haruz, the Cowardly Dog",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		--[[{		name = "HELLAMERDURIAL_BALANCED",		label = "Hella Merdurial",		hover = "Balance Hella Merdurial",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},]]		{		name = "LUFFY_BALANCED",		label = "Luffy",		hover = "Balance Luffy",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "MADELEINE_BALANCED",		label = "Madeleine",		hover = "Balance Madeleine, the Rich Cat",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "MICHAELTHEFOX_BALANCED",		label = "Michael the Fox",		hover = "Balance Michael the Fox, the Scaredy Cat",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "MIKUHATSUNE_BALANCED",		label = "Miku Hatsune",		hover = "Balance Miku Hatsune",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "MITSURU_BALANCED",		label = "Mitsuru",		hover = "Balance Mitsuru, the Winter Wolfy",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		--[[{		name = "NEPTUNIA_BALANCED",		label = "Neptunia",		hover = "Balance Hyperdimension Neptunia: Neptune",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},]]		{		name = "SERAS_BALANCED",		label = "Seras",		hover = "Balance Seras, the Fledgling Vampire",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "SOLLYZ_BALANCED",		label = "Sollyz",		hover = "Balance Sollyz, the Cat Slap",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "SHOVELKNIGHT_BALANCED",		label = "Shovel Knight",		hover = "Balance Shovel Knight, the Blue Burrower",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "TAMAMO_BALANCED",		label = "Tamamo",		hover = "Balance Tamamo, Queen of Kitsunes",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		--[[{		name = "THANA_BALANCED",		label = "Thana",		hover = "Balance Thana, the Nightstalker",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},]]		--[[{		name = "THEMEDIC_BALANCED",		label = "The Medic",		hover = "Balance The Medic",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},]]		{		name = "WARK_BALANCED",		label = "Wark, the Chocobo",		hover = "Balance Wark, the Chocobo",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "WOLF_BALANCED",		label = "Wolf",		hover = "Balance Wolf, the Lone Wolf",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},		{		name = "WOODIE_BALANCED",		label = "Woodie",		hover = "Balance Woodie, the Lumberjack",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},	--[[{		name = "ZIM_BALANCED",		label = "Zim",		hover = "Balance Purswader's Zim",		options =	{						{description = "Balanced", data = 1},						{description = "Ignored", data = 0},					},		default = 1,	},]]}

 

And my GitHub

 

 

 

Problem is, at first my character would say that health did not exist on Tamamo, and throw a nil on modifyStats.

Next, it would say eat was also nil.

Then, it would work but crash soon after all the players in the server but the host.

 

Most of the time it worked for the host but no client ever. Every other character modification works for host and clients with no problems.

 

So then, we deleted EVERYTHING FROM THE BALANCE TAMAMO STATS FUNCTION, but this:

	modifyStats(inst, {    health = 125,    walkSpeed = 1,    runSpeed = 1,    damage = 1,		dapperness = 0,		hungerRate = 1,	})

 

And it would still crash. Would still say health is nil at the same line from modifystats where it tries to use it.

local hunger_percent = inst.components.hunger:GetPercent()

Or somewhere around there. Since honestly after 2 days of absolutely filling up Tamamo with **** I'm pretty lost as to what crashed where.

 

 

For comparison here's Endia's prefab code if anyone wants to look at it, since me changing stats about endia actually work:

local MakePlayerCharacter = require "prefabs/player_common"local assets = {        Asset( "ANIM", "anim/player_basic.zip" ),        Asset( "ANIM", "anim/player_idles_shiver.zip" ),        Asset( "ANIM", "anim/player_actions.zip" ),        Asset( "ANIM", "anim/player_actions_axe.zip" ),        Asset( "ANIM", "anim/player_actions_pickaxe.zip" ),        Asset( "ANIM", "anim/player_actions_shovel.zip" ),        Asset( "ANIM", "anim/player_actions_blowdart.zip" ),        Asset( "ANIM", "anim/player_actions_eat.zip" ),        Asset( "ANIM", "anim/player_actions_item.zip" ),        Asset( "ANIM", "anim/player_actions_uniqueitem.zip" ),        Asset( "ANIM", "anim/player_actions_bugnet.zip" ),        Asset( "ANIM", "anim/player_actions_fishing.zip" ),        Asset( "ANIM", "anim/player_actions_boomerang.zip" ),        Asset( "ANIM", "anim/player_bush_hat.zip" ),        Asset( "ANIM", "anim/player_attacks.zip" ),        Asset( "ANIM", "anim/player_idles.zip" ),        Asset( "ANIM", "anim/player_rebirth.zip" ),        Asset( "ANIM", "anim/player_jump.zip" ),        Asset( "ANIM", "anim/player_amulet_resurrect.zip" ),        Asset( "ANIM", "anim/player_teleport.zip" ),        Asset( "ANIM", "anim/wilson_fx.zip" ),        Asset( "ANIM", "anim/player_one_man_band.zip" ),        Asset( "ANIM", "anim/shadow_hands.zip" ),        Asset( "SOUND", "sound/sfx.fsb" ),        Asset( "SOUND", "sound/wilson.fsb" ),        Asset( "ANIM", "anim/beard.zip" ),		-- Don't forget to include your character's custom assets!        Asset( "ANIM", "anim/endia.zip" ),		Asset( "ANIM", "anim/ghost_endia_build.zip" ),}local prefabs = { "endiaamulet" }local start_inv = { "endiaamulet" }local friendly_tags = {"smallcreature", "animal", "pig", "berrythief"}local nonfriendly_tags = {"hostile", "killer", "frog", "mosquito"}local common_postinit = function(inst)	-- choose which sounds this character will play	inst.soundsname = "wendy"	-- a minimap icon must be specified	inst.MiniMapEntity:SetIcon( "endia.png" )	-- todo: Add an example special power here.end-- Sanity gain from friendly creatures (rabbits, birds, bees, beefalo, etc)local function sanityfn(inst)	local x,y,z = inst.Transform:GetWorldPosition()		local delta = 0	local max_rad = 10	local ents = TheSim:FindEntities(x,y,z, max_rad, nil, nonfriendly_tags, friendly_tags)    for k,v in pairs(ents) do 		local distsq = inst:GetDistanceSqToInst(v)		delta = delta + TUNING.SANITYAURA_TINY/math.max(1, distsq)    end    return math.min(delta, TUNING.SANITYAURA_TINY) + inst.components.sanity.rateend-- Flat burnrate reduction (not overwriting burnrate because certain items would reset it to 1)local function hungerfn(self, dt, ignore_damage)	local old = self.current	if self.burning then		if self.current <= 0 then			if not ignore_damage then				self.inst.components.health:DoDelta(-self.hurtrate*dt, true, "hunger")			end		else			self:DoDelta(math.max(0, self.burnrate-0.5)*(-self.hungerrate*dt), true)		end	endendlocal function onkilledother(inst, data)	if data ~= nil and data.victim ~= nil then		local isfriendly = false		local ishostile = false		for k,v in pairs(friendly_tags) do			if data.victim:HasTag(v) then				isfriendly = true				break			end		end				if isfriendly then			for k,v in pairs(nonfriendly_tags) do				if data.victim:HasTag(v) then					ishostile = true					break				end			end						if not ishostile then				-- killed a friendly creature, you should feel bad!				inst.components.sanity:DoDelta(-8)								if inst.components.talker ~= nil then					inst.components.talker:Say(GetString(inst, "ANNOUNCE_KILL_INNOCENT_CREATURE"))				end			end		end	endendlocal function OnAttackOther(inst, data)		if data.target ~= nil then		-- Birds AI don't really care about being hit so force them to fly away		if data.target:HasTag("bird") then			data.target:PushEvent("flyaway")		end				-- Turkey AI doesn't care about being attacked either, force them to panic		if data.target:HasTag("berrythief") and data.target.components.hauntable ~= nil then			data.target.components.hauntable:Panic()		end	end		endlocal master_postinit = function(inst)	-- Stats		inst.components.health:SetMaxHealth(200)	inst.components.hunger:SetMax(115)	inst.components.sanity:SetMax(75)			inst.components.hunger.DoDec = hungerfn		inst.components.sanity.custom_rate_fn = sanityfn	-- Rabbits dont run away	inst:RemoveTag("scarytoprey")		inst:ListenForEvent("killed", function(inst, data) onkilledother(inst, data) end)	inst:ListenForEvent("onattackother", OnAttackOther)endreturn MakePlayerCharacter("endia", prefabs, assets, common_postinit, master_postinit, start_inv)

 

 

So in the end, add a mode to tamamo with a function that can also be applied to other characters, which can modify stats in that mode or whatever about them, and also remove other things. It mostly seems to flip out on tamamo since it doesn't even recognize health as a thing that exists in this world, or eater, or anything really. Also the function according to a friend can't add more than one mode to one character, so if that changes that would be great too.

 

Also tried in the end making the mod not required on clients to see what happened. Everything worked, BUT TAMAMO!

 

So anyone that has the greater insights about everything, please. Im absolutely lost on this.

Link to comment
Share on other sites

Also the function according to a friend can't add more than one mode to one character, so if that changes that would be great too.

 

c0176335c6.png

 

to be politically correct

 

Thanks good guy saeldur for doing it in 5 minutes after being linked this post

 

 

EDIT: Also as a quick edit if anyone wants to fix a more minor problem, mod sometimes crashes when equipping or deequipping some mod character items like shovel knight's armor

Thought I kind of care less about that one.

 

EDIT: Found a couple of screenshots, this is when a friend joined as tamamo:

Tamamo ( also another one which is the same just me moving things around in the code )

Friend

I (host) didn't crash

Edited by DrSmugleaf
Link to comment
Share on other sites

Think I figured out the problem, any character with Ksizor's mode changing code simply won't work with changing or reading stats (gir, tamamo...), from an outside mod or from the own mod itself. Think the only way to fix it is to change the base mod so that instead of a key toggle it is some other kind of toggle.

 

Heres a bunch of crash logs for anyone that feels like continuing my effort, after 6 days of achieving nothing

http://pastebin.com/Vt7sFXc1

http://pastebin.com/rxEXNRJE

http://pastebin.com/xb4rVHDA

http://pastebin.com/z9Gf20d9

 

The hunger nil and such always happens clientside, never to the host. That will happen for any stat in my mod or the base mod as it will say that the thing exists, but that it is nil. Removing Ksizor's mode code solves it, but not exactly what I was looking for.

Edited by DrSmugleaf
Link to comment
Share on other sites

@DrSmugleaf, geez, thanks for tossing me under the bus there mate.

 

Based on the information you've provided; it seems that you are misunderstanding how to properly network the code. If you'd like some assistance hit me up on Steam (Ysovuka) and I will try to explain how it works and how to get yours to work with it.

 

Edit:

I put this code in my test mod and it worked flawlessly to adjust Tamamo's stats.

 

local function OnKeyPressed(inst, data)    if data.inst == ThePlayer then        if data.key == KEY_Z then            if TheWorld.ismastersim then                BufferedAction(inst, inst, ACTIONS.FERAL):Do()                -- Since we are the server, do the action on the server.            else                SendRPCToServer(RPC.DoWidgetButtonAction, ACTIONS.FERAL.code, inst, ACTIONS.FERAL.mod_name)            end        end    endendAddPrefabPostInit("tamamo", function(inst)    inst:ListenForEvent("keypressed", OnKeyPressed)		return instend)local FERAL = GLOBAL.Action()FERAL.str = "Feral"FERAL.id = "FERAL"FERAL.fn = function(act)    print("Feral action called.")    if act.target.transformed then        print("We're transformed.")        act.target.components.health:SetMaxHealth(250)        act.target.components.health:DoDelta(0)        print("Health: "..act.target.components.health.maxhealth)    else        print("We're not transformed.")        act.target.components.health:SetMaxHealth(1)        act.target.components.health:DoDelta(0)        print("Health: "..act.target.components.health.maxhealth)    end                        return trueend AddAction(FERAL)  

Edited by Kzisor
Link to comment
Share on other sites

@Kzisor, didn't mean to be rude, just a little tired of bashing my head against a wall for 6 days lol.

Will get in contact with you, probably tomorrow though as its already 3AM for me, but thanks for offering to help, I don't doubt I'm doing something wrong, but out of 4 friends and me none of us knew what was going wrong.

 

 

Also, did you try that code with someone joining the server? Because, yes, it works flawlessly for the host, but crashes anyone connecting that isnt the host. If you managed to make that work then I'm amazed and will make 10 mental notes to talk to you tomorrow.

Link to comment
Share on other sites

@Kzisor, didn't mean to be rude, just a little tired of bashing my head against a wall for 6 days lol.

Will get in contact with you, probably tomorrow though as its already 3AM for me, but thanks for offering to help, I don't doubt I'm doing something wrong, but out of 4 friends and me none of us knew what was going wrong.

 

 

Also, did you try that code with someone joining the server? Because, yes, it works flawlessly for the host, but crashes anyone connecting that isnt the host. If you managed to make that work then I'm amazed and will make 10 mental notes to talk to you tomorrow.

 

I used a dedicated server and joined as a client, so yes it worked flawlessly as a client without crashing.

Link to comment
Share on other sites

I used a dedicated server and joined as a client, so yes it worked flawlessly as a client without crashing.

Well if you managed to do that AND to make my mod (EDIT: by my mod I mean part of what it does) work on a dedicated server then we might as well start firing happiness fireworks right about now. You have permission to kill me if I forget to contact you tomorrow then.

 

(Though mod not working on dedicated servers was probably Kuldiin's fault)

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