Jump to content

Recommended Posts

EDIT: Solved

 

I am a total noob when it comes to networking. To be fair, I know that data needs to be send by the host for the client to recieve it, but that's about it.

 

I tried porting Vasa Mundus to DST (available on Steam Workshop), and whilst the host part works perfectly fine, the client... lacks. I couldn't test everything because client testing takes two people, but here are two important issues:

 

1. crash when opening a chest prefab. The client side never sets the container widget's data to the standard "treasurechest". I didn't get to try an explicit data set so far, though I doubt it would be any different.


local assets = {
Asset("ANIM","anim/jabchest.zip"),

Asset("ANIM", "anim/treasure_chest.zip"),
Asset("ANIM", "anim/ui_chest_3x2.zip"),
}

local function onopen(inst)
inst.AnimState:PlayAnimation("open")
inst.SoundEmitter:PlaySound("dontstarve/wilson/chest_open") --hurting non-players is further down
end

local function onclose(inst)
inst.AnimState:PlayAnimation("close")
inst.SoundEmitter:PlaySound("dontstarve/creatures/bat/bite")
inst.AnimState:PushAnimation("closed", false)
end

local function onhammered(inst, worker)
inst.components.lootdropper:DropLoot()
inst.components.container:DropEverything()
SpawnPrefab("collapse_small").Transform:SetPosition(inst.Transform:GetWorldPosition())
inst.SoundEmitter:PlaySound("dontstarve/wilson/rock_break")
inst:Remove()
end

local function onhit(inst, worker)
inst.AnimState:PlayAnimation("hit")
--inst.components.container:DropEverything()
inst.AnimState:PushAnimation("closed", false)
inst.components.container:Close()

if worker then
if worker.components.combat then
worker.components.combat:GetAttacked(inst,20)
elseif worker.components.health then
worker.components.health:DoDelta(-20,false,inst.prefab)
end
end
end

local function onbuilt(inst,data)
inst.AnimState:PlayAnimation("place")
inst.AnimState:PushAnimation("closed", false)
inst.owner = data.builder.userid
end

local function onsave(inst, data)
if inst.owner then
data.owner = inst.owner
end
end

local function onload(inst, data)
if data and data.owner then
inst.owner = data.owner
end
end

local function fn()
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddSoundEmitter()
inst.entity:AddNetwork()
inst.entity:AddMiniMapEntity()
inst.MiniMapEntity:SetIcon( "treasure_chest.png" )

inst.AnimState:SetBank("jabchest")
inst.AnimState:SetBuild("jabchest")
inst.AnimState:PlayAnimation("closed")

inst:AddTag("structure")
inst:AddTag("chest")
inst:AddTag("playerowned")
inst:AddTag("personal")

MakeSnowCoveredPristine(inst)

inst.entity:SetPristine()

if not TheWorld.ismastersim then
return inst
end

inst:AddComponent("inspectable")
inst:AddComponent("container")
inst.components.container:WidgetSetup("treasurechest")
inst.components.container.onopenfn = onopen
inst.components.container.onclosefn = onclose

inst:AddComponent("lootdropper")
inst:AddComponent("workable")
inst.components.workable:SetWorkAction(ACTIONS.HAMMER)
inst.components.workable:SetWorkLeft(4)
inst.components.workable:SetOnFinishCallback(onhammered)
inst.components.workable:SetOnWorkCallback(onhit)

inst:ListenForEvent( "onbuilt", onbuilt)
inst:ListenForEvent( "onopen", function(self, data) --due to data
local dude = data.doer
if dude and not dude:HasTag("player") or --npc thief
(inst.owner and dude.userid ~= inst.owner) then --player thief
if dude.components.combat then
dude.components.combat:GetAttacked(self,10)
elseif dude.components.health then
dude.components.health:DoDelta(-10, false, "stingchest")
end
dude:PushEvent("thorns") --say auch
end
end)

inst.OnSave = onsave
inst.OnLoad = onload

MakeSnowCovered(inst)

return inst
end

return Prefab("forest/objects/stingchest",fn,assets),
MakePlacer("common/stingchest_placer","jabchest","jabchest","closed")

 

2. Talker component does not talk. This isn't critical, but highly annoying, and even worse, I have no idea why it happens (or doesn't, rather). The prefab is meant to talk when hit, and it properly shows for the host only.

 

local assets = {
Asset("ANIM", "anim/shelldummy.zip")
}

local function Die(inst)
SpawnPrefab("collapse_small").Transform:SetPosition(inst.Transform:GetWorldPosition())
inst.SoundEmitter:PlaySound("dontstarve/creatures/slurtle/shatter")
inst.components.lootdropper:DropLoot()
inst:Remove()
end

local function onbuilt(inst)
inst.AnimState:PlayAnimation("place")
inst.AnimState:PushAnimation("idle_LP",true)
end

