Joachim Posted July 26, 2016 Share Posted July 26, 2016 (edited) Dear fellow modders, I have been working on porting snakes from Shipwrecked to DST. This all seemed to work perfectly when I was testing the game locally, i.e., when I was the host. However, when running the same version (I checked this multiple times) on a dedicated server, the snake suddenly becomes invisible for clients. I know the snake is there, because it keeps hitting me, but I can't hit it back. I have no idea why this problem occurs, since I have worked on several prefabs (items, mobs, etc.). All of them worked both as host and as client, with the exception of the snake which only works as a host but not as a client (at least when it comes to showing the animation). I have even made sure to insert the SetPristine code at the right location. Here is a snippet to show you this: ... anim:SetBank("snake") anim:SetBuild("snake_build") anim:PlayAnimation("idle") inst.AnimState:SetRayTestOnBB(true) inst.entity:SetPristine() if not TheWorld.ismastersim then return inst end inst:AddComponent("knownlocations") inst:AddComponent("locomotor") -- locomotor must be constructed before the stategraph inst.components.locomotor.runspeed = 3 inst:SetStateGraph("SGsnake") .... The only thing that makes the snake stand out in my mod is that it has a custom stategraph. I have, however, compared this to other stategraphs of DST, but I can't find anything special about this stategraph that would explain this. I have read somewhere that this might have to do with movement prediction and that it may help to add "nopredict" to the tag tables, but no luck there. This is what the stategraph looks like: require("stategraphs/commonstates") local actionhandlers = { ActionHandler(ACTIONS.EAT, "eat"), ActionHandler(ACTIONS.LAVASPIT, "spit"), ActionHandler(ACTIONS.GOHOME, "gohome"), } local events= { EventHandler("attacked", function(inst) if not inst.components.health:IsDead() and not inst.sg:HasStateTag("attack") then inst.sg:GoToState("hit") end end), EventHandler("death", function(inst) inst.sg:GoToState("death") end), EventHandler("doattack", function(inst, data) if not inst.components.health:IsDead() and (inst.sg:HasStateTag("hit") or not inst.sg:HasStateTag("busy")) then inst.sg:GoToState("attack", data.target) end end), CommonHandlers.OnSleep(), CommonHandlers.OnLocomote(true,false), CommonHandlers.OnFreeze(), } local states= { State{ name = "gohome", tags = {"busy", "nopredict"}, onenter = function(inst, playanim) if inst.components.homeseeker and inst.components.homeseeker.home and inst.components.homeseeker.home:IsValid() then --inst.components.homeseeker.home.AnimState:PlayAnimation("chop", false) end inst:PerformBufferedAction() end, }, State{ name = "idle", tags = {"idle", "canrotate", "nopredict"}, onenter = function(inst, playanim) --inst.SoundEmitter:PlaySound("dontstarve/creatures/spider/idle") inst.Physics:Stop() if playanim then inst.AnimState:PlayAnimation(playanim) inst.AnimState:PushAnimation("idle", true) else inst.AnimState:PlayAnimation("idle", true) end inst.sg:SetTimeout(2*math.random()+.5) end, }, State{ name = "attack", tags = {"attack", "busy", "nopredict"}, onenter = function(inst, target) inst.sg.statemem.target = target inst.Physics:Stop() inst.components.combat:StartAttack() --inst.SoundEmitter:PlaySound("dontstarve/creatures/spider/pre-attack") inst.AnimState:PlayAnimation("atk_pre") inst.AnimState:PushAnimation("atk", false) inst.AnimState:PushAnimation("atk_pst", false) end, timeline= { TimeEvent(8*FRAMES, function(inst) if inst.components.combat.target then inst:ForceFacePoint(inst.components.combat.target:GetPosition()) end end), TimeEvent(14*FRAMES, function(inst) if inst.components.combat.target then inst:ForceFacePoint(inst.components.combat.target:GetPosition()) end inst.SoundEmitter:PlaySound("dontstarve/creatures/spider/attack") end), TimeEvent(20*FRAMES, function(inst) if inst.components.combat.target then inst:ForceFacePoint(inst.components.combat.target:GetPosition()) end end), TimeEvent(27*FRAMES, function(inst) inst.components.combat:DoAttack(inst.sg.statemem.target) if inst.components.combat.target then inst:ForceFacePoint(inst.components.combat.target:GetPosition()) end end), }, events= { EventHandler("animqueueover", function(inst) inst.sg:GoToState("idle") end), }, }, State{ name = "eat", tags = {"busy", "nopredict"}, onenter = function(inst, cb) inst.Physics:Stop() inst.components.combat:StartAttack() inst.AnimState:PlayAnimation("atk_pre") inst.AnimState:PushAnimation("atk", false) inst.AnimState:PushAnimation("atk_pst", false) end, timeline= { TimeEvent(14*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/spider/attack") end), TimeEvent(24*FRAMES, function(inst) if inst:PerformBufferedAction() then inst.components.combat:SetTarget(nil) end end), }, events= { EventHandler("animqueueover", function(inst) inst.sg:GoToState("taunt") end), }, }, State{ name = "spit", tags = {"busy", "nopredict"}, onenter = function(inst) -- print("snake spit") if ((inst.target ~= inst and not inst.target:HasTag("fire")) or inst.target == inst) and not (inst.recently_frozen) then if inst.components.locomotor then inst.components.locomotor:StopMoving() end inst.AnimState:PlayAnimation("atk_pre") inst.AnimState:PushAnimation("atk", false) inst.AnimState:PushAnimation("atk_pst", false) inst.components.propagator:StartSpreading() --print("vomitfire_fx spawned") -- inst.vomitfx = SpawnPrefab("vomitfire_fx") -- inst.vomitfx.Transform:SetPosition(inst.Transform:GetWorldPosition()) -- inst.vomitfx.Transform:SetRotation(inst.Transform:GetRotation()) --inst.SoundEmitter:PlaySound("dontstarve_DLC001/creatures/dragonfly/vomitrumble", "vomitrumble") else -- print("no spit") inst:ClearBufferedAction() inst.sg:GoToState("idle") end end, onexit = function(inst) -- print("spit onexit") if inst.last_target and inst.last_target ~= inst then inst.num_targets_vomited = inst.last_target.components.stackable and inst.num_targets_vomited + inst.last_target.components.stackable:StackSize() or inst.num_targets_vomited + 1 inst.last_target_spit_time = GetTime() end --inst.Transform:SetFourFaced() -- if inst.vomitfx then -- inst.vomitfx:Remove() -- end -- inst.vomitfx = nil -- inst.SoundEmitter:KillSound("vomitrumble") inst.components.propagator:StopSpreading() end, events= { EventHandler("animqueueover", function(inst) -- print("spit animqueueover") inst.sg:GoToState("idle") end), }, timeline= { TimeEvent(2*FRAMES, function(inst) -- print("spit timeline") inst:PerformBufferedAction() inst.last_target = inst.target inst.target = nil inst.spit_interval = math.random(20,30) inst.last_spit_time = GetTime() end), }, }, State{ name = "hit", tags = {"busy", "hit", "nopredict"}, onenter = function(inst, cb) inst.Physics:Stop() inst.AnimState:PlayAnimation("hit") inst.SoundEmitter:PlaySound("dontstarve/creatures/spider/hurt") end, events= { EventHandler("animover", function(inst) inst.sg:GoToState("idle") end), }, }, State{ name = "taunt", tags = {"busy", "nopredict"}, onenter = function(inst, cb) inst.Physics:Stop() inst.AnimState:PlayAnimation("taunt") -- inst.SoundEmitter:PlaySound("dontstarve_DLC002/creatures/snake/taunt") end, timeline= { TimeEvent(10*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/spider/scream") end), --TimeEvent(24*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve_DLC002/creatures/snake/taunt") end), }, events= { EventHandler("animover", function(inst) inst.sg:GoToState("idle") end ), }, }, State{ name = "death", tags = {"busy"}, onenter = function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/spider/death") inst.AnimState:PlayAnimation("death") inst.Physics:Stop() RemovePhysicsColliders(inst) inst.components.lootdropper:DropLoot(Vector3(inst.Transform:GetWorldPosition())) end, }, } CommonStates.AddSleepStates(states, { sleeptimeline = { TimeEvent(30*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/spider/sleep") end), }, }) CommonStates.AddRunStates(states, { runtimeline = { --TimeEvent(0, function(inst) inst.SoundEmitter:PlaySound("dontstarve_DLC002/creatures/snake/move") end), --TimeEvent(4, function(inst) inst.SoundEmitter:PlaySound("dontstarve_DLC002/creatures/snake/move") end), }, }) CommonStates.AddFrozenStates(states) return StateGraph("snake", states, events, "taunt", actionhandlers) If anyone can help me out, that would be great. Thanks in advance. Edited July 26, 2016 by Joachim Link to comment Share on other sites More sharing options...
Joachim Posted July 28, 2016 Author Share Posted July 28, 2016 As always, it turned out to be something simple. I forgot to add a Network component. Silly me. So in case anyone else has the same problem, don't forget to add the Network component, stupid! 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