Posted December 5, 201311 yr 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?
December 5, 201311 yr Hi I think you might be right. setBlockBoundsOnState is used mostly for rendering but also for collision/hit detection on the server eg arrow. Guess they hope that nobody will notice in-game. Have you tested it to verify? -TGG
December 6, 201311 yr Author 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...
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.