mojira.dev

Alexander Gundermann

Assigned

No issues.

Reported

MC-227520 Overworld Fossils always generate at bedrock level Fixed MC-188821 Flat world preset code: stronghold not working properly Duplicate MC-98995 Birch Forest M Biome Generation off Fixed MC-72065 Old superflat codes broken when using multiple layers Duplicate

Comments

I think they still can spawn in bamboo jungles, because the stronghold location generator falls back to some "biome search starting point" if no suitable biome is found within a certain range. So if that starting point was a bamboo jungle, and no suitable biome is in the area, it would spawn there.

But it's probably far less likely now.

They still generate, there's one at the coords I mentioned above. Perhaps the command is based on the same biome list that's missing bamboo?

I think there's actually two issues then. What I was referring to has to do with bamboo biomes specifically.

 

To give a non superflat example, in seed "3" there used to be a stronghold in a bamboo jungle @ 16964/31/5604, which is now gone. And in general, many stronghold positions are changed as a result of the change to the list of biomes that strongholds spawn in.

Yes, they are. Try "3;10*1;1;village". I anticipated them not to work either, but was happy to see that they do. The only thing that does not work is using old multipliers (x instead of *), which should be converted automatically when using old version codes (indicated by a leading 2). I presume this is just something they missed because they only tested with single layer codes.

They thought of that. There's an explicit condition that checks if all chunks within a certain radius (32m iirc) have loaded before an entity is updated. Of course, there could still be a bug in the way that implemented it, but it's not like they completely neglected it.

For what it's worth, I've done a lot of debugging last year in July for 1.6 to narrow down this issue (as have others). My main findings can still be found here https://github.com/taurose/Unglitch , and in the comments above. To sum it up, there were a lot of different problems leading to this issue (and related ones), some of which were really easy to fix (ie changing 1 line), while others seemed to be conceptual problems that would require a lot of changes and compromises in terms of performance or even network bandwidth.

@Djfe I did that already and posted my findings above. By now, I'm fairly certain that what I described is the main cause. It's primarily the server that sends wrong positions to the client.

I've spent some time recently trying to figure out the cause of server client glitches like that. While I can't explain the scenario in the report, I think I do know what's going on with boats and why they are so bugged. There's lots of issues with boats and client/server synchronization in general, so I'll try sticking to the causes of the soul sand setup glitches, which by the way also works with just a single solid block on which you place the boat (make sure there's no adjacent blocks).

First of all, you should know there's an evil flag in the boat class. When set to false, the client takes over the control of the boat on his side. The flag is more than likely meant to be false whenever the player is inside the boat. In MCP it's called "field_70279_a". Think of it like "not ridden by local player" or "give control to server".

1) Boats glitching into the ground
The cause of this is that when the client accepts server updates (i.e. flag is true), it skips collision detection entirely, and just warps the boat to the received location. This would be fine if the positions sent by the server were always correct, but they generally are not due to optimization and bugs. One consequence of this is that when you place a boat on a full block, it will be slightly inside the ground. You don't really notice that because the client doesn't even apply gravity to the boat, at least until you get in and make the client take control of the boat, at which point the collision of the boat with the ground block goes unnoticed (because it's already inside the block), but only by the client.

2) Server/Client split
As pointed out above, once the player enters the boat, and the flag is set to false, the client entirely ignores updates from the server for the boat (without having checked that, I assume when riding something the player's position is synchronized via the vehicle, not the player itself), only the movement commands are now being synchronized, so you still move server-side.
However, there's some indication in the code that the player ridden boat is still supposed to accept position updates, but only if the discrepancy is more than 1 block. On the other hand, they could have changed it in hindsight because the movement might have ended up being jerky if the latency was high. So I guess this is either an unintended error, or the (possible unintentional) consequence of another bugfix.

3) Ghost boats
Once you leave the desynced boat, you'll notice that you (the player) returns to the correct server-side position while the boat is still off. That seems to be because of an error (in NetClientHandler) which causes the flag to stay false, even after the player leaves the boat. So any boat you enter and leave will essentially become a ghost, because the client starts ignoring updates from the server and does his own thing. Apart from restarting the game / reloading the entity, this false state is only corrected when another entity enters the boat.