local function OnHit(inst, guy, dmg)
inst.AnimState:PlayAnimation("hit")
inst.AnimState:PushAnimation("idle_LP",true)
if inst.hittime < GetTime() - 2.5 then
inst.components.talker:Say(tostring(dmg))
inst.hitnum = 0
elseif inst.hitnum >= 3 then
Die(inst)
else
inst.hitnum = inst.hitnum + 1
inst.components.talker:Say("I'm hurt! Stop it!")
end
inst.hittime = GetTime()
inst.components.health.currenthealth = inst.components.health.maxhealth
end

local function fn()
local inst = CreateEntity()
inst.entity:AddSoundEmitter()
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddNetwork()

MakeObstaclePhysics(inst, .6)

inst.AnimState:SetBank("shelldummy")
inst.AnimState:SetBuild("shelldummy")

inst.AnimState:PushAnimation("idle_LP",true)

inst.entity:SetPristine()

if not TheWorld.ismastersim then
return inst
end

inst.hitnum = 0
inst.hittime = GetTime()

inst:AddComponent("lootdropper")
inst:AddComponent("inspectable")
inst:AddComponent("talker")

inst:AddComponent("combat")
inst.components.combat.onhitfn = OnHit

inst:AddComponent("health") --why do I have to do this... why does combat want me to do this...
inst.components.health.vulnerabletoheatdamage = false
inst.components.health.minhealth = 1 --never die
inst.components.health.nofadeout = true
inst.components.health.canmurder = false
inst.components.health.canheal = false

inst:ListenForEvent("onbuilt",onbuilt)

inst:AddTag("grass") --maybe port this back to DS?

return inst
end

return Prefab("forest/objects/shelldummy", fn, assets),
MakePlacer("common/shelldummy_placer", "shelldummy", "shelldummy", "idle")

 

Thank you for letting me complain about things I don't grasp. I am probably just being stupid or ignorant or overthinking or all three of those. Don't be harsh, just honest. Thanks again!

Edited by Mobbstar

I tried porting Vasa Mundus to DST (available on Steam Workshop), and whilst the host part works perfectly fine, the client... lacks. I couldn't test everything because client testing takes two people, but here are two important issues:

 

If it can help you, i suggest you to make a local dedicated server. It's very, very, very usefull when you want to test your mod in client-side, because you can test a lot more easily your mod.

You don't have to have a server to make this, the computur you use to launch and play the game usually is perfectly fine for it.

 

See this link :

 

http://dont-starve-game.wikia.com/wiki/Guides/Don%E2%80%99t_Starve_Together_Dedicated_Servers

 

And if you needs help to make one, you could have help. This way, in the future, it will be easier for you to test, find what is wrong and all.

Dedicated server is very convenient for test :)

if not TheWorld.ismastersim then    inst.OnEntityReplicated = function(inst) inst.replica.container:WidgetSetup("treasurechest") end    return instend

As I pointed out here

http://forums.kleientertainment.com/topic/58664-i-derped-with-the-backpacks/

clients try to lookup the jabchest widget info in the params table of containers.lua, since the WidgetSetup of the container component doesn't propagate the setup to the client.

 

And as I pointed out here

http://forums.kleientertainment.com/topic/56702-joining-clients-hate-the-talker-component/

inst:AddComponent("talker")inst.entity:SetPristine()if not TheWorld.ismastersim then	return instend

As of now, talker is a server and client component.

If only the server has it, then clients won't update their textwidgets over their prefabs, so they won't see any text.

Edited by DarkXero

If it can help you, i suggest you to make a local dedicated server. It's very, very, very usefull when you want to test your mod in client-side, because you can test a lot more easily your mod.

You don't have to have a server to make this, the computur you use to launch and play the game usually is perfectly fine for it.

 

See this link :

 

http://dont-starve-game.wikia.com/wiki/Guides/Don%E2%80%99t_Starve_Together_Dedicated_Servers

 

And if you needs help to make one, you could have help. This way, in the future, it will be easier for you to test, find what is wrong and all.

Dedicated server is very convenient for test :-)

 

Ah, I should try that. Thank you very much for pointing it out!

 

 

 

if not TheWorld.ismastersim then

inst.OnEntityReplicated = function(inst) inst.replica.container:WidgetSetup("treasurechest") end

return inst

end

As I pointed out here

clients try to lookup the jabchest widget info in the params table of containers.lua, since the WidgetSetup of the container component doesn't propagate the setup to the client.

 

And as I pointed out here

inst:AddComponent("talker")

inst.entity:SetPristine()

if not TheWorld.ismastersim then

    return inst

end

As of now, talker is a server and client component.

If only the server has it, then clients won't update their textwidgets over their prefabs, so they won't see any text.

 

 

Thank you for the thorough help! I didn't realise I could set things up for the client too, I thought the game would do all the work for me ;_;

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
×
  • Create New...