Jump to content

[1.12] Block isn't updating on the client, but only sometimes


Dream

Recommended Posts

I have a block (Block A) that turns into another block (Block B) when the player walks on it. When the player walks off of Block B, Block B turns back into Block A.

 

Here's the code from Block B that changes it back into Block A.

 

Spoiler

public BlockB() {
        super(Material.ROCK);
        this.setTickRandomly(true);
}

@Override
public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) {
	worldIn.scheduleBlockUpdate(pos, this, 20, 0);
}

@Override
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) {
	if (!worldIn.isRemote) {
		int x = pos.getX();
		int y = pos.getY();
		int z = pos.getZ();
		EntityPlayer player = worldIn.getClosestPlayer(x, y, z, 2, false);
		AxisAlignedBB boundingbox = new AxisAlignedBB(x, y, z, x+1D, y+1D, z+1D);

		worldIn.scheduleBlockUpdate(pos, this, 20, 0);

		if (worldIn.getEntitiesWithinAABB(EntityPlayer.class, boundingbox).size() < 1) {
			worldIn.setBlockState(pos, ModBlocks.block_a.getDefaultState(), 3);
		}
	}
}

 

 

It works, however sometimes the block change from Block B to Block A doesn't appear on the client. The server recognizes the change, but the client can't see it until reloading. It happens with about 1 in every 10-15 blocks walked on and off on a dedicated server, and only rarely like 1 in 50 blocks in singleplayer. Walking on them again resets them to Block B and they work like normal again.

 

Anyone know why this happens? Thanks.

Edited by Dream
Link to comment
Share on other sites

Are you doing the tick just for detecting the entity, or also doing other stuff?

 

I think that the problem is probably that you're missing it somehow -- the tick processing is only happening about once per second so maybe the player is already past the block sometimes? But if the server processes it it is still strange that it is not synced. Maybe the chunk needs to be updated or something...

 

However, I would suggest doing it another way. The Block class already has an onEntityWalk() method. I think you can forget the tick stuff and just have your block change in that method. The method will give you the entity type so you can check for if it is a player or not.

 

This method is what is used to make stairs work, and to bounce on slime, and so forth.

Edited by jabelar

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

9 minutes ago, jabelar said:

This method is what is used to make stairs work

No its not. Stairs work by having two collision volumes and the player's step-height.

 

I suggest looking at Redstone Ore

Edited by Draco18s

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

33 minutes ago, Draco18s said:

No its not. Stairs work by having two collision volumes and the player's step-height.

Well, BlockStairs does override this method. I guess you're right that the actual functionality might not be in there, but they still thought (or at some point during development in the past thought) that it would be a useful method for stairs. 

 

Anyway, my point is that this is a commonly used method for detecting walking on. There are many examples, magma, slime, redstone ore, and so forth that do actual functionality within that method.

Edited by jabelar

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

30 minutes ago, jabelar said:

Well, BlockStairs does override this method. I guess you're right that the actual functionality might not be in there, but they still thought (or at some point during development in the past thought) that it would be a useful method for stairs. 

    public void onEntityWalk(World worldIn, BlockPos pos, Entity entityIn)
    {
        this.modelBlock.onEntityWalk(worldIn, pos, entityIn);
    }

The method just forwards the interaction to the base block (e.g. if you were to make Redstone Ore stairs, this would cause the block to switch from not-glowing to glowing...assuming of course that the Redstone Ore class knows how to handle the block at the given pos not being redstone ore).

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Thanks for the suggestions. Redstone Ore sets the tick rate differently than my Block B. Block B also checks if a player is standing on it before changing back into Block A. It seems to be successfully checking for the player, so that leads me to believe that the problem might be the tick rate.

 

Redstone Ore's tick rate is too slow for this block since it takes a minute or two to change instead of a few seconds. This is the Redstone Ore tick rate:

Spoiler

public int tickRate(World worldIn)
    {
        return 30;
    }

 

I used this and changed the return to a variety of numbers between 1 and 100, but no change seemed to make a difference in how long they took to change back to Block A. What am I missing about changing this value? For example, this is the updated code using the Redstone Ore tickRate instead of the scheduled updates in the original code:

Spoiler

public BlockB() {
        super(Material.ROCK);
        this.setTickRandomly(true);
}

@Override
public int tickRate(World worldIn) {
        return 1;
    }

@Override
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) {
	if (!worldIn.isRemote) {
		int x = pos.getX();
		int y = pos.getY();
		int z = pos.getZ();
		AxisAlignedBB boundingbox = new AxisAlignedBB(x, y, z, x+1D, y+2D, z+1D);

		if (worldIn.getEntitiesWithinAABB(EntityPlayer.class, boundingbox).size() < 1) {
			worldIn.setBlockState(pos, ModBlocks.block_a.getDefaultState(), 3);
		}
	}
}

 

 

I don't understand why the tick rate would change whether or not the client gets the setBlockState change even though the server does. If it isn't a problem with the tick rate, is it a problem with setBlockState?

 

There are plenty of examples of blocks being walked on (and Block A is using onEntityWalk to turn into Block B), but not many (any?) that detect not being walked on. Lit Redstone Ore doesn't actually detect if you stopped being on it or not, it invariably resets itself to off after a minute or two. I tested that by making a small enclosed space with a Redstone Ore block in the middle of the floor, stood on it, and waited. Eventually the light flickered for a split second, and again every minute or two. It doesn't actually check if you're there, just turns itself off and then the unlit ore turns back into the lit ore almost instantly. So that's why I'm checking if the player is there first or else it flickers between blocks a lot since I want it to change much faster than Redstone Ore.

Edited by Dream
Link to comment
Share on other sites

You know that the tickRate method is called by dick and jack, right? It's completely unused by the outside world. The only thing that calls it is a block itself to call scheduleUpdate() with.  The only non-block that references this function is the CommandBlock (to scheduleUpdates on spawned blocks) and BlockFluidFinite to determine how quickly its subclasses should flow (oh wait, its in the Block hierarchy).

 

Even within the Block hierarchy it goes virtually unused! BlockStair only uses it to pass off the call to the block that the stairs are made out of (so, basically nothing) as well as the Tripwire and TripwireHook (which actually do use it, again to scheduleUpdates ).

 

Seriously, put 9999999 in there and tell me if it makes any difference what so ever.

Edited by Draco18s

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Just now, Draco18s said:

You know that the tickRate method is called by dick and jack, right? It's completely unused by the outside world. The only thing that calls it is a block itself to call scheduleUpdate() with.  The only non-block that references this function is the CommandBlock (to scheduleUpdates on spawned blocks) and BlockFluidFinite to determine how quickly its subclasses should flow.

 

Seriously, put 9999999 in there and tell me if it makes any difference what so ever.

Exactly, it doesn't do anything. So I'm back where I started, using scheduled updates. And the setBlockState sometimes seemingly at random doesn't send the change to the client, because I can't figure out why.

Link to comment
Share on other sites

onBlockAdded -> schedule update -> replace self

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

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.

×
×
  • Create New...

Important Information

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