mojira.dev
MC-95720

Client-server desync on seemingly invalid block placement

Placing a block in a position that is valid according to the client but invalid according to the server will make it disappear from the client-side inventory until the inventory spot where it was gets manually updated.
Instead, the server should tell the client that removing that item from the inventory client-side to mask lag was an incorrect action because the block didn't get placed.
Alternatively the underlying issue could be fixed that makes the server consider the block placement in these cases invalid in the first place, because it is never actually invalid block placement when this happens, but appears to be an interpolation issue.

This is an issue that has been present since the SMP/SSP-merge in Minecraft 1.3.1 and happens in survival all the time. However, it usually goes by unnoticed in survival because of the figures. (One in a stack of 30+ items missing isn't very obvious, especially if it gets added again as soon as you place another item from that stack.)
It is a huge issue in custom maps with a limited amount of blocks though.

New steps to reproduce in written form:
(see attached gif)
1. Get a block
2. Look down at an angle and sneak
3. Spam right click to make block placement attempts inside you while slowly moving backwards
4. Stop spamming right click as soon as the block disappears from your inventory but didn't get placed

Old steps to reproduce in video form:
https://youtu.be/HF9xrRwrNcA
Because of the seemingly random nature of this issue, I decided to make a video on how to reproduce it with relative consistency, as following written steps to reproduce could easily lead to the assumption that it is not reproducible.

Old steps to reproduce in written form:
1. Create some sort of stress for your server (can be singleplayer).
Frequent lighting updates work great. The more stress on your server, the more often you will be able to reproduce the issue. Note however that this can and does happen — albeit more rarely — without any stress on the server whatsoever.
2. Run towards a block
3. Place a block onto the block you are running towards right before you actually hit it.
4. Result: The block you should have placed didn't get placed, but is still missing from your client-side inventory.
Technically though it is still in your inventory and updating the inventory spot where it should be (by dropping it, clicking it, attempting to place it or by relogging) will make it re-appear.

Important:
This desync can and does happen in cases very different from the case in the steps to reproduce. It can and does happen on a flat floor, it can and does happen on ceilings and if there is a lot of stress on the server it can and does happen when you attempt to place blocks more than one block away from your character. The cases in the steps to reproduce are just the cases that are the easiest to reproduce.

Update:
-added gif to show that this still is an issue in the current version (16w44a)

Related issues

MC-99148 When placing a block near to current position, the block is lost MC-117995 Shulker Box Vanishing Glitch MC-119324 Piston Disappearing MC-164239 Bed error when placing in a 2x1 place MC-174581 Placed blocks disappear MC-191035 Block gets deleted when mob walks at same time as block is placed MC-204950 when I try to put a blast furnace or some other type of object like the previous one and a villager crosses the blast furnace it just disappears and I can't get it back its crafting is simple that is true but still annoying MC-206983 Minecraft fence bug / entity bug. MC-215724 Entities can delete blocks when placed at the right time... MC-221286 Disappearing Block MC-221475 Impossible to play SkyWars, BedWars, or bridging in servers MC-222401 blocks get deleted when a villager is in it. MC-230858 Gravity blocks - Falling Entities (eg Gravel) Break Hopper Unexpectedly MC-273701 When placing a lectern under a falling block, the lectern will be in your hand and able to be placed, but the inventory will not register it

Attachments

Comments

migrated
[media][media][media]
migrated

Sound related to MC-12363

migrated

Sound related to MC-12363

I guess it is a similar sort of desync as the end result is identical (wrong client-side inventory), and I can see an additional "update your inventory, client!"-message after the client failed to perform an action "band-aid-fixing" both issues.

But this report is about specific instances where the server thinks you couldn't place a block because you tried to place it inside your character model even though that can clearly not be the case, which is something that shouldn't happen in the first place, even if the band-aid-fix still makes sense. 😉

marcono1234

Relates to MC-99075

migrated

Is this still an issue in the latest snapshot 16w44a? If so please update the affected versions.

This is an automated comment on any open or reopened issue with out-of-date affected versions.

migrated

Is this still an issue in the latest snapshot 16w44a? If so please update the affected versions.

Updated it. Again, (in singleplayer) this happens in any version since the 1.3.1 SSP/SMP merge.

SetantaLP

I think the main reason for this bug is, that block-placing is handled on client and server (which also causes block-placement sounds to be played/the block to be rendered for a short time even if the server cancels the block placement.)

migrated

This is because the client and the server are out of sync if either one of them lags behind and is a result of a feature rather than a bug.

migrated

Can confirm in 21w11a

migrated

This report contains two bugs.
1. The inventory desync
When a block is canceled the server doesn't update the player's inventory.

2. The invalid block placement
The server thinks you're placing a block inside yourself therefore it cancels the block. This is because the client doesn't send its position when you move less than 0.03 blocks.

migrated

at net.minecraft.client.player.localplayer.sendPosition() you can see that the client won't send its position to the server unless the player moved atleast 0.03 blocks or when 20 ticks have passed.

final double double4 = this.getX() - this.xLast;
final double double5 = this.getY() - this.yLast1;
final double double6 = this.getZ() - this.zLast;

++this.positionReminder;

boolean boolean4 = double4 * double4 + double5 * double5 + double6 * double6 > 9.0E-4 || this.positionReminder >= 20;

I can't think of a good reason for this, you want the server to have the same location as the client. A simple fix would be to send the position when the player moved more than 0 blocks.

final double double4 = this.getX() - this.xLast;
final double double5 = this.getY() - this.yLast1;
final double double6 = this.getZ() - this.zLast;

boolean boolean4 = double4 != 0 || double5 != 0 || double6 != 0;

You might think why 0, what if the client moved 0.0000001 blocks? Do you want to send the position in that case? Well basically you can't, if no keys are pressed and the client's motion is lower than 0.003 it will be set to 0. And then again, even if it is sent each tick it is such a small packet you wouldn't notice any increase in bandwidth.

migrated

Can confirm in 21w13a

migrated

Can confirm in 21w14a

migrated

Can confirm in 21w15a

clamlol

I'm not very knowledgeable about how this currently works internally, but one solution could be to decrement the Count property of the item being placed on the client while waiting for the server's response.* The server will respond with the new count, and the item in the client's inventory will either reflect this or be deleted if the returned value is <1. Obviously this would make latency more visible to the client (and lead to issues if you want the player to legitimately have an item with an invalid Count), but imo the benefits would be well worth it.

*For an item with Count <1, the item will remain in the player's inventory on the client but the client will no longer consider its functionality, placeability or attribute modifiers and will not render the item in the player's hand.**
**A possible extension would be that when shift-clicking items into the hotbar or offhand, an item with Count <1 will be considered an empty slot and will swap places with the item being shift-clicked. I'm not sure if this would feel good or just add frustration, but it might be something to try.

migrated

@unknown That could work but is quite a big change, it would be much simpler to update the player's inventory after their block is being canceled.

migrated

Can confirm in 21w16a

migrated

Using cobweb you can easily verify if this bug still exists, see attachment

[media]
migrated

Can confirm in 21w17a

migrated

Can confirm in 21w18a

migrated

Can confirm in 21w19a

marcono1234

Thanks @unknown for testing the issue in the latest versions. Though in general it is not necessary to confirm a bug for every version; most important is to confirm it for releases or when the changelog indicates that similar bugs have been fixed or that the game logic has been changed in this area.

migrated

Can confirm in Pre-release 4

ampolive

The issue shown in the video using cobweb.mp4 is MC-224949.

ampolive

Can confirm in 1.17.1.

clamlol

Affects 1.18.2-pre1.

migrated

Affects 1.19

migrated

(Unassigned)

Confirmed

Platform

Important

Networking

block, client, place, server

Minecraft 1.8.9, Minecraft 16w02a, Minecraft 1.9, Minecraft 1.10.2, Minecraft 16w43a, ..., 1.17.1, 1.18.1, 1.18.2 Pre-release 1, 1.19, 1.21

Retrieved