Project Zomboid

Project Zomboid

Soul Filcher's Cooking Time
Kyomujin 12 Nov, 2021 @ 8:34am
Bugs and stuff
I didn't want to spam multiple posts, so I'm making this discussion page instead. Found a bunch more things in the process of looking into the idea of making my first mod for this game based around nutrition. More specifically calculating calories using atwater average kcal/g. I've looked over all the food items in this mod once now, mostly just nutrition but I also checked the recipes for some of them or lack thereof.

I can't find any recipe or spawn for: Lemonade, Toasts
I found no ingredients for evolvedRecipe: Jelly. Not yet implemented?

SFCookingGuide is missing the recipe for plain dough

Plain dough ends up with the age NaN. My best guess after messing around is that the game for some reason tries to pull the age of the ingredients and apply to the result in some way. Since none of the ingredients have an age it ends up as NaN. Adding salt to the recipe or I suspect any ingredient of the type "food" will provide a functional age. Feels more like a game bug than an error in this mod to me. The only workaround I found was to just add a OnCreate function setting the age to 0.
function Recipe.OnCreate.PlainBreadAgeFix(items, result, player) result:setAge(0); end

SFCornbreadBatter can't be cooked and no further refinement possible. Don't know if you wanted to cook it directly like BreadDough or use the baking tray. Vanilla bread is just confusing to me with multiple entries for bread dough.
SFBakingTrayCornbread can't be made, but it's set to give Base.Dough on cooked like Base.BakingTrayBread.

Taking a WaferStick doubles the hunger compared to the jar, the recipe should be "SFChocolateWaferSticksJarOpen;2,". The calories are also super low. Using atwater average numbers which, the game is usually close to, the jar is 1050kcal and individual wafers at 35kcal

Yeast recipe has a low yield of 1.36 (0.36 new) yeast per dough you age. Seems like a bit excessive waste of flour to get renewable yeast by using 2.75 units of Flour (0.6875 bags) per new yeast created.

PumpkinPieWholeRaw losses a lot of nutrition compared to its ingredients. A straight sum of the PiePrep and 25 units of pumpkin is carbs=192.13, proteins=19.5 lipids=50.8 calories=1364.

SFCupcakeBatter and the downstream items seem a bit low on calories. Instead of basing the nutrition on Cupcake I think it's better to base it on CakeBatter with 800 calories, though personally I'm not a fan of how using 2 flour to make bread is over 1k calories but only 800 in CakeBatter.

Spoonbread has too many carbs compared to calories. The game is mostly close to 4 calories per carb/protein, meaning less than 20 carbs is more reasonable.

"recipe Make Hotdog" could make at least 2 or 3 hotdogs considering input calories vs output calories, BreadSlices=170 (unless from partially eaten bread) SFSausage=150 Hotdog=100
"recipe Make Corndog" also a bit wasteful like with the hotdogs. 1/5 cornbatter=160 SFSausage=150 Corndog=180 making 2 per recipe makes more sense to me.
These two recipes could also be set to use SFSausage;5, BreadSlices;5, which also helps with avoiding weird min/max play of eating 3/4 of all ingredients before use

VegetableOil maybe more spawns e.g. *StoreKitchenBaking, *GigamartBakingMisc GigamartSauce GigamartBottles StoreKitchenSauce CounterKitchenSpiffo FridgeBottles.
*Seem the most fitting

A minor thing I would suggest is for your recipe code to follow the scheme of "Recipe.OnCreate.MakeBowlOfBeans2" to reduce clutter in the global lua namespace. Doesn't matter for a single mod, but it can accumulate and make lua code slower when it needs to use any global variable. A limitation of the kahlua lua implementation in java makes it much slower at using globals than pure lua and penalty grows as the global namespace grows.

SFDrinkBase function is faulty and just gives half the calories of what the ingredient has after use and no calories if the bottle is used up. I tried fixing the function, but it's still a bit hacky when you use up the last bit of the bottle.

