Jump to content

Why Movement Prediction is bad, and needs to be redone.


Recommended Posts

  • Developer

This video, is showing the difference between movement prediction being on and off. Do you notice the delay at which wickerbottom "follows" wolfgang with movement prediction on? this is a forest+caves server hosted on my local machine, imagine how much worse that gets if you add in even more ping delay!
while you might like movement prediction off, the level of delay created by movement prediction is to costly.
if you want to test this yourself, launch a world with caves + forest(forest only worlds can't have movement prediction turned of for remote clients) and run this command(make sure it says remote before hitting enter):
 

local player = ThePlayer wicker = c_spawn("wickerbottom") wicker.Physics:SetActive(false) wicker:DoPeriodicTask(0, function(inst) inst.Transform:SetPosition(player.Transform:GetWorldPosition()) end)

the reason for this, is simple.
how movement works(in layman's terms) is:
if movement prediction is off
it sends the move request to the server(immediately)
otherwise if movement prediction is on
it does the move action, and sometime later sends the move request to the server(this means you have a delay + ping delay before you start moving on the server)

how it should work is:
sends movement request(regardless of movement prediction being on or off)
then if movement prediction is on
it would do predicted movement
thus not feeling sluggish and having the same movement delay regardless of being on or off.

Link to comment
Share on other sites

4 hours ago, Zarklord said:

how it should work is:
sends movement request(regardless of movement prediction being on or off)
then if movement prediction is on
it would do predicted movement
thus not feeling sluggish and having the same movement delay regardless of being on or off.

So if I'm on a server with say not so great ping, how much of a difference in actual positions is there under the current implementation of lag compensation versus your suggestion? I'm having difficulty visualizing the difference.

Link to comment
Share on other sites

  • Developer
2 minutes ago, lakhnish said:

So if I'm on a server with say not so great ping, how much of a difference in actual positions is there under the current implementation of lag compensation versus your suggestion? I'm having difficulty visualizing the difference.

the gap between where you are and where the server says you are gets larger(and therefore it takes longer for your character to move, from when you move), if you have Too Many Items you can do the "flying" speed, and it would show the gap a bit more accurately.

Link to comment
Share on other sites

  • Developer
5 hours ago, Zarklord said:

how it should work is:
sends movement request(regardless of movement prediction being on or off)
then if movement prediction is on
it would do predicted movement
thus not feeling sluggish and having the same movement delay regardless of being on or off.

Fairly sure this is how it works.

Link to comment
Share on other sites

  • Developer
5 minutes ago, bizziboi said:

Fairly sure this is how it works.

in all the places i checked, there was entirely separate code paths for movement prediction on vs off, rather than the same code for both, with extra code for movement prediction on.
and that video, which was done on the exact same local hosted world without restarting the world, proves that extra delay is created with it on.

Link to comment
Share on other sites

  • Developer

As far as I recall (but it's been a while since I was on DST), when movement prediction is off the movement is sent to the server immediately (C-side) and is only executed when the server response comes back. When movement prediction is on, it sends it immediately and simulates it immediately, if the server response indicates that we're on a different location than we though we'd be through local simulation our position will be corrected.

I may be wrong.

Link to comment
Share on other sites

  • Developer
1 minute ago, bizziboi said:

As far as I recall (but it's been a while since I was on DST), when movement prediction is off the movement is sent to the server immediately (C-side) and is only executed when the server response comes back. When movement prediction is on, it sends it immediately and simulates it immediately, if the server response indicates that we're on a different location than we though we'd be through local simulation our position will be corrected.

I may be wrong.

components/playercontroller.lua @ ln 602-611
is a perfect example of what I'm talking about
if movement prediction is off(self.locomotor == nil) it sends the RPC instantly
else, the RPC is sent when preview_cb is called, rather than immediately.


        if self.locomotor == nil then
            self.remote_controls[CONTROL_CONTROLLER_ACTION] = 0
            SendRPCToServer(RPC.ControllerActionButtonDeploy, obj, act.pos.x, act.pos.z, act.rotation ~= 0 and act.rotation or nil)
        elseif self:CanLocomote() then
            act.preview_cb = function()
                self.remote_controls[CONTROL_CONTROLLER_ACTION] = 0
                local isreleased = not TheInput:IsControlPressed(CONTROL_CONTROLLER_ACTION)
                SendRPCToServer(RPC.ControllerActionButtonDeploy, obj, act.pos.x, act.pos.z, act.rotation ~= 0 and act.rotation or nil, isreleased)
            end
        end

 

Link to comment
Share on other sites

  • Developer

Maybe I am misreading what you mean (or the code, possible too!), but it seems to me that in one case (mastersim) the locomoter is called to locomote directly, and in the case when we are slave we still end up in PreviewAction which still locomotes directly, but the final action (use item, waits for confirmation from the server)?

 

 

Link to comment
Share on other sites

I was always under the impression from playing around with it is that:

Off: Client sends movement, waits for server reply, moves accordingly.  Lag = 2*ping with sync but client input is delayed by Lag.  AKA lock-step method.

On: Client sends movement and moves accordingly, gets server reply but doesn't really do any error correction.  Lag = 0, but clients will experience "phantom" hits from the desync.  Clients will also wait for actions to complete on the server before showing them to the client like lock-step, as actions aren't predicted as far as I can tell.

 

That all being said, the prediction side of the engine doesn't take into account server tickrate hiccups which really throw it off.

Meanwhile with the lock-step approach you feel every single stutter and know exactly where you're at every stuttery step of the way.

This reason alone is why I choose no prediction.

Link to comment
Share on other sites

  • Developer
14 hours ago, bizziboi said:

Maybe I am misreading what you mean (or the code, possible too!), but it seems to me that in one case (mastersim) the locomoter is called to locomote directly, and in the case when we are slave we still end up in PreviewAction which still locomotes directly, but the final action (use item, waits for confirmation from the server)?

 

 

your mostly correct, but the thing is, if movement prediction is on, extra delay is added, as the RPC is sent when preview_cb is called rather than immediately, this creates extra delay when no real purpose for extra delay exists for it.

13 hours ago, CarlZalph said:

I was always under the impression from playing around with it is that:

Off: Client sends movement, waits for server reply, moves accordingly.  Lag = 2*ping with sync but client input is delayed by Lag.  AKA lock-step method.

On: Client sends movement and moves accordingly, gets server reply but doesn't really do any error correction.  Lag = 0, but clients will experience "phantom" hits from the desync.  Clients will also wait for actions to complete on the server before showing them to the client like lock-step, as actions aren't predicted as far as I can tell.

 

That all being said, the prediction side of the engine doesn't take into account server tickrate hiccups which really throw it off.

Meanwhile with the lock-step approach you feel every single stutter and know exactly where you're at every stuttery step of the way.

This reason alone is why I choose no prediction.

again, mostly right except extra delay is added for all send RPC's when its on vs off.
IE
off = 2*ping
on = delay + (2*ping)

Link to comment
Share on other sites

1 hour ago, Zarklord said:

your mostly correct, but the thing is, if movement prediction is on, extra delay is added, as the RPC is sent when preview_cb is called rather than immediately, this creates extra delay when no real purpose for extra delay exists for it.

again, mostly right except extra delay is added for all send RPC's when its on vs off.
IE
off = 2*ping
on = delay + (2*ping)

Said delay is irrelevant (from what I've played around  with, at least).

To test it, I added some print statements to the game to check how big the delay is:


Lines 2990-3001:

        if self.locomotor == nil then
            self.remote_controls[CONTROL_PRIMARY] = 0
            SendRPCToServer(RPC.LeftClick, act.action.code, position.x, position.z, mouseover, nil, controlmods, act.action.canforce, act.action.mod_name)
        elseif act.action ~= ACTIONS.WALKTO and self:CanLocomote() then
            print("left click time: "..tostring(GetTime()))
            act.preview_cb = function()
                print("act preview time: "..tostring(GetTime()))
                self.remote_controls[CONTROL_PRIMARY] = 0
                local isreleased = not TheInput:IsControlPressed(CONTROL_PRIMARY)
                SendRPCToServer(RPC.LeftClick, act.action.code, position.x, position.z, mouseover, isreleased, controlmods, nil, act.action.mod_name)
            end
        end

 

result:
image.png.fe0ce531ebf4db6bea3bd10237718966.png

 

This was on a server where I had over 800 ping (the host only spoke Spanish and is probably very confused as to why I joined, dropped my items and then left). The delay between the click time and the time the preview_cb function is called is often 0 or 1 frames, provided I'm in the range of the action (the delay is longer when not because the player has to walk into range before doing the action, which would also be the case without movement prediction).

Link to comment
Share on other sites

  • Developer
2 hours ago, Electroely said:

Said delay is irrelevant (from what I've played around  with, at least).

To test it, I added some print statements to the game to check how big the delay is:


Lines 2990-3001:


        if self.locomotor == nil then
            self.remote_controls[CONTROL_PRIMARY] = 0
            SendRPCToServer(RPC.LeftClick, act.action.code, position.x, position.z, mouseover, nil, controlmods, act.action.canforce, act.action.mod_name)
        elseif act.action ~= ACTIONS.WALKTO and self:CanLocomote() then
            print("left click time: "..tostring(GetTime()))
            act.preview_cb = function()
                print("act preview time: "..tostring(GetTime()))
                self.remote_controls[CONTROL_PRIMARY] = 0
                local isreleased = not TheInput:IsControlPressed(CONTROL_PRIMARY)
                SendRPCToServer(RPC.LeftClick, act.action.code, position.x, position.z, mouseover, isreleased, controlmods, nil, act.action.mod_name)
            end
        end

 

result:
image.png.fe0ce531ebf4db6bea3bd10237718966.png

 

This was on a server where I had over 800 ping (the host only spoke Spanish and is probably very confused as to why I joined, dropped my items and then left). The delay between the click time and the time the preview_cb function is called is often 0 or 1 frames, provided I'm in the range of the action (the delay is longer when not because the player has to walk into range before doing the action, which would also be the case without movement prediction).

while that might be true in most(or all?) cases, at this point you have unnecessary code, creating less maintable(and therefore) buggy code sine your now duplicating LOADS of code in playercontroller.lua, meaning you still have a big issue with how its written.

Link to comment
Share on other sites

i completely agree
when i was playing with it on : i got terrible lag in input ( which what u should expect )
but also i got hit while 10 feet away from the boarilla while playing woodie or in general games of Normal DST i would literally get hit twice by tentacles while im far enough for them to sleep again
i know this can be the effect of lag but, i would rather have lag in one way and not the other, certainly not both
so you should always stick to 
image.png.9856b04e3afe5da90122ec130e8892c4.png

Link to comment
Share on other sites

One thing I think that was failed to take into consideration with the video is input delay. With movement prediction off it shows your true position on a server, but that comes at a cost of a delay between when you press a button and your character makes that action. Either way, there's still going to be lag. Turning off lag compensation doesn't just magically make latency disappear. That's literally impossible. If you have a good connection to a server, it won't really matter one way or the other. If you have a bad connection, then having lag compensation off can still screw you over just as much as having it on can.

Link to comment
Share on other sites

I've tested it some time ago too, aka said lag compensation: off. Obviously didn't help me one bit on servers with various problematic latency. Further so, made it even more annoying by giving the impression, when pressing WASD, I just sat there taking damage from hostiles like a chump when high ping kicked in. All-in-all I for one prefer (subjective matter) to "be hit from 2 tiles away" than having apparently "unresponsive keyboard".

Link to comment
Share on other sites

Actually, the one thing I never understood is why Lag Compensation is on Predictive by default instead of None. I've seen a lot of new players who play DST, but there is this delay to their actions and would have never known that this delay was b/c of Lag Compensation until I had to point the fact out to them. This is especially prominent for players who host their own world.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...