D4rkh0bb1T Posted March 28, 2016 Share Posted March 28, 2016 (edited) Hello modders community! I've been working on a Light Potion and decided to add some configuration to it in the modinfo so I can choose the light color! I attempted to call in my prefab the data chosen on the config option screen. The problem is that the game do not pick the data from the modinfo and the light on the character remains unchanged, very normal. I saw this threat on the forum and tried to put what is proposed but it is not working. I just want to add several configuration options in my lightpotion.lua so the color fits the choice made in the configuration options. I will show you what's in my modinfo, in the top of my modmain and what's in the prefab so far, followed with the crash log. Ask anything if u need! Modinfo : Spoiler name = Ada-Hadabra --GetModConfigData : USE NAME FOLDER INSTEAD!!! configuration_options = { { name = "LIGHTCOLOR", label = "Potion Light Color", options = { {description = "Red", data = "Red"}, {description = "Blue", data = "Blue"}, {description = "Green", data = "Green"}, {description = "Purple", data = "Purple"}, {description = "Orange", data = "Orange"}, {description = "Yellow", data = "Yellow"}, {description = "White", data = "White"}, }, default = "Red", }, } Modmain : Spoiler --I Really Don't Know What Should Be Here, But Not Crash... GLOBAL.package.loaded["korrigan.modenv"] = env GLOBAL.Red = (GetModConfigData("LIGHTCOLOR")=="Red") GLOBAL.Blue = (GetModConfigData("LIGHTCOLOR")=="Blue") GLOBAL.Green = (GetModConfigData("LIGHTCOLOR")=="Green") GLOBAL.Purple = (GetModConfigData("LIGHTCOLOR")=="Purple") GLOBAL.Orange = (GetModConfigData("LIGHTCOLOR")=="Orange") GLOBAL.Yellow = (GetModConfigData("LIGHTCOLOR")=="Yellow") GLOBAL.White = (GetModConfigData("LIGHTCOLOR")=="White") Lightpotion.lua : Spoiler local name = "korrigan" --This is the mod folder name, not the one in modinfo!!! local folder = KnownModIndex:GetModActualName(name) local foldername = KnownModIndex:GetModActualName("korrigan") --This is the mod folder name!!! local LIGHTCOLOR=GetModConfigData("LIGHTCOLOR", folder) local modenv = require "korrigan.modenv" --As Told By Simplex local Red = GetModConfigData("LIGHTCOLOR", foldername) --Not Sure local Red = modenv.GetModConfigData("LIGHTCOLOR") --Not Sure ----Tested, Not Working --local Red=ModIndex:GetModActualName(name) --local Blue=ModIndex:GetModActualName(name) --local Green=ModIndex:GetModActualName(name) --local Purple=ModIndex:GetModActualName(name) --local Orange=ModIndex:GetModActualName(name) --local Yellow=ModIndex:GetModActualName(name) --local White=ModIndex:GetModActualName(name) local intens = 0.75 local potiontime = 105 local breakcounter = 0 local assets= { Asset("ANIM", "anim/lightpotion.zip"), Asset("ATLAS", "images/inventoryimages/lightpotion.xml"), Asset("IMAGE", "images/inventoryimages/lightpotion.tex"), } PrefabFiles = { "lightpotion", } local function reduce1(inst) --Works if breakcounter > 1 then else intens = 0.5 inst.Light:SetIntensity(intens) end end local function reduce2(inst) --Works if breakcounter > 1 then else intens = 0.25 inst.Light:SetIntensity(intens) end inst.components.talker:Say("Light is reducing!", 4) --Hard To Make It Works (Talker nil value...) end local function reduce3(inst) --Works if breakcounter > 1 then breakcounter = breakcounter - 1 else intens = 0 inst.Light:SetIntensity(intens) inst.Light:Enable(false) print "Light off" breakcounter = breakcounter - 1 end inst.components.talker:Say("Light has gone...", 4) --Hard To Make It Works (Talker nil value...) end local function oneaten(inst, eater) addlight(eater) --It MUST Work eater:DoTaskInTime(potiontime-80, reduce1) --Works eater:DoTaskInTime(potiontime-40, reduce2) --Works eater:DoTaskInTime(potiontime-1, reduce3) --Works eater.components.talker:Say("Let there be light!", 4) --Works end local function addlight(eater) --It MUST Work if inst.Light then else inst.entity:AddLight() print "new light :(" end intens = 0.75 -- breakcounter = breakcounter + 1 print (breakcounter) -- if Red then inst.Light:Enable(true) inst.Light:SetRadius(2) inst.Light:SetFalloff(.8) inst.Light:SetIntensity(intens) inst.Light:SetColour(255/255,0,0) else if Blue then inst.Light:Enable(true) inst.Light:SetRadius(2) inst.Light:SetFalloff(.8) inst.Light:SetIntensity(intens) inst.Light:SetColour(0,0,255/255) else if Green then inst.Light:Enable(true) inst.Light:SetRadius(2) inst.Light:SetFalloff(.8) inst.Light:SetIntensity(intens) inst.Light:SetColour(0,255/255,0) else if Purple then inst.Light:Enable(true) inst.Light:SetRadius(2) inst.Light:SetFalloff(.8) inst.Light:SetIntensity(intens) inst.Light:SetColour(153/255,0,153) else if Orange then inst.Light:Enable(true) inst.Light:SetRadius(2) inst.Light:SetFalloff(.8) inst.Light:SetIntensity(intens) inst.Light:SetColour(255/255,128/255,0) else if Yellow then inst.Light:Enable(true) inst.Light:SetRadius(2) inst.Light:SetFalloff(.8) inst.Light:SetIntensity(intens) inst.Light:SetColour(255/255,255/255,0) else if White then inst.Light:Enable(true) inst.Light:SetRadius(2) inst.Light:SetFalloff(.8) inst.Light:SetIntensity(intens) inst.Light:SetColour(255/255,255/255,255/255) end end end end end end end end Crash log : Spoiler [00:01:17]: [string "scripts/modutil.lua"]:13: modname must be supplied manually if calling GetModConfigData from outside of modmain or modworldgenmain. Use ModIndex:GetModActualName(fancyname) function [fancyname is name string from modinfo]. LUA ERROR stack traceback: =[C] in function 'assert' scripts/modutil.lua(13,1) in function 'GetModConfigData' ../mods/korrigan/scripts/prefabs/lightpotion.lua(4,1) in function 'fn' scripts/mainfunctions.lua(95,1) =(tail call) ? =[C] in function 'xpcall' scripts/mods.lua(123,1) scripts/mods.lua(494,1) in function 'RegisterPrefabs' scripts/gamelogic.lua(206,1) in function 'LoadAssets' scripts/gamelogic.lua(772,1) =[C] in function 'SetPersistentString' scripts/saveindex.lua(70,1) in function 'Save' scripts/saveindex.lua(294,1) =[C] in function 'SerializeWorldSession' scripts/networking.lua(209,1) in function 'SerializeWorldSession' scripts/saveindex.lua(297,1) in function 'OnGenerateNewWorld' scripts/gamelogic.lua(783,1) in function 'cb' scripts/screens/worldgenscreen.lua(171,1) in function 'OnUpdate' scripts/frontend.lua(597,1) in function 'Update' scripts/update.lua(94,1) There is something wrong in modmain/prefab but I can't figure what it is. I tried different schemes, without luck. Red only is written for testing purpose. Any help would be really appreciated, I'm sure I almost got it worked! Note : Potions are stackable. I tried to put the addlight(eater) function in the oneaten function, which worked. But, when dropping the potions on the ground, the character loses its light! The light entity was hold by the potions, not the character! D4rkh0bb1T Edited March 28, 2016 by D4rkh0bb1T Link to comment Share on other sites More sharing options...
Muche Posted March 28, 2016 Share Posted March 28, 2016 (edited) GetModConfigData function that is available in modmain is defined in modutil|InsertPostInitFunctions() as follows: env.GetModConfigData = function( optionname, get_local_config ) initprint("GetModConfigData", optionname, get_local_config) return GetModConfigData(optionname, env.modname, get_local_config) end it calls the global GetModConfigData() with the modname parameter equal to the name of the current mod. Thus if you want to use GetModConfigData() outside of modmain you have to specify mod name you are trying to access: GetModConfigData("LIGHTCOLOR", "<your_temporary_dev_folder_name>") , but GetModConfigData("LIGHTCOLOR", "workshop-<your_mod's_id>") for uploaded version. If you want to specify the name of the mod instead of its id, you can use modindex's translation service: local modnameFancy = "Ada-Hadabra" local modnameActual = KnownModIndex:GetModActualName(modnameFancy) local optcolor if modnameActual == nil then print(string.format("Mod '%s' not found", modnameFancy)) optcolor = "Red" else optcolor = GetModConfigData("LIGHTCOLOR", modnameActual) end You can also store the value in GLOBAL, just make sure the probability of the clash with other mod is low enough; something like -- modmain: GLOBAL.global("mods") if GLOBAL.mods == nil then GLOBAL.mods = {} end GLOBAL.assert(type(GLOBAL.mods) == "table", string.format("Type of GLOBAL.mods is %s, expected table; caused most probably by incompatibility between mods.", type(GLOBAL.mods))) GLOBAL.assert(GLOBAL.mods.AdaHadabra == nil, string.format("GLOBAL.mods.AdaHadabra is %s, expected nil; caused most probably by incompatibility between mods.", tostring(GLOBAL.mods.AdaHadabra))) GLOBAL.mods.AdaHadabra = {} GLOBAL.mods.AdaHadabra.LIGHTCOLOR = GetModConfigData("LIGHTCOLOR") -- prefab: local optcolor = mods.AdaHadabra.LIGHTCOLOR Edited March 28, 2016 by Muche Link to comment Share on other sites More sharing options...
D4rkh0bb1T Posted March 28, 2016 Author Share Posted March 28, 2016 (edited) 2 hours ago, Muche said: Thus if you want to use GetModConfigData() outside of modmain you have to specify mod name you are trying to access: GetModConfigData("LIGHTCOLOR", "<your_temporary_dev_folder_name>") , but GetModConfigData("LIGHTCOLOR", "workshop-<your_mod's_id>") for uploaded version. If you want to specify the name of the mod instead of its id, you can use modindex's translation service: local modnameFancy = "Ada-Hadabra" local modnameActual = KnownModIndex:GetModActualName(modnameFancy) local optcolor if modnameActual == nil then print(string.format("Mod '%s' not found", modnameFancy)) optcolor = "Red" else optcolor = GetModConfigData("LIGHTCOLOR", modnameActual) end I put these lines in lightpotion at the top. But how do I call optcolor? Then I also added local optcolor = mods.AdaHadabra.LIGHTCOLOR just below, the headline prefab looks like this : Spoiler local name = "korrigan" local folder = KnownModIndex:GetModActualName(name) local foldername = KnownModIndex:GetModActualName("korrigan") local modenv = require "korrigan.modenv" local Red = modenv.GetModConfigData("LIGHTCOLOR") GetModConfigData("LIGHTCOLOR", "korrigan") --To be sure local modnameFancy = "Ada-Hadabra" local modnameActual = KnownModIndex:GetModActualName(modnameFancy) local optcolor if modnameActual == nil then print(string.format("Mod '%s' not found", modnameFancy)) optcolor = "Red" else optcolor = GetModConfigData("LIGHTCOLOR", modnameActual) end local optcolor = mods.AdaHadabra.LIGHTCOLOR local intens = 0.75 local potiontime = 105 local breakcounter = 0 --Code below, just like the first post 2 hours ago, Muche said: You can also store the value in GLOBAL, just make sure the probability of the clash with other mod is low enough; something like -- modmain: GLOBAL.global("mods") if GLOBAL.mods == nil then GLOBAL.mods = {} end GLOBAL.assert(type(GLOBAL.mods) == "table", string.format("Type of GLOBAL.mods is %s, expected table; caused most probably by incompatibility between mods.", type(GLOBAL.mods))) GLOBAL.assert(GLOBAL.mods.AdaHadabra == nil, string.format("GLOBAL.mods.AdaHadabra is %s, expected nil; caused most probably by incompatibility between mods.", tostring(GLOBAL.mods.AdaHadabra))) GLOBAL.mods.AdaHadabra = {} GLOBAL.mods.AdaHadabra.LIGHTCOLOR = GetModConfigData("LIGHTCOLOR") -- prefab: local optcolor = mods.AdaHadabra.LIGHTCOLOR With this code, my modmain headline looks like this now : Spoiler --Headlines local STRINGS = GLOBAL.STRINGS local Ingredient = GLOBAL.Ingredient local RECIPETABS = GLOBAL.RECIPETABS local TECH = GLOBAL.TECH local require = GLOBAL.require GLOBAL.global("mods") if GLOBAL.mods == nil then GLOBAL.mods = {} end GLOBAL.assert(type(GLOBAL.mods) == "table", string.format("Type of GLOBAL.mods is %s, expected table; caused most probably by incompatibility between mods.", type(GLOBAL.mods))) GLOBAL.assert(GLOBAL.mods.AdaHadabra == nil, string.format("GLOBAL.mods.AdaHadabra is %s, expected nil; caused most probably by incompatibility between mods.", tostring(GLOBAL.mods.AdaHadabra))) GLOBAL.mods.AdaHadabra = {} GLOBAL.mods.AdaHadabra.LIGHTCOLOR = GetModConfigData("LIGHTCOLOR") GLOBAL.package.loaded["korrigan.modenv"] = env GLOBAL.Red = (GetModConfigData("LIGHTCOLOR")=="Red") GLOBAL.Blue = (GetModConfigData("LIGHTCOLOR")=="Blue") GLOBAL.Green = (GetModConfigData("LIGHTCOLOR")=="Green") GLOBAL.Purple = (GetModConfigData("LIGHTCOLOR")=="Purple") GLOBAL.Orange = (GetModConfigData("LIGHTCOLOR")=="Orange") GLOBAL.Yellow = (GetModConfigData("LIGHTCOLOR")=="Yellow") GLOBAL.White = (GetModConfigData("LIGHTCOLOR")=="White") I have no crash, but the color remains the same, unchanged. Beside, what could cause the mod to clash with other mod? D4rkh0bb1T Edited March 28, 2016 by D4rkh0bb1T Link to comment Share on other sites More sharing options...
Muche Posted March 28, 2016 Share Posted March 28, 2016 (edited) The thing is, you need only one of those options. So 1) either with the GetModConfigData: Spoiler -- -- modmain -- --Headlines local STRINGS = GLOBAL.STRINGS local Ingredient = GLOBAL.Ingredient local RECIPETABS = GLOBAL.RECIPETABS local TECH = GLOBAL.TECH local require = GLOBAL.require -- -- prefab -- local modnameFancy = "Ada-Hadabra" local modnameActual = KnownModIndex:GetModActualName(modnameFancy) local optcolor if modnameActual == nil then print(string.format("Mod '%s' not found", modnameFancy)) optcolor = "Red" else optcolor = GetModConfigData("LIGHTCOLOR", modnameActual) end local colors = { Red = {0, 0, 255/255}, Green = {0, 255/255, 0}, Purple = {153/255, 0, 153/255}, Orange = {255/255, 128/255, 0}, Yellow = {255/255, 255/255, 0}, White = {255/255, 255/255, 255/255} } local intens = 0.75 local potiontime = 105 local breakcounter = 0 local assets= { Asset("ANIM", "anim/lightpotion.zip"), Asset("ATLAS", "images/inventoryimages/lightpotion.xml"), Asset("IMAGE", "images/inventoryimages/lightpotion.tex"), } PrefabFiles = { "lightpotion", } local function reduce1(inst) --Works if breakcounter > 1 then else intens = 0.5 inst.Light:SetIntensity(intens) end end local function reduce2(inst) --Works if breakcounter > 1 then else intens = 0.25 inst.Light:SetIntensity(intens) end inst.components.talker:Say("Light is reducing!", 4) --Hard To Make It Works (Talker nil value...) end local function reduce3(inst) --Works if breakcounter > 1 then breakcounter = breakcounter - 1 else intens = 0 inst.Light:SetIntensity(intens) inst.Light:Enable(false) print "Light off" breakcounter = breakcounter - 1 end inst.components.talker:Say("Light has gone...", 4) --Hard To Make It Works (Talker nil value...) end local function oneaten(inst, eater) addlight(eater) --It MUST Work eater:DoTaskInTime(potiontime-80, reduce1) --Works eater:DoTaskInTime(potiontime-40, reduce2) --Works eater:DoTaskInTime(potiontime-1, reduce3) --Works eater.components.talker:Say("Let there be light!", 4) --Works end local function addlight(eater) --It MUST Work if inst.Light then else inst.entity:AddLight() print "new light :(" end intens = 0.75 -- breakcounter = breakcounter + 1 print (breakcounter) -- inst.Light:Enable(true) inst.Light:SetRadius(2) inst.Light:SetFalloff(.8) inst.Light:SetIntensity(intens) inst.Light:SetColour(unpack(colors[optcolor])) end or 2) storing it in GLOBAL: Spoiler -- -- modmain -- --Headlines local STRINGS = GLOBAL.STRINGS local Ingredient = GLOBAL.Ingredient local RECIPETABS = GLOBAL.RECIPETABS local TECH = GLOBAL.TECH local require = GLOBAL.require GLOBAL.global("mods") if GLOBAL.mods == nil then GLOBAL.mods = {} end GLOBAL.assert(type(GLOBAL.mods) == "table", string.format("Type of GLOBAL.mods is %s, expected table; caused most probably by incompatibility between mods.", type(GLOBAL.mods))) GLOBAL.assert(GLOBAL.mods.AdaHadabra == nil, string.format("GLOBAL.mods.AdaHadabra is %s, expected nil; caused most probably by incompatibility between mods.", tostring(GLOBAL.mods.AdaHadabra))) GLOBAL.mods.AdaHadabra = {} GLOBAL.mods.AdaHadabra.LIGHTCOLOR = GetModConfigData("LIGHTCOLOR") -- -- prefab -- local optcolor = mods.AdaHadabra.LIGHTCOLOR local colors = { Red = {0, 0, 255/255}, Green = {0, 255/255, 0}, Purple = {153/255, 0, 153/255}, Orange = {255/255, 128/255, 0}, Yellow = {255/255, 255/255, 0}, White = {255/255, 255/255, 255/255} } local intens = 0.75 local potiontime = 105 local breakcounter = 0 local assets= { Asset("ANIM", "anim/lightpotion.zip"), Asset("ATLAS", "images/inventoryimages/lightpotion.xml"), Asset("IMAGE", "images/inventoryimages/lightpotion.tex"), } PrefabFiles = { "lightpotion", } local function reduce1(inst) --Works if breakcounter > 1 then else intens = 0.5 inst.Light:SetIntensity(intens) end end local function reduce2(inst) --Works if breakcounter > 1 then else intens = 0.25 inst.Light:SetIntensity(intens) end inst.components.talker:Say("Light is reducing!", 4) --Hard To Make It Works (Talker nil value...) end local function reduce3(inst) --Works if breakcounter > 1 then breakcounter = breakcounter - 1 else intens = 0 inst.Light:SetIntensity(intens) inst.Light:Enable(false) print "Light off" breakcounter = breakcounter - 1 end inst.components.talker:Say("Light has gone...", 4) --Hard To Make It Works (Talker nil value...) end local function oneaten(inst, eater) addlight(eater) --It MUST Work eater:DoTaskInTime(potiontime-80, reduce1) --Works eater:DoTaskInTime(potiontime-40, reduce2) --Works eater:DoTaskInTime(potiontime-1, reduce3) --Works eater.components.talker:Say("Let there be light!", 4) --Works end local function addlight(eater) --It MUST Work if inst.Light then else inst.entity:AddLight() print "new light :(" end intens = 0.75 -- breakcounter = breakcounter + 1 print (breakcounter) -- inst.Light:Enable(true) inst.Light:SetRadius(2) inst.Light:SetFalloff(.8) inst.Light:SetIntensity(intens) inst.Light:SetColour(unpack(colors[optcolor])) end 1 hour ago, D4rkh0bb1T said: Beside, what could cause the mod to clash with other mod? If the other mod chose the same name and method of accessing its configuration options, or version of your own mod, if you by accident enable both the version in workshop-<id> and dev folder. Edited March 28, 2016 by Muche Link to comment Share on other sites More sharing options...
D4rkh0bb1T Posted March 28, 2016 Author Share Posted March 28, 2016 I'm really trying to make it works. I commented out some lines on the top of my script, which I don't know if they are right. Spoiler --local name = "korrigan" --local folder = KnownModIndex:GetModActualName(name) --local foldername = KnownModIndex:GetModActualName("korrigan") --local modenv = require "korrigan.modenv" --local Red = modenv.GetModConfigData("LIGHTCOLOR") --GetModConfigData("LIGHTCOLOR", "korrigan") --To be sure Then I tried the 1st option. Nothing in the modmain + the new things in the prefab - just like in your post. The light remains unchanged. So I tried the 2nd option. Global things in the modmain + the new things in the prefab. The light remains unchanged... When I say "new things", I mean local optcolor, local color and (unpack(colors[optcolor])) I might misunderstand something... and the modname should'nt be the mod actual folder (korrigan)? AdaHadabra "Ada-Hadabra" = modinfo's name. Link to comment Share on other sites More sharing options...
Muche Posted March 29, 2016 Share Posted March 29, 2016 Well, I assumed that your hard-coded way of specifying the color worked, and just needed it to be configurable. By seeing just the snippets of the code, I have no idea how they are used. For example, addlight function is being called in oneaten function, but is defined after it; addlight function references inst, but that's nowhere to be seen to be defined. Anyways, there's always the old-fashioned way. Add some debug prints, e.g. print(string.format("[lightpotion|addlight(%s)] optcolor=%s", tostring(eater), tostring(optcolor))) at the start of the addlight function, run it and see what the log says the color it read is. Yes, modname of a mod (used for global version of GetModConfigData) is the folder name of the mod. That's why the KnownModIndex:GetModActualName(modnameFancy) is used, it translates mod's name as it is specified in modinfo into modname as its folder name. This way you wouldn't have to change all the names after you upload the mod onto the workshop from your temporary dev folder name into final workshop-<id> folder name; which you don't know before you actually upload the mod. Link to comment Share on other sites More sharing options...
D4rkh0bb1T Posted March 29, 2016 Author Share Posted March 29, 2016 Good! I passed eater all the way into the addlight function instead of inst and put the local function above oneaten and that's all! It seems that your code nor mine was the trouble. I must admit that your way to simplify the color makes things easier to understand, this is a punch in my face, but a relief to my brain! A very big thanks to you and the time you took to help me out! Time to play! D4rkh0bb1T Link to comment Share on other sites More sharing options...
MF99K Posted April 20, 2016 Share Posted April 20, 2016 I'm also having some trouble with this type of coding. I have a couple of mods that I'm using configuration settings to change prefab variables, sort of the equivalent of TUNING variables. I have a mod that works that adds new tuning variables via string referencing, but it uses an existing component and I'm trying to do it with prefabs Link to comment Share on other sites More sharing options...
rezecib Posted April 20, 2016 Share Posted April 20, 2016 @mf99k You can just add them to the TUNING table. For example, GLOBAL.TUNING.MY_PREFABS_SPECIAL_VALUE = 30 (in the modmain). That's really just another version of converting config data into variables in the global space. To reduce the probability of namespace clashes, you could also make it a subtable of TUNING, like: GLOBAL.TUNING.MYMODNAME = { SPECIALVALUE = 30, } Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now