Here's my suggested improvement for drinkbase code. instead of the Default table it would be nicer if one could just do a lookup of the all the base values and just always work from base values instead of current stats. Feels like that would be the best tradeoff, but I don't really know how one would go about finding those values. Last time I tried to get caloric data on a fooditem by name I couldn't figure it out. Note that I also switched out from SFBeer to vanilla beer and merged all the drinkbase functions.
local function DrinkInitStats(item, result) local hungerUsed = -0.04; local defaults = { --if missing predefined stats assume close to beer Default = { hunger = hungerUsed, boredom = 0, unhappy = -2, thirst = -0.04, calories = 100, carbs = 20, proteins = 0, lipids = 0, }, WhiskeyFull = { hunger = hungerUsed, boredom = 0, unhappy = -2, thirst = -0.04, calories = 300, carbs = 0, proteins = 0, lipids = 0, }, Wine = { hunger = hungerUsed, boredom = 0, unhappy = -4, thirst = -0.04, calories = 96.2, carbs = 0, proteins = 0, lipids = 0, }, Wine2 = { hunger = hungerUsed, boredom = 0, unhappy = -4, thirst = -0.04, calories = 102, carbs = 0, proteins = 0, lipids = 0, }, BeerBottle = { hunger = hungerUsed, boredom = 0, unhappy = -7.11, thirst = -0.0577, calories = 75.55, carbs = 17.33, proteins = 0, lipids = 0, }, BeerCan = { hunger = hungerUsed, boredom = 0, unhappy = -7.5, thirst = -0.065, calories = 80, carbs = 19.5, proteins = 0, lipids = 0, }, } -- local useFrac = item:getHungerChange() / hungerUsed; local itemBaseHunger = item:getBaseHunger() local itemHungerChange = item:getHungerChange() local useFracPrev = (itemHungerChange+hungerUsed) / hungerUsed; if useFracPrev > itemBaseHunger / hungerUsed then useFracPrev = itemBaseHunger / hungerUsed end local useFrac = itemHungerChange / hungerUsed if itemHungerChange == 0 then --getHungerChange, Calories and such return values after the ingredient has been used in recipe --Meaning once hunger reaches 0, the calories and such is also set to 0 and predefines values are needed if defaults[item:getType()] then local default = defaults[item:getType()] else local default = defaults.Default end result:setBaseHunger(hungerUsed); result:setHungChange(default.hunger) result:setBoredomChange(default.boredom) result:setUnhappyChange(item:getUnhappyChange()) result:setThirstChange(default.thirst) result:setCalories(default.calories) result:setCarbohydrates(default.carbs) result:setProteins(default.proteins) result:setLipids(default.lipids) else result:setBaseHunger(hungerUsed) result:setHungChange(itemHungerChange / useFrac) result:setBoredomChange(item:getBoredomChange() / useFrac) local drinkUnhappyChange = item:getUnhappyChange() / useFracPrev result:setUnhappyChange(drinkUnhappyChange) --unhappy change in the ingredient must be reduced or it remains at the base value if itemHungerChange+hungerUsed < itemBaseHunger then -- < because negative -- being here means we are using less than hungerUsed from this item item:setUnhappyChange(item:getUnhappyChange() - drinkUnhappyChange * (itemBaseHunger-itemHungerChange)/hungerUsed ) else if item:getUnhappyChange() ~= 0 then item:setUnhappyChange(item:getUnhappyChange() - drinkUnhappyChange) end end result:setThirstChange(item:getThirstChange() / useFrac) result:setCalories(item:getCalories() / useFrac) result:setCarbohydrates(item:getCarbohydrates() / useFrac) result:setProteins(item:getProteins() / useFrac) result:setLipids(item:getLipids() / useFrac) end end function Recipe.OnCreate.SFDrinkBase(items, result, player) local drinkTable = { BeerBottle = "ContextMenu_Glass_of_Beer", BeerCan = "ContextMenu_Glass_of_Beer", Wine = "ContextMenu_Glass_of_Wine", Wine2 = "ContextMenu_Glass_of_Wine2", WhiskeyFull = "ContextMenu_Glass_of_Whiskey", } for i=0,items:size() - 1 do local item = items:get(i) if drinkTable[item:getType()] then --sets stats like hunger, calories, ... DrinkInitStats(item, result) result:setName(getText(drinkTable[item:getType()])) end end end
< >
Showing 1-4 of 4 comments
UberFubarius 20 Sep, 2022 @ 12:55pm 
Found a bug.
recipe Slice Bread was looking for SFPlainBread, which doesn't exist and probably should've been SFPlainBreadCooked
dtoxic 4 Dec, 2022 @ 12:33pm 
Latest update got these errors

function: Pasta -- file: SFCook_Recipes.lua line # 209 | MOD: Soul Filcher's Cooking Time

