PanAzej Posted October 30, 2016 Share Posted October 30, 2016 I'm making a new character with a new 'tf2metal' stat. I 'heavily' edited the health and health_replica components and made a badge for them. It works fine serverside, but it crashes on clients, saying: Quote [string "../mods/ENGINEER/modmain.lua"]:122: attempt to index local 'metal' (a nil value) So, it definitely can't see the replicable component. It's my first time trying to make something like that (and not blindly copy-pasting), what am I doing wrong? Also I'd like to use this new 'metal' stat for crafting, if that's possible. How to make it a crafting ingredient of sorts? Here's the mod (since seems like nothing can be uploaded here atm :V) Any help is appreciated! Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/ Share on other sites More sharing options...
PanAzej Posted November 1, 2016 Author Share Posted November 1, 2016 Okay, I still can't figure out what's wrong. Every replicable component seems to attach itself in the same way as mine, I used AddReplicableComponent in modmain, yet the HUD still can't be built, since apparently client doesn't have a replica. It works serverside, though. I also searched for any info related to crafting using a custom stat. Here's the post I found: Click! I've tried using this method, but it doesn't seem to work for me. The recipe appears in crafting menu, but it ignores my character's stat. It always says I have 0 of the required ingredient. Here's another iteration of my mod if anyone would want to try to help me out: New version Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-832063 Share on other sites More sharing options...
Kzisor Posted November 3, 2016 Share Posted November 3, 2016 Just wanted to chime in and say, as far as I'm aware nothing would have broken the code in the post you linked where I helped the other person get it set up. If it's not working for you, more than likely you made a mistake somewhere. This is very likely due to the changes in the forum breaking a lot of the older posts with code in them. You could download the Chakra mod and look at it in order to determine what might be the cause of your issue as that mod is still working as far as I can tell, based on comments. Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-832478 Share on other sites More sharing options...
PanAzej Posted November 3, 2016 Author Share Posted November 3, 2016 3 hours ago, Kzisor said: Just wanted to chime in and say, as far as I'm aware nothing would have broken the code in the post you linked where I helped the other person get it set up. If it's not working for you, more than likely you made a mistake somewhere. This is very likely due to the changes in the forum breaking a lot of the older posts with code in them. You could download the Chakra mod and look at it in order to determine what might be the cause of your issue as that mod is still working as far as I can tell, based on comments. That's possible, that's why I'm coming here. From my perspective everything seems like it should work, yet it doesn't. I downloaded that Jutsu Mod to see how author did it. They used AddPlayerPostInit, because they wanted all players on the server to have this new stat added. I'm making a single character, though. I tried doing the same thing (because maybe i'm adding replica/component wrong way), but server kept crashing for me, not leaving a word in its log file, (just "shutting down" and that's it), leaving me wondering what I'm doing wrong. I tried AddComponentPostInit from modmain, because maybe functions in character's prefab weren't working or something. Nothing changed. I also thought that maybe testing this on master (where the character works), the replica doesn't send information properly, but it returns correct numbers in the console. I'm probably just doing it wrong, I'm not knowledgeable enough to know what's up. Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-832505 Share on other sites More sharing options...
Kzisor Posted November 3, 2016 Share Posted November 3, 2016 9 hours ago, PanAzej said: That's possible, that's why I'm coming here. From my perspective everything seems like it should work, yet it doesn't. I downloaded that Jutsu Mod to see how author did it. They used AddPlayerPostInit, because they wanted all players on the server to have this new stat added. I'm making a single character, though. I tried doing the same thing (because maybe i'm adding replica/component wrong way), but server kept crashing for me, not leaving a word in its log file, (just "shutting down" and that's it), leaving me wondering what I'm doing wrong. I tried AddComponentPostInit from modmain, because maybe functions in character's prefab weren't working or something. Nothing changed. I also thought that maybe testing this on master (where the character works), the replica doesn't send information properly, but it returns correct numbers in the console. I'm probably just doing it wrong, I'm not knowledgeable enough to know what's up. Take a look at the links in the post, I'm sure they might shed some more like on the issue. Sorry, posting from phone so can only give a single link. However, the links in that post show how to create custom widgets which both tutorials still work to this day. I'll try to recreate the tutorials on GitHub so they will keep their format. Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-832640 Share on other sites More sharing options...
PanAzej Posted November 4, 2016 Author Share Posted November 4, 2016 13 hours ago, Kzisor said: Take a look at the links in the post, I'm sure they might shed some more like on the issue. Sorry, posting from phone so can only give a single link. However, the links in that post show how to create custom widgets which both tutorials still work to this day. I'll try to recreate the tutorials on GitHub so they will keep their format. Hm, thanks! I've already looked at your Wortox character, though. This time I removed postinit for player_classified, changed all stuff to go through prefab and added all "dirty" variables/values. Previously all things went through player_classified that I edited through AddPrefabPostInit. My badge code seems to be fine to me. Game still says that "tf2metal is nil", so it seems like there's no replica on client. I've marked the place in which the error occurs. local function StatusDisplaysPostInit(self) if self.owner:HasTag("tf2engineer") then local TF2MetalBadge = require "widgets/tf2metalbadge" self.tf2metalmeter = self:AddChild(TF2MetalBadge(self.owner)) -- compatibility with Always On Status mod if KnownModIndex:IsModEnabled("workshop-376333686") then self.tf2metalmeter:SetPosition(-62, -52, 0) else self.tf2metalmeter:SetPosition(-80, -40, 0) end local function OnSetPlayerMode(self) if self.onmetaldelta == nil then self.onmetaldelta = function(owner, data) self.tf2metalmeter:SetPercent(self.owner.replica.tf2metal:GetPercent(), self.owner.replica.tf2metal:Max()) end self.inst:ListenForEvent("metaldelta", self.onmetaldelta, self.owner) local metal = self.owner.replica.tf2metal --------------- self.tf2metalmeter:SetPercent(self.owner.replica.tf2metal:GetPercent(), metal:Max()) --<< here is the error, apparently end end local function OnSetGhostMode(self) if self.onmetaldelta ~= nil then self.inst:RemoveEventCallback("metaldelta", self.onmetaldelta, self.owner) self.onmetaldelta = nil end end self._SetGhostMode = self.SetGhostMode function self:SetGhostMode(ghostmode) self._SetGhostMode(self, ghostmode) if ghostmode then self.tf2metalmeter:Hide() OnSetGhostMode(self) else self.tf2metalmeter:Show() OnSetPlayerMode(self) end end OnSetPlayerMode(self) end return self end AddClassPostConstruct( "widgets/statusdisplays", StatusDisplaysPostInit) Here's my current character's prefab: local MakePlayerCharacter = require "prefabs/player_common" local assets = { Asset("SCRIPT", "scripts/prefabs/player_common.lua"), } local prefabs = {} local start_inv = { "tf2wrench", } -- When loading or spawning the character local function onload(inst) -- end local function OnMetalDirty( inst, system ) if inst ~= nil then local percent = inst.currentmetal:value() / inst.maxmetal:value() local currentmetal = inst.currentmetal:value() local maxmetal = inst.maxmetal:value() local data = { newpercent = percent, maxmetal = maxmetal, currentmetal = currentmetal, } inst:PushEvent("metaldirty", data) end end local function AddMetalSystem( inst ) inst.maxmetal = net_ushortint(inst.GUID, "tf2metal.max", "currentmetaldirty") inst.currentmetal = net_ushortint(inst.GUID, "tf2metal.current", "currentmetaldirty") inst:ListenForEvent("currentmetaldirty", function( inst ) OnMetalDirty(inst) end) end -- This initializes for both the server and client. Tags can be added here. local common_postinit = function(inst) inst.MiniMapEntity:SetIcon( "tf2engineer.tex" ) inst:AddTag("tf2engineer") AddMetalSystem( inst ) end -- This initializes for the server only. Components are added here. local master_postinit = function(inst) inst.soundsname = "wolfgang" inst.Transform:SetScale(1.07, 1.07, 1.07) inst.components.health:SetMaxHealth(125) inst.components.hunger:SetMax(125) inst.components.sanity:SetMax(250) if not inst.components.tf2metal then inst:AddComponent("tf2metal") end inst.components.tf2metal.maxmetal = 200 inst.components.tf2metal.minmetal = 0 inst.components.tf2metal.currentmetal = 200 inst.components.combat.damagemultiplier = 0.75 inst.components.builder.science_bonus = 1 inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE --- local _RemoveIngredients = inst.components.builder.RemoveIngredients function inst.components.builder:RemoveIngredients( ingredients, recname ) local recipe = AllRecipes[recname] if recipe then for k,v in pairs(recipe.character_ingredients) do if v.type == CHARACTER_INGREDIENT.TF2METAL then self.inst.components.tf2metal:DoDelta(-v.amount) end end end _RemoveIngredients( self, ingredients, recname ) end local _HasCharacterIngredient = inst.components.builder.HasCharacterIngredient function inst.components.builder:HasCharacterIngredient( ingredient ) local _ret = _HasCharacterIngredient( self, ingredient ) if not _ret then if ingredient.type == CHARACTER_INGREDIENT.TF2METAL then if self.inst.components.tf2metal ~= nil then return self.inst.components.tf2metal.currentmetal >= ingredient.amount end end end return _ret end --- inst.OnLoad = onload inst.OnNewSpawn = function(inst) onload(inst) local helmet = SpawnPrefab("tf2hardhat") inst.components.inventory:Equip(helmet) end end return MakePlayerCharacter("tf2engineer", prefabs, assets, common_postinit, master_postinit, start_inv) Badge/new stat seems to be working on master. Client crashes when character is selected. Crafting recipe doesn't work on master as well (ignores stat, show that there's always 0 of it), but I guess that's to be expected if there's something so wrong that game crashes on client. I've attached new iterations of component and replica to this post, maybe there's something wrong with them. tf2metal.lua tf2metal_replica.lua Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-833072 Share on other sites More sharing options...
Kzisor Posted November 4, 2016 Share Posted November 4, 2016 (edited) Ill take a look at this when I get home, currently at work. Will update this post with my findings. Edit: The components look fine to me at first glance, I had some PC issues with my laptop when I got home; stupid Windows updates. What does your modmain.lua file look like at this moment in time? Edited November 5, 2016 by Kzisor Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-833306 Share on other sites More sharing options...
PanAzej Posted November 5, 2016 Author Share Posted November 5, 2016 20 hours ago, Kzisor said: Ill take a look at this when I get home, currently at work. Will update this post with my findings. Edit: The components look fine to me at first glance, I had some PC issues with my laptop when I got home; stupid Windows updates. What does your modmain.lua file look like at this moment in time? Thanks for looking into my stuff despite technical difficulties. I've attached the modmain to this post. modmain.lua Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-833701 Share on other sites More sharing options...
Kzisor Posted November 5, 2016 Share Posted November 5, 2016 @PanAzej, could you also post the postinits.lua file that contains the error? Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-833723 Share on other sites More sharing options...
PanAzej Posted November 5, 2016 Author Share Posted November 5, 2016 (edited) 52 minutes ago, Kzisor said: @PanAzej, could you also post the postinits.lua file that contains the error? I probably screwed up and pasted only a part of it in modmain previously. My bad! Here's the whole new mod version: ENGINEER2.zip Edited November 5, 2016 by PanAzej Or... did I? Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-833743 Share on other sites More sharing options...
Kzisor Posted November 5, 2016 Share Posted November 5, 2016 (edited) @PanAzej, so I have figured out the problem. Klei has made some changes to how character ingredients work. After actually getting a chance to test the Jutsu mod it actually does not work anymore. After spending about 3-4 hours on this particular issue today and about 2 the previous days trying to determine the root cause, I am afraid that it might not be doable 'at the moment' without some intervention from a Klei developer. It seems the issue at hand is how they've modified the way character ingredients work. Previously, we could simply add a new line to the CHARACTER_INGREDIENT table like you're doing and it would automatically pick-up newly index items. However, now with the changes it seems they are only picking up the character ingredients a single time; when the save file loads but, before any mods are loaded. It all fails and is tied to the following functionality which has been added since 'A New Reign'. local is_character_ingredient = nil function IsCharacterIngredient(ingredienttype) if is_character_ingredient == nil then is_character_ingredient = {} for k, v in pairs(CHARACTER_INGREDIENT) do is_character_ingredient[v] = true end end return ingredienttype ~= nil and is_character_ingredient[ingredienttype] == true end Recipes call this function to determine if the ingredient is a character ingredient. Unfortunately, if we override this function our custom ingredient type always returns nil. With that being said, our custom ingredient is added to the recipes.ingredients table instead of the recipe.character_ingredients table. A workaround would be to override the builder:CanBuild function, with a method similar to the following: local _CanBuild = inst.components.builder.CanBuild function inst.components.builder:CanBuild(recname) local _ret = _CanBuild(self, recname) if not _ret then local recipe = GetValidRecipe(recname) for i, v in ipairs(recipe.ingredients) do if v.type == GLOBAL.CHARACTER_INGREDIENT.TF2METAL then -- do your normal HasCharacterIngredient method here... elseif not self.inst.components.inventory:Has(v.type, math.max(1, RoundBiasedUp(v.amount * self.ingredientmod))) then return false end end for i, v in ipairs(recipe.character_ingredients) do if not self:HasCharacterIngredient(v) then return false end end for i, v in ipairs(recipe.tech_ingredients) do if not self:HasTechIngredient(v) then return false end end -- We've already determine that the ingredients failed before, -- so if we get here, we know they failed due to our custom ingredient, -- so return true ;) return true end return _ret end You would need to override the CanBuild function in the builder_replica as well, I'll leave that as an exercise for you to determine how to handle it. With all this said, I've already created a method for handling this in the future from the development of the game and I will be posting a request for the code to get looked at and possibly be added in to a future update. Edit: You can view the full details of the issue here: Edited November 5, 2016 by Kzisor Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-833866 Share on other sites More sharing options...
PanAzej Posted November 6, 2016 Author Share Posted November 6, 2016 4 hours ago, Kzisor said: @PanAzej, so I have figured out the problem. Klei has made some changes to how character ingredients work. After actually getting a chance to test the Jutsu mod it actually does not work anymore. After spending about 3-4 hours on this particular issue today and about 2 the previous days trying to determine the root cause, I am afraid that it might not be doable 'at the moment' without some intervention from a Klei developer. It seems the issue at hand is how they've modified the way character ingredients work. Previously, we could simply add a new line to the CHARACTER_INGREDIENT table like you're doing and it would automatically pick-up newly index items. However, now with the changes it seems they are only picking up the character ingredients a single time; when the save file loads but, before any mods are loaded. It all fails and is tied to the following functionality which has been added since 'A New Reign'. local is_character_ingredient = nil function IsCharacterIngredient(ingredienttype) if is_character_ingredient == nil then is_character_ingredient = {} for k, v in pairs(CHARACTER_INGREDIENT) do is_character_ingredient[v] = true end end return ingredienttype ~= nil and is_character_ingredient[ingredienttype] == true end Recipes call this function to determine if the ingredient is a character ingredient. Unfortunately, if we override this function our custom ingredient type always returns nil. With that being said, our custom ingredient is added to the recipes.ingredients table instead of the recipe.character_ingredients table. A workaround would be to override the builder:CanBuild function, with a method similar to the following: local _CanBuild = inst.components.builder.CanBuild function inst.components.builder:CanBuild(recname) local _ret = _CanBuild(self, recname) if not _ret then local recipe = GetValidRecipe(recname) for i, v in ipairs(recipe.ingredients) do if v.type == GLOBAL.CHARACTER_INGREDIENT.TF2METAL then -- do your normal HasCharacterIngredient method here... elseif not self.inst.components.inventory:Has(v.type, math.max(1, RoundBiasedUp(v.amount * self.ingredientmod))) then return false end end for i, v in ipairs(recipe.character_ingredients) do if not self:HasCharacterIngredient(v) then return false end end for i, v in ipairs(recipe.tech_ingredients) do if not self:HasTechIngredient(v) then return false end end -- We've already determine that the ingredients failed before, -- so if we get here, we know they failed due to our custom ingredient, -- so return true ;) return true end return _ret end You would need to override the CanBuild function in the builder_replica as well, I'll leave that as an exercise for you to determine how to handle it. With all this said, I've already created a method for handling this in the future from the development of the game and I will be posting a request for the code to get looked at and possibly be added in to a future update. Edit: You can view the full details of the issue here: Thanks for the insight, I'll definitely look into it and try to make it work! Any idea why the character instantly crashes on client, though? On master game loads just fine. I tried everything at this point, I have no idea what I'm doing wrong... Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-833980 Share on other sites More sharing options...
Kzisor Posted November 6, 2016 Share Posted November 6, 2016 34 minutes ago, PanAzej said: Thanks for the insight, I'll definitely look into it and try to make it work! Any idea why the character instantly crashes on client, though? On master game loads just fine. I tried everything at this point, I have no idea what I'm doing wrong... I would need to have an updated version of the actual crash as the postinits file has been updated since the original error had bee posted. Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-834009 Share on other sites More sharing options...
PanAzej Posted November 7, 2016 Author Share Posted November 7, 2016 (edited) On 6.11.2016 at 3:12 AM, Kzisor said: I would need to have an updated version of the actual crash as the postinits file has been updated since the original error had bee posted. It's mostly the same as before. I've got recipes working thanks to you! The game doesn't show current metal amount properly, though, but I'm getting there. Here's what I've put in character's prefab: local _RemoveIngredients = inst.components.builder.RemoveIngredients function inst.components.builder:RemoveIngredients( ingredients, recname ) local recipe = AllRecipes[recname] if recipe then for k,v in pairs(recipe.ingredients) do if v.type == CHARACTER_INGREDIENT.TF2METAL then self.inst.components.tf2metal:DoDelta(-v.amount) end end end _RemoveIngredients( self, ingredients, recname ) end local _CanBuild = inst.components.builder.CanBuild function inst.components.builder:CanBuild(recname) local _ret = _CanBuild(recname) if not _ret and recname ~= nil then --game crashed because recname is nil for some reason local recipe = GetValidRecipe(recname) for i, v in ipairs(recipe.ingredients) do if v.type == CHARACTER_INGREDIENT.TF2METAL then if self.inst.components.tf2metal ~= nil then return self.inst.components.tf2metal.currentmetal >= v.amount end elseif not self.inst.components.inventory:Has(v.type, math.max(1, RoundBiasedUp(v.amount * self.ingredientmod))) then return false end end for i, v in ipairs(recipe.character_ingredients) do if not self:HasCharacterIngredient(v) then return false end end for i, v in ipairs(recipe.tech_ingredients) do if not self:HasTechIngredient(v) then return false end end return true end return _ret end GetValidRecipe in CanBuild returns nil for some reason. Not too sure why, since recipes are added properly, should be in AllRecipes table and should return their name/tab. And here's current postinits file: postinits.lua And error: Basically, the game tries to create a widget and set value, but it crashes on client, because component's replica doesn't exist for some reason. I've added it through AddReplicableComponent in modmain, but it doesn't change a thing. Widget doesn't have this problem on master. Everything works as intended there. Edited November 7, 2016 by PanAzej Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-834435 Share on other sites More sharing options...
Kzisor Posted November 13, 2016 Share Posted November 13, 2016 (edited) On 11/7/2016 at 1:03 AM, PanAzej said: It's mostly the same as before. I've got recipes working thanks to you! The game doesn't show current metal amount properly, though, but I'm getting there. Here's what I've put in character's prefab: GetValidRecipe in CanBuild returns nil for some reason. Not too sure why, since recipes are added properly, should be in AllRecipes table and should return their name/tab. And here's current postinits file: postinits.lua Basically, the game tries to create a widget and set value, but it crashes on client, because component's replica doesn't exist for some reason. I've added it through AddReplicableComponent in modmain, but it doesn't change a thing. Widget doesn't have this problem on master. Everything works as intended there. Sorry, haven't really had a chance to look into this until this weekend came around. I have looked through your code and have looked through my Wortox mod which as far as I know still works. The major difference between the two is the fact that I am checking to see if the replica is actually there and you aren't. self.tf2metalmeter:SetPercent(self.owner.replica.tf2metal:GetPercent(), metal:Max()) -- error? compared to mine: if self.owner.replica.leveler then leveldelta( { newpercent = self.owner.replica.leveler:GetPercent( level_system ), maxexperience = self.owner.replica.leveler:GetMaxExperience( level_system ), currentlevel = self.owner.replica.leveler:GetLevel( level_system ), maxlevel = self.owner.replica.leveler:GetMaxLevel( level_system ) }) end This is the only thing that I can think of that would be causing the issue with the widget. Edited November 13, 2016 by Kzisor Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-836831 Share on other sites More sharing options...
PanAzej Posted November 13, 2016 Author Share Posted November 13, 2016 22 hours ago, Kzisor said: Sorry, haven't really had a chance to look into this until this weekend came around. I have looked through your code and have looked through my Wortox mod which as far as I know still works. The major difference between the two is the fact that I am checking to see if the replica is actually there and you aren't. self.tf2metalmeter:SetPercent(self.owner.replica.tf2metal:GetPercent(), metal:Max()) -- error? compared to mine: if self.owner.replica.leveler then leveldelta( { newpercent = self.owner.replica.leveler:GetPercent( level_system ), maxexperience = self.owner.replica.leveler:GetMaxExperience( level_system ), currentlevel = self.owner.replica.leveler:GetLevel( level_system ), maxlevel = self.owner.replica.leveler:GetMaxLevel( level_system ) }) end This is the only thing that I can think of that would be causing the issue with the widget. Thanks for looking into it. Yup, this seems to fix the issue with crashing. Metal widget and crafting tab don't seem to update properly on client, but seems that replica exists and crafting consumes correct metal amount. I'll try to fix this stuff sometime. Thanks once again! Link to comment https://forums.kleientertainment.com/forums/topic/71273-replicable-component-not-replicating/#findComment-837229 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