Jump to content

Client crashes after item dropped onto the floor


Recommended Posts

While testing a function of my character mod I had a friend join to help me test something, though once I dropped the item being tested they crashed, the mod works fine on my end, but I can't figure out what's causing the crash, especially since the error is calling the 'inventoryitem' component, which is a vanilla component

[string "scripts/components/inventoryitem.lua"]:10: attempt to index field 'inventoryitem' (a nil value)
LUA ERROR stack traceback:
    scripts/components/inventoryitem.lua:10 in (field) ? (Lua) <9-11>
    scripts/class.lua:30 in () ? (Lua) <23-32>
    scripts/components/inventoryitem.lua:31 in (field) _ctor (Lua) <28-49>
    scripts/class.lua:181 in (local) cmp (Lua) <171-184>
    scripts/entityscript.lua:519 in (method) AddComponent (Lua) <508-530>
    ../mods/robe/scripts/prefabs/robewand.lua:33 in (field) fn (Lua) <22-44>
    scripts/mainfunctions.lua:175 in () ? (Lua) <164-206>

 

Here are lines 22-44 of the modded prefab in case it's important

local function fn()
	local inst = CreateEntity()
	inst.entity:AddTransform()
	inst.entity:AddAnimState()
	inst.entity:AddNetwork()
	MakeInventoryPhysics(inst)
	
	inst.AnimState:SetBank("robewand")
	inst.AnimState:SetBuild("robewand")
	inst.AnimState:PlayAnimation("idle")
	
	inst:AddComponent("inventoryitem")
	inst.components.inventoryitem.imagename = "robewand"
	inst.components.inventoryitem.atlasname = "images/inventoryimages/robewand.xml"
	inst:AddComponent("equippable")
	inst:AddComponent("inspectable")
	inst.components.equippable:SetOnEquip(OnEquip)
	inst.components.equippable:SetOnUnequip(OnUnequip)
	inst:AddComponent("sentientaxe") --This is the placeholder being tested
	
	
	return inst
end

 

Link to comment
Share on other sites

Try that instead and let me know if it works.

local function fn()
	local inst = CreateEntity()
	inst.entity:AddTransform()
	inst.entity:AddAnimState()
	inst.entity:AddNetwork()
	MakeInventoryPhysics(inst)
	
	inst.AnimState:SetBank("robewand")
	inst.AnimState:SetBuild("robewand")
	inst.AnimState:PlayAnimation("idle")
	
	if not TheWorld.ismastersim then
		return inst
	end

	inst:AddComponent("inventoryitem")
	inst.components.inventoryitem.imagename = "robewand"
	inst.components.inventoryitem.atlasname = "images/inventoryimages/robewand.xml"
	inst:AddComponent("equippable")
	inst:AddComponent("inspectable")
	inst.components.equippable:SetOnEquip(OnEquip)
	inst.components.equippable:SetOnUnequip(OnUnequip)
	inst:AddComponent("sentientaxe") --This is the placeholder being tested
	
	
	return inst
end

 

Link to comment
Share on other sites

1 hour ago, ZupaleX said:

Try that instead and let me know if it works.


local function fn()
	local inst = CreateEntity()
	inst.entity:AddTransform()
	inst.entity:AddAnimState()
	inst.entity:AddNetwork()
	MakeInventoryPhysics(inst)
	
	inst.AnimState:SetBank("robewand")
	inst.AnimState:SetBuild("robewand")
	inst.AnimState:PlayAnimation("idle")
	
	if not TheWorld.ismastersim then
		return inst
	end

	inst:AddComponent("inventoryitem")
	inst.components.inventoryitem.imagename = "robewand"
	inst.components.inventoryitem.atlasname = "images/inventoryimages/robewand.xml"
	inst:AddComponent("equippable")
	inst:AddComponent("inspectable")
	inst.components.equippable:SetOnEquip(OnEquip)
	inst.components.equippable:SetOnUnequip(OnUnequip)
	inst:AddComponent("sentientaxe") --This is the placeholder being tested
	
	
	return inst
end

 

That worked, thank you so much!

Link to comment
Share on other sites

So a quick explanation so it doesn't look like black magic.

Notice the part 

	if not TheWorld.ismastersim then
		return inst
	end

This tells the game that if this code is running on the client, it should stop at that point. Anything which comes after should ONLY be executed on the host. You don't want the client and the host trying to access values for a container at the same time right? Imagine the mess that would produce due to latency between the client and the host.

So you let the host deal with all that complicated stuff and the client merely receive the useful information.

Link to comment
Share on other sites

2 minutes ago, ZupaleX said:

So a quick explanation so it doesn't look like black magic.

Notice the part 


	if not TheWorld.ismastersim then
		return inst
	end

This tells the game that if this code is running on the client, it should stop at that point. Anything which comes after should ONLY be executed on the host. You don't want the client and the host trying to access values for a container at the same time right? Imagine the mess that would produce due to latency between the client and the host.

So you let the host deal with all that complicated stuff and the client merely receive the useful information.

Oh, okay, so calling components should always come after a code like that?

Link to comment
Share on other sites

It depends which components but that's mostly true.

For example the components which deals with the reaction to keystroke to move your character around cannot be on the host, because how could it know which key you are currently pressing on the keyboard?

As a general rule: put the components after the statement to stop the function if running on the client. If something is not working as intended, start wondering if it should actually be run on the client or not.

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...