LOG : General , 1670185784092> Object tried to call nil in Pasta
LOG : General , 1670185784226> creating new sourcewindow: E:/Games HDD/PZ_Test/Saves/mods/CookingTime/media/lua/server/Cooking/SFCook_Recipes.lua
ERROR: General , 1670185794422> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: Object tried to call nil in Pasta at KahluaUtil.fail line:82.
ERROR: General , 1670185794422> DebugLogStream.printException> Stack trace:
java.lang.RuntimeException: Object tried to call nil in Pasta
at se.krka.kahlua.vm.KahluaUtil.fail(KahluaUtil.java:82)
at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:973)
at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163)
at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980)
at se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1827)
at se.krka.kahlua.integration.LuaCaller.protectedCallVoid(LuaCaller.java:122)
at zombie.inventory.RecipeManager.LoadedAfterLua(RecipeManager.java:166)
at zombie.inventory.RecipeManager.LoadedAfterLua(RecipeManager.java:133)
at zombie.inventory.RecipeManager.LoadedAfterLua(RecipeManager.java:119)
at zombie.gameStates.GameLoadingState.enter(GameLoadingState.java:103)
at zombie.gameStates.GameStateMachine.update(GameStateMachine.java:145)
at zombie.GameWindow.logic(GameWindow.java:298)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.GameWindow.frameStep(GameWindow.java:765)
at zombie.GameWindow.run_ez(GameWindow.java:681)
at zombie.GameWindow.mainThread(GameWindow.java:495)
at java.base/java.lang.Thread.run(Unknown Source)
LOG : General , 1670185794423> -----------------------------------------
STACK TRACE
-----------------------------------------
function: Pasta -- file: SFCook_Recipes.lua line # 209 | MOD: Soul Filcher's Cooking Time

LOG : General , 1670185794423>
LOG : General , 1670185795894> -----------------------------------------
STACK TRACE
-----------------------------------------
function: Pasta -- file: SFCook_Recipes.lua line # 209 | MOD: Soul Filcher's Cooking Time

LOG : General , 1670185795894> Object tried to call nil in Pasta
ERROR: General , 1670185799977> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: Object tried to call nil in Pasta at KahluaUtil.fail line:82.
ERROR: General , 1670185799977> DebugLogStream.printException> Stack trace:
java.lang.RuntimeException: Object tried to call nil in Pasta
at se.krka.kahlua.vm.KahluaUtil.fail(KahluaUtil.java:82)
at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:973)
at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163)
at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980)
at se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1827)
at se.krka.kahlua.integration.LuaCaller.protectedCallVoid(LuaCaller.java:122)
at zombie.inventory.RecipeManager.LoadedAfterLua(RecipeManager.java:166)
at zombie.inventory.RecipeManager.LoadedAfterLua(RecipeManager.java:133)
at zombie.inventory.RecipeManager.LoadedAfterLua(RecipeManager.java:119)
at zombie.gameStates.GameLoadingState.enter(GameLoadingState.java:103)
at zombie.gameStates.GameStateMachine.update(GameStateMachine.java:145)
at zombie.GameWindow.logic(GameWindow.java:298)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.GameWindow.frameStep(GameWindow.java:765)
at zombie.GameWindow.run_ez(GameWindow.java:681)
at zombie.GameWindow.mainThread(GameWindow.java:495)
at java.base/java.lang.Thread.run(Unknown Source)
LOG : General , 1670185799978> -----------------------------------------
STACK TRACE
-----------------------------------------
function: Pasta -- file: SFCook_Recipes.lua line # 209 | MOD: Soul Filcher's Cooking Time

