Jump to content

Threading issues with Block.setBlockBoundsBasedOnState


Sangar

Recommended Posts

I guess my question is this: is

Block.setBlockBoundsBasedOnState

meant to be sided (client/server only)? Because if it's not, then this method together with Minecraft's one-instance-per-block policy is a major design flaw when used in single player. Why? Because it usually sets the block instance's

(min)|(max)[XYZ] 

fields. On the one block instance used by both server and client thread.

 

Essentially what my problem boils down to is this:

- Server thread calls block's

setBlockBoundsBasedOnState

, sets

Block.minX

, ... to whatever based on the server's world state.

- Server does some other stuff / OS decides to pause the server thread.

- Client thread calls

setBlockBoundsBasedOnState

and sets the bounds to something else, based on the client's world state.

- Server thread continues doing stuff, does something based on the block bounds which are now the client's bounds, not the server bounds. Which leads to stuff breaking. Badly.

 

What I'm doing, specifically, is using world.clip to check if a ray intersects some blocks with possibly dynamic bounds. Am I using

setBlockBoundsBasedOnState

wrong, or is this just how it is and I simply have to throw a bunch of

synchronize

s into my code?

Link to comment
Share on other sites

Yeah. I overrode

collisionRayTrace

and synchronized it with

setBlockBoundsBasedOnState

in my block that I had the problem with. Haven't run into the issue since, but since it's a threading issue I'll keep an eye on it for it a bit longer...

 

Some context: I have a block that "moves", interpolating its bounding box while in transit. I'll not get into the details, to keep this short, but I don't want raytraces that originate in that block to hit it. That check looks like so:

override def collisionRayTrace(world: World, x: Int, y: Int, z: Int, origin: Vec3, direction: Vec3) = {
  // Set interpolated bounds for server/client.
  setBlockBoundsBasedOnState(world, x, y, z)
  // Get interpolated bounds, should be server/client, could be the other.
  val bounds = getCollisionBoundingBoxFromPool(world, x, y, z)
  if (bounds.isVecInside(origin)) null
  else super.collisionRayTrace(world, x, y, z, origin, direction)
}

 

Before synchronizing it sometimes incorrectly got hit, because the animation on the client was a bit behind the server (the movement gets triggered by a network packet).

 

Sounds confusing? Yep. This was quite the pain to track down...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.