This Week In Veloren 185

3 minute read15 August 2022

Authored by Christof

- AngelOnFira, TWiV Editor

Contributor Work

Thanks to this week's contributors, @Isse, @zesterer, @xMAC94x, @DaforLynx, @JulioCezarSilva, @Pfau, @Sam, @flo, @AldanTanneo, @imbris, @Slipped, @Vincent, and @juliancoffee.

More mediocre animations

@Isse

This week I got my MR merged that implemented spectator mode, but hidden in that MR was also a bug fix. Which is in my opinion more interesting than the feature itself.

So for some time now we've had a bug were if you die while in lava, you would still be on fire when you respawn.

So a fix for this bug had already been outlined by @imbris [GMT-4], and a very good description by @zesterer [GMT+0], in this issue. The first part of the issue was caused by having client authoritative physics, and the client "teleporting" back into the lava after respawning. Zesterer wrote this great diagram describing the issue:

Server thinks the player is...   | Client thinks the player is...
---------------------------------|-------------------------------
1) Player walks into lava

In lava, alive                   | In lava, alive

2) Player burns to death, entering the dead state

In lava, dead                    | In lava, dead

3) Player requests a respawn. Request received by server and a teleport occurs, but client does
not yet know

At waypoint, alive               | In lava, dead

4) Client and server now send contradictory position requests to one-another: the client still
thinks the player is in the lava, but the server thinks they are respawned. Both server and
client accept the reality of the other, so the server and client's view of the world 'swap'.

In lava, alive (on fire)         | At waypoint, alive

5) The short window above is enough time for the character to pick up the burning debuff because
the server sees them as being in the lava. Now, the client's new "correct" position request gets
sent back to the server, unifying both views of reality and finally placing the player back at
the waypoint for both server and client

At waypoint, alive (on fire)     | At waypoint, alive (on fire)

6) The burning debuff sticks around because it is on a time delay. The player *perceives* this as
a continuation of the debuff they had when they died, but in fact it is a new debuff that got
picked up as a result of the respawn position hot-swapping discussed above.

This issue was fixed by holding a counter of each force update that is done for that client, i.e each respawn, mounting position updates and teleports through commands. If we then we also keep this counter in sync on the client, and send that synced counter back with position updates from the client to the server, we can check if that position update is valid for the current counter on the server. If it's not equal to the one on the server, we can throw that update out.

So, I had implemented all that... But it still wasn't working. So I tested a bit and found out that the bug still happened with client authoritative physics turned off! Which was surprising. After some debugging I found that after respawning, the server still thought that the player was in lava. Which definitely wasn't correct. I'll also make a little diagram of what was happening.

1) Player walks into lava

2) The phys system runs, setting in_liquid to Some(Lava).

3) Player dies from burning debuff, in_liquid remains unchanged

4) Player respawns, in_liquid still remains unchanged.

// This next part depends on ecs system order being this way
5) The buff system runs, checking that in_liquid is Some(Lava) and if so applying the burning debuff.

6) The phys system runs, setting in_liquid to None. // In most cases. There could be a campfire underwater :P

This was a much simpler fix than the former one. We just needed to reset the component holding in_liquid once the player respawned. This being a double issue might've contributed to why it took so long for it to be fixed, and also the former fix is not really a straight forward fix. But in most cases it was the second fix that actually caused the bug, because client authoritative couldn't have caused it if the player's spawn point is far enough away, or they're playing on server authoritative physics.

A large tree in the distance! See you next time!