LOG : General , 1670185799978>
ERROR: General , 1670185801318> LuaManager.getFunctionObject> no such function "TPaste_FlossMedHigh"
ERROR: General , 1670185801318> RecipeManager.LoadedAfterLua> no such function LuaCreate = "TPaste_FlossMedHigh" in recipe "Use Mouthwash"
ERROR: General , 1670185801321> LuaManager.getFunctionObject> no such function "Recipe.OnGiveXP.None
Sound"
ERROR: General , 1670185801321> RecipeManager.LoadedAfterLua> no such function LuaGiveXP = "Recipe.OnGiveXP.None
Sound" in recipe "Grind Coffee Beans"
ERROR: General , 1670185801324> LuaManager.getFunctionObject> no such function "Recipe.OnGiveXP.Give20MechanicsXP"
ERROR: General , 1670185801324> RecipeManager.LoadedAfterLua> no such function LuaGiveXP = "Recipe.OnGiveXP.Give20MechanicsXP" in recipe "Make Spare Engine Parts"
ERROR: General , 1670185801324> LuaManager.getFunctionObject> no such function "Recipe.OnGiveXP.Give20MechanicsXP"
ERROR: General , 1670185801324> RecipeManager.LoadedAfterLua> no such function LuaGiveXP = "Recipe.OnGiveXP.Give20MechanicsXP" in recipe "Make Spare Engine Parts"
ERROR: General , 1670185801324> LuaManager.getFunctionObject> no such function "Recipe.OnGiveXP.Give10MechanicsXP"
ERROR: General , 1670185801325> RecipeManager.LoadedAfterLua> no such function LuaGiveXP = "Recipe.OnGiveXP.Give10MechanicsXP" in recipe "Make Spare Engine Parts"
ERROR: General , 1670185801332> LuaManager.getFunctionObject> no such function "MBAODismantletapedArrowAddon_OnCreate"
ERROR: General , 1670185801332> RecipeManager.LoadedAfterLua> no such function LuaCreate = "MBAODismantletapedArrowAddon_OnCreate" in recipe "Take Stone Arrow Apart"
ERROR: General , 1670185801332> LuaManager.getFunctionObject> no such function "MBAOtapeArrowAddon_OnCreate"
ERROR: General , 1670185801332> RecipeManager.LoadedAfterLua> no such function LuaCreate = "MBAOtapeArrowAddon_OnCreate" in recipe "Make Stone Arrow"
ERROR: General , 1670185801332> LuaManager.getFunctionObject> no such function "MBAOtapeArrowAddon_OnCreate"
ERROR: General , 1670185801332> RecipeManager.LoadedAfterLua> no such function LuaCreate = "MBAOtapeArrowAddon_OnCreate" in recipe "Convert Stone Arrowhead"
ERROR: General , 1670185801335> LuaManager.getFunctionObject> no such function "BSNewItem_OnCreate"
ERROR: General , 1670185801336> RecipeManager.LoadedAfterLua> no such function LuaCreate = "BSNewItem_OnCreate" in recipe "Make Chisel"
LOG : General , 1670185801337> -----------------------------------------
STACK TRACE
-----------------------------------------
function: Beans -- file: SFCook_Recipes.lua line # 201 | MOD: Soul Filcher's Cooking Time

LOG : General , 1670185801337> Object tried to call nil in Beans
ERROR: General , 1670185803605> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: Object tried to call nil in Beans at KahluaUtil.fail line:82.
ERROR: General , 1670185803605> DebugLogStream.printException> Stack trace:
java.lang.RuntimeException: Object tried to call nil in Beans
at se.krka.kahlua.vm.KahluaUtil.fail(KahluaUtil.java:82)
at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:973)
at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163)
at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980)
at se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1827)
at se.krka.kahlua.integration.LuaCaller.protectedCallVoid(LuaCaller.java:122)
at zombie.inventory.RecipeManager.LoadedAfterLua(RecipeManager.java:166)
at zombie.inventory.RecipeManager.LoadedAfterLua(RecipeManager.java:133)
at zombie.inventory.RecipeManager.LoadedAfterLua(RecipeManager.java:119)
at zombie.gameStates.GameLoadingState.enter(GameLoadingState.java:103)
at zombie.gameStates.GameStateMachine.update(GameStateMachine.java:145)
at zombie.GameWindow.logic(GameWindow.java:298)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.GameWindow.frameStep(GameWindow.java:765)
at zombie.GameWindow.run_ez(GameWindow.java:681)
at zombie.GameWindow.mainThread(GameWindow.java:495)
at java.base/java.lang.Thread.run(Unknown Source)
LOG : General , 1670185803606> -----------------------------------------
STACK TRACE
-----------------------------------------
function: Beans -- file: SFCook_Recipes.lua line # 201 | MOD: Soul Filcher's Cooking Time
dtoxic 7 Dec, 2022 @ 9:47am 
Thx for the update but now right clicking on any item throws an error
CrankerX 7 Dec, 2022 @ 3:06pm 
I am getting error when right clicking anything also.

I get this error 2400 times on game loading.
The error after this one is when rightclicking

STACK TRACE
-----------------------------------------
Callframe at: getEvolvedRecipe
function: populateRecipesList -- file: ISCraftingUI.lua line # 1182 | Vanilla
function: createChildren -- file: ISCraftingUI.lua line # 969 | Vanilla
function: instantiate -- file: ISUIElement.lua line # 653 | Vanilla
function: addToUIManager -- file: ISUIElement.lua line # 1009 | Vanilla
function: createInventoryInterface -- file: ISPlayerDataObject.lua line # 157 | Vanilla
function: createPlayerData -- file: ISPlayerData.lua line # 187 | Vanilla

