fenomas / noa

Experimental voxel game engine.
MIT License
608 stars 86 forks source link

Bug - player sometimes gets placed in adjacent solid blocks when building down #152

Closed MCArth closed 3 years ago

MCArth commented 3 years ago

image

I can repro on https://andyhall.github.io/noa-examples/test/ (where this screenshot is)

No idea why it happens. It think it might be only happening within the first 20/30 blocks of digging down? If it hasn't happened by then I haven't managed to make it happen lower down.

Steps:

  1. Dig down bit
  2. Stand in corner of hole
  3. Continue digging down
  4. Wait till you glitch into an adjacent block

https://user-images.githubusercontent.com/26874892/104848244-fa93bb80-58db-11eb-82bd-ced559f9d1dd.mp4

fenomas commented 3 years ago

Hi, thanks for the video - I see what's happening and can now reproduce this reliably. I'm also seeing that it only happens right around Y=-24 or so... which is... really weird 😅

I'll have a look...

fenomas commented 3 years ago

Okay, this turns out to stem from how the world periodically rebases its coordinate system, to avoid floating point error. When the entity's edge was right up to a voxel boundary at the time of the rebase, math error could cause its extents to end up crossing a voxel boundary. By default the rebase happens when you move a distance of 25 voxels, so that explains the distance - but why it wasn't happening on subsequent rebases, I'm not sure.

I whipped up a fix which is a bit of a hack. If I can't think of a more robust fix I'll push it to develop soon.

One side effect is that the hack would fail on an entity whose width is precisely an integer number of voxels. But I guess the engine should probably throw a warning in cases like that - if an entity that's exactly one voxel wide gets itself into a one-voxel gap, it's probably unavoidable that it will wind up crossing over one or the other voxel border...

MCArth commented 3 years ago

Great - thanks for looking into this 😄

fenomas commented 3 years ago

Hi, this should now be fixed in #develop. Basically when rebasing, the engine will check if an entity is right on a voxel border, and if so nudge it away by a small epsilon before rebasing. Thanks for finding this!

MCArth commented 3 years ago

Great, I'll close this then.