I also made a mod to fix related issues: https://github.com/taurose/Unglitch . At the moment, it only fixes 1) mentioned here. I might do some more tests to figure out a clean way to fix the other issues as well though.

Yeah, boats are supposed to sink into the ground like that by 0.3 blocks. The only "bug" here is that they initially spawn 0.3 blocks higher client-side, before the server corrects that with a position update. Unfortunately though, simply removing that client-side offset, reveals some more substantial bugs which would need to be fixed as well.

I recently made a bugfix mod for glitching mobs and even though I couldn't reliably reproduce this issue in 1.6.2, I think there's a good chance this should be covered as well: https://github.com/taurose/Unglitch (4).

In the tracker code there's a flag that determines whether an entity has moved far enough to send a position update. Several lines later, if the flag is true, the tracker stores the entity's location that is supposedly sent to the players for later updates. However, it seems that over time Mojang added several conditions to circumvent that flag and send or not send position updates regardless, which causes the "last sent" locations to be off. And once that happened, the clients receive false position updates and the entity appears offset.
Luckily, this can be fixed quite easily with a few lines once you know the problem.

If that's the source of the issue, this would be related to MC-342.

I recently made a bugfix mod for glitching mobs and I think this should be covered as well: https://github.com/taurose/Unglitch (4).

In the tracker code there's a flag that determines whether an entity has moved far enough to send a position update. Several lines later, if the flag is true, the tracker stores the entity's location that is supposedly sent to the players for later updates. However, it seems that over time Mojang added several conditions to circumvent that flag and send or not send position updates regardless, which causes the "last sent" locations to be off. And once that happened, the clients receive false position updates and the entity appears offset.
Luckily, this can be fixed quite easily with a few lines once you know the problem.

I did some more investigating, and discovered some more (easy to fix) bugs, mostly related to client-server synchronization of entity positions. Also, I revamped my epsilon fix to rely directly on integers, which should make it much more efficient (though still slower than a simple comparison of course). I also had to increase the tolerance a bit, because I found some setups which caused higher errors. Most noticeably, when entities are being pushed upwards (eg by water) at certain y-coordinates.

I also decided to do redo the server position adjustment algorithm (responsible for mitigating temporary client-side glitches). I already attempted to do so in the past, but I wasn't satisfied with the results. However, now that all the other bugs are out of the way, things are looking much better. I don't wanna say visual glitches are fixed 100% by the mod (they're not), but I think it's pretty close now, and certainly a major improvement to the current situation.

Here are the links:
Repo: https://github.com/taurose/Unglitch (thorough explanation, test worlds, source snippets)
Direct Mod DL (Client): https://github.com/taurose/Unglitch/raw/master/Mod_1.6.2-v2.zip

What it does in a nutshell:

  • fixes server-side permanent, entity glitches on load (MC-2025) and during gameplay, hopefully 100%

  • mostly fixes temporary, client-side entity glitches (MC-10)

  • fixes client-server synchronization issues (cause for MC-19331, probably more)

  • in contrast to Daniel's Mod, this mod does fewer changes to server-side game physics by not relying on an universal pushoutofblocks method. It doesn't fix the glitchy behavior of items or xp orbs, and presumably breaks fewer contraptions than Daniel's. On the other hand, Daniel's fix might be able to account for some rare or future glitches.

Oh, now I see why you were thinking that way..

That's an awesome solution, great job! 🙂

Well, I generally prefer fixing the root cause of bugs. In this instance, it seems the whole concept of storing dynamic block bounds in the block object seems to be the root, and may probably cause other bugs, which are very hard to find because of threading. If not now, maybe in the future. So ensuring that at least the colliding blocks functions are always working correctly is what I was trying to do that with that fix by making the methods not rely on the object's block bounds at all. There may also be mods that could call setBlockBounds.
So in the end, I think this approach is much more robust (though again, there might be other places besides collision logic where setBlockBounds could cause race conditions; so the very best thing would probably to make the fields of the block bounds final and only set them during instantiation for non-dynamic blocks).
But yeah, yours is much faster to write, and since you tested it, I do think it's suited for a mod, but I honestly hope Mojang doesn't go that route.

I'm pretty sure you're wrong about this bug only affecting blocks with multiple bounding boxes. I'm not sure why you'd think that. As pointed out in the repo, the problem is that the affected blocks store each of their dynamically generated block bounds to the same fields in the block object and rely on it not being changed before retrieving it again. But when both client and server generate the bounds of the same block at roughly the same time, one may override the generated bounding box of the other. This is not only caused by a block consisting of multiple block bounds at the same time, but also by different bounding boxes being possibly generated for the same block, depending on their coordinates, orientation, meta data, adjacent blocks etc. (I call them "dynamic"). It's just more likely to happen with multiple ones, because then the game has to spend more time for that so the chance of the threads "overlapping" at those checks is bigger.
I also tested it out just now. Try enclosing some villagers with full blocks in a 2x2 horizontal space or so, and put open trapdoors (vertical) on the walls. This way, there will be a lot of collisions going on with open trap doors. Now, make something like this: http://i.imgur.com/AK3dRZw.png , where the villagers (or other mobs) can escape their cage by glitching through a closed trap door. Since there's a chance that the closed trap door can be treated as an open one, you should see some villagers glitching through and falling down

Edit: In case you want to try that scenario with my mod, you have to change the first if condition inside getBlockBoundsOnState to "if ((meta & 8) != 0)" instead of "if ((meta) != 0)" to fix the bug you discovered.

No worries. I actually mentioned this possibility in the repository readme. I chose not to do that for a couple of reasons.
First, because there are several other places calling setBounds(), for example arrows. So the collision could still get screwed up. Checking every possible method that may eventually call setBlockBounds and see which thread they could run on to get an idea what could go wrong seemed too cumbersome. You could also use a synchronization object for that, but that would make it a lot more complex in the end.
The other thing is the performance impact. I don't know by how much, maybe even on slow PCs not noticeable, at least in normal worlds But I fear it could go worse if there are lot of mobs with a lot of collisions going on. And also, I think it's a bad programming style, since there's no thread communication, so it seems unnecessary. And for the mod, it doesn't reduce the number of edited classes, unfortunately.
But yeah, it's faster to write and avoids copy & paste errors and such 😉

Thanks for giving it a try and letting me know about the trap door issue.

Argh, I screwed up the installation of your mod before. Now who's feeling stupid? 😉 Great job! I still wonder why it works with fences and other non-"normal" blocks, or is the position reset doing all the magic? However, I don't think fiddling with the server logic is the right way to go, unless it's really necessary. I kinda enjoy glitches and abusing them, as long as they are predictable and not totally arbitrary like those. Moreover, I doubt that the visual glitches are related to server-side misplacements.

Visual Errors - Cause
You're right, they're caused by the server sending bytes/ints instead of doubles. Bytes are only used to send differentials though; if an entity moved too far to represent the distance using bytes, the game will send integers instead. The way this works, the position received by clients may ultimately be off by up to 1/32. Although I haven't backtraced it, I think this glitch was introduced in beta 1.6, where the changelog states "Compressed network traffic more aggressively.", at which point they probably started sending bytes/ints.

Visual Errors - History
As I already said, I made a mod called BetterSMP some time ago which mitigated this issue as well. It was working quite good, though not as good as yours I think.
Back then, there was also the issue that the server applied the "rounded" coordinates to the entities, which you apparently assume to happen right now. So after chunk reload, the misplacements became permanent. BetterSMP fixed that, too, as well as a slime-specific glitch. The mod was then integrated into bukkit, but they found it too slow, so they came up with their own algorithm.

Some time before the client/server merge or even at the same time, their algorithm as well as the two fixes made it into minecraft (I guess they had to come up with some solution, otherwise SSP would be much worse today).

Visual Errors - Current Fix
I haven't quite grasped that algorithm yet (see EnumEntitySize.java), but the way I understand it, it relies on the size of the entities and the measures of common blocks to correct glitches in certain common scenarios.

For example, it might have been programmed so that when, say, a chicken is pushed against a fence to the south, it will notice this by the fractional part of the coordinates (which are always the same in this scenario no matter the integer part) and round the right way. And in the same manner, it might have been tweaked to fix other scenarios, or at least that's how I imagine it 😉. As you already know, the problem with that algorithm is that it doesn't always work, even in common scenarios. But what's worse is that, in uncommon scenarios, it totally fails. For example, try putting some villagers into a small area enclosed by skull blocks.

So if I'm right, this seems like a very hacky fix/workaround which is likely to cause even more glitches with future blocks/entities or those added by mods.

Visual Errors - Solution?
However, as I said before, I'm pretty convinced these position errors remain client-side, and do not affect the server at all anymore. But I also think there should be a better fix to this than the current one. Yours running client-side only could be a great solution, but there are still a some issues left. For example, chickens sinking into water, or mobs who end up falling down a cliff due to the position shift (unless your mod already fixes that). I'm gonna try to merge this on github as well, once I catch some time.

I've also tried a different approach. In a way, sending ints/bytes instead of doubles to save traffic when the whole communications is done via memory feels kinda stupid. So I tried making it send doubles again. It's working perfectly. I haven't played around with it for too long, but I wouldn't be suprised if that fixed or improved other things as well. However, the problem with this could be that it would again separate SSP from SMP, so things working in SSP might end up not working in SMP or the other way around. So maybe this might be better suited for a mod.

Float gibberish
I've also done some more testing with the floating point errors. It seems it mostly happens if the mobs' coordinates are close to a power of two, like 32, 64, .. , at which point the min and max coordinates of the bounding box have different precisions (floating point internals...), so adding or subtracting values from them may cause them to diverge, and that error can be propagated. Using doubles for width and height didn't seem to change a lot though. In my test map, the golems are at 512. I honestly wasn't aware of that back then.

Anyways, the epsilon approach based on the precision of the coordinates still feels like the right way to go.

Now, let's hope Mojang picks this up 😉

I've been keeping track of mob glitches in Minecraft as well. A couple versions back I already made a mod called BetterSMP to fix smp-exclusive permanent glitches and reduce the amount of temporary/visual glitches. The algorithm was reworked by the bukkit team and later incorporated into Minecraft, along with the other fixes.

Anyways, I also did a lot of investigating into the current issues, but haven't gotten enough time to put everything together until now. I found the source of two different bugs and was able to fix them (100% glitch free now as far as I can tell). I created a github repository containing an explanation, the mod, the source code and test worlds:

https://github.com/taurose/Unglitch

Summary of what I found:

  • Race Condition: When the collision boxes of certain blocks are generated, the min/max coordinates are sometimes saved to fields of the block object, and shortly after read again to create the AABB object used for collision checks. However, in SSP (or SSP opened to public), both the server and client threads do collision checks at the same time, using the same block objects. This can lead to false bounding boxes being generated (for example, server generates bounding box based on client's calculations on the same block but at very different coordinates).

  • Floating Point Error: During collision checks, Minecraft mainly works with the min/max coordinates of the entity's bounding box and writes the average (= center) to the entity's position fields at the end of each tick. When an entity is loaded, the min/max coordinates of its bounding box are recreated using those center coordinates. However, in certain, rare situations the recreated bounding box could slightly differ from the original one, possibly making mobs glitch into blocks.

My fixes:

  • Rewrote the code where the bounding boxes are generated to not rely on any values stored within the object.

  • Introduced an epsilon value for collision checks, which causes entities not to ignore collisions with blocks if they're barely inside of them (like 10^(-14), depending on the magnitude of the current coordinates and thus the possibly caused error).

@Daniel: I tested your mod with my worlds as well, but I found that it doesn't fix either of the problems. I took a look at your pushOutOfBlocks code, but since it relies on isBlockNormalCube() I wonder how it could work with fences and other blocks that are collidable, but return false for that method.