ERROR: General , 1670451542291> ExceptionLogger.logException> Exception thrown java.lang.reflect.InvocationTargetException at NativeMethodAccessorImpl.invoke0 (Native Method).
ERROR: General , 1670451542291> DebugLogStream.printException> Stack trace:
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at se.krka.kahlua.integration.expose.caller.MethodCaller.call(MethodCaller.java:62)
at se.krka.kahlua.integration.expose.LuaJavaInvoker.call(LuaJavaInvoker.java:198)
at se.krka.kahlua.integration.expose.LuaJavaInvoker.call(LuaJavaInvoker.java:188)
at se.krka.kahlua.vm.KahluaThread.callJava(KahluaThread.java:182)
at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:1007)
at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163)
at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980)
at se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1812)
at se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:66)
at se.krka.kahlua.integration.LuaCaller.protectedCallVoid(LuaCaller.java:139)
at zombie.Lua.Event.trigger(Event.java:64)
at zombie.Lua.LuaEventManager.triggerEvent(LuaEventManager.java:134)
at zombie.gameStates.GameLoadingState.exit(GameLoadingState.java:405)
at zombie.gameStates.GameStateMachine.update(GameStateMachine.java:105)
at zombie.GameWindow.logic(GameWindow.java:298)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.GameWindow.frameStep(GameWindow.java:765)
at zombie.GameWindow.run_ez(GameWindow.java:667)
at zombie.GameWindow.mainThread(GameWindow.java:495)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException: Cannot invoke "String.contains(java.lang.CharSequence)" because "this.resultItem" is null
at zombie.scripting.objects.EvolvedRecipe.getResultItem(EvolvedRecipe.java:558)
at zombie.inventory.RecipeManager.getEvolvedRecipe(RecipeManager.java:1512)
... 24 more


STACK TRACE
-----------------------------------------
Callframe at: getEvolvedRecipe
function: createMenu -- file: ISInventoryPaneContextMenu.lua line # 236 | Vanilla
function: onRightMouseUp -- file: ISInventoryPane.lua line # 1444 | Vanilla

ERROR: General , 1670451713070> ExceptionLogger.logException> Exception thrown java.lang.reflect.InvocationTargetException at GeneratedMethodAccessor463.invoke.
ERROR: General , 1670451713070> DebugLogStream.printException> Stack trace:
java.lang.reflect.InvocationTargetException
at jdk.internal.reflect.GeneratedMethodAccessor463.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at se.krka.kahlua.integration.expose.caller.MethodCaller.call(MethodCaller.java:62)
at se.krka.kahlua.integration.expose.LuaJavaInvoker.call(LuaJavaInvoker.java:198)
at se.krka.kahlua.integration.expose.LuaJavaInvoker.call(LuaJavaInvoker.java:188)
at se.krka.kahlua.vm.KahluaThread.callJava(KahluaThread.java:182)
at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:1007)
at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163)
at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980)
at se.krka.kahlua.vm.KahluaThread.pcallBoolean(KahluaThread.java:1924)
at se.krka.kahlua.integration.LuaCaller.protectedCallBoolean(LuaCaller.java:104)
at zombie.ui.UIElement.onRightMouseUp(UIElement.java:1458)
at zombie.ui.UIElement.onRightMouseUp(UIElement.java:1416)
at zombie.ui.UIManager.update(UIManager.java:910)
at zombie.GameWindow.logic(GameWindow.java:262)
at zombie.core.profiling.AbstractPerformanceProfileProbe.invokeAndMeasure(AbstractPerformanceProfileProbe.java:71)
at zombie.GameWindow.frameStep(GameWindow.java:765)
at zombie.GameWindow.run_ez(GameWindow.java:667)
at zombie.GameWindow.mainThread(GameWindow.java:495)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException: Cannot invoke "String.contains(java.lang.CharSequence)" because "this.resultItem" is null
at zombie.scripting.objects.EvolvedRecipe.getResultItem(EvolvedRecipe.java:558)
at zombie.inventory.RecipeManager.getEvolvedRecipe(RecipeManager.java:1512)
... 21 more
LOG : General , 1670451713070> Test Item: Plasticbag
LOG : General , 1670451713070> Test Item: nil
LOG : General , 1670451727803> -----------------------------------------
< >
Showing 1-4 of 4 comments
Per page: 1530 50