Redstone torches (and other redstone components) have inconsistent timings
Redstone torches, wood/stone/iron/gold pressure plates, wood/stone buttons, tripwire and detector rails sometimes skip (or shorten) their delay due to random ticks.
There might even be more things affected by this bug but this is what we found so far.
It's easy to show it in the snapshots since you can use the gamerule randomTickSpeed. Just to make sure: The bug also appears if the randomTickSpeed is on the default value (3). The gamerule is just to make it more likely and nicely visible.
Steps to reproduce
1. Place a chain of redstone torches.
2. Set the randomTickSpeed really high: "/gamerule randomTickSpeed 50000"
3. Power the first torch in the chain so that the others change their state, too.
What I expect to happen:
The torches change their state with the normal delay.
What really happened:
The torches change their state almost instantly.
This video shows how to reproduce it for the other affected components: https://www.youtube.com/watch?v=JBICFHdTBNk&list=PLkg2LgCHsnWUtCmXSYzGwaG76J0om_T2z
The timing of redstone components shouldn't rely on random ticks but be consistent so you can work with it.
Possible fix in short:
Make the affected blocks only process random ticks if there are no scheduled ticks queued up for them.
Possible fix (in 5 steps):
1. Add an extra method to Block.java which should get called for random ticks instead of the normal update method.
On default this method should just call the other one. So normal behavior stays the same.
[…] /** * Performs a random update tick on a block. */ public void randomTick(Level level, int x, int y, int z, Random rand) { this.updateTick(level, x, y, z, rand); } [...]
2. In the "server-subclass" of Level.java (One of the main classes. It has a server and a client subclass) change the call it does on Block.java for randomTicks to the method from step one.
3. Add a method to Level.java
On default it can just return false.
[...] /** * Checks if a scheduled update is waiting to get processed for a certain block. */ public boolean scheduledUpdateOnTheWay(int x, int y, int z, Block block) { return false; } [...]
4. In the server subclass of Level.java we override the method to check if a block is getting ticked already. For the client subclass we just don't override it.
[...] @Override public boolean scheduledUpdateOnTheWay(int x, int y, int z, Block block) { return this.pendingTickListEntriesHashSet.contains(new NextTickListEntry(x, y, z, block)); } [...]
5. In the classes of blocks which are affected by the bug we override the randomTick-method to only perform an update tick if there is no scheduled tick waiting to get processed.
[...] @Override public void randomTick(Level level, int x, int y, int z, Random rand) { if (!level.scheduledUpdateOnTheWay(x, y, z, this)) { this.updateTick(level, x, y, z, rand); } } [...]
In MCP the classes I changed in this step are called:
- BlockRedstoneTorch.java
- BlockButton.java
- BlockBasePressurePlate.java
- BlockRailDetector.java
- BlockTripWire.java
- BlockTripWireHook.java (I'm not sure if it's needed here but it wouldn't hurt either)
Thanks for your time ![]()
- Panda
Created Issue:
Redstone torches (and other redstone components) have inconsistent timings
Redstone torches, wood/stone/iron/gold pressure plates, wood/stone buttons, tripwire and detector rails sometimes skip (or shorten) their delay due to random ticks.
There might even be more things affected by this bug but this is what we found so far.It's easy to show it in the snapshots since you can use the gamerule randomTickSpeed. Just to make sure: The bug also appears if the randomTickSpeed is on the default value (3). The gamerule is just to make it more likely and nicely visible.
Steps to reproduce
1. Place a chain of redstone torches.
2. Set the randomTickSpeed really high: "/gamerule randomTickSpeed 50000"
3. Power the first torch in the chain so that the others change their state, too.What I expect to happen:
The torches change their state with the normal delay.What really happened:
The torches change their state almost instantly.This video shows how to reproduce it for the other affected components: https://www.youtube.com/watch?v=JBICFHdTBNk
The timing of redstone components shouldn't rely on random ticks but be consistent so you can work with it.
Possible fix in short:
Make the affected blocks only process random ticks if there are no scheduled ticks queued up for them.Possible fix (in 5 steps):
1. Add an extra method to Block.java which should get called for random ticks instead of the normal update method.
On default this method should just call the other one. So normal behavior stays the same.Level.java[…] /** * Performs a random update tick on a block. */ public void randomTick(Level level, int x, int y, int z, Random rand) { this.updateTick(level, x, y, z, rand); } [...]2. In the "server-subclass" of Level.java (One of the main classes. It has a server and a client subclass) change the call it does on Block.java for randomTicks to the method from step one.
3. Add a method to Level.java
On default it can just return false.Level.java[...] /** * Checks if a scheduled update is waiting to get processed for a certain block. */ public boolean scheduledUpdateOnTheWay(int x, int y, int z, Block block) { return false; } [...]4. In the server subclass of Level.java we override the method to check if a block is getting ticked already. For the client subclass we just don't override it.
WorldServer.java[...] @Override public boolean scheduledUpdateOnTheWay(int x, int y, int z, Block block) { return this.pendingTickListEntriesHashSet.contains(new NextTickListEntry(x, y, z, block)); } [...]5. In the classes of blocks which are affected by the bug we override the randomTick-method to only perform an update tick if there is no scheduled tick waiting to get processed.
Block*.java[...] @Override public void randomTick(Level level, int x, int y, int z, Random rand) { if (!level.scheduledUpdateOnTheWay(x, y, z, this)) { this.updateTick(level, x, y, z, rand); } } [...]In MCP the classes I changed in this step are called:
- BlockRedstoneTorch.java
- BlockButton.java
- BlockBasePressurePlate.java
- BlockRailDetector.java
- BlockTripWire.java
- BlockTripWireHook.java (I'm not sure if it's needed here but it wouldn't hurt either)
Thanks for your time
- Panda
is duplicated by
Redstone torches, wood/stone/iron/gold pressure plates, wood/stone buttons, tripwire and detector rails sometimes skip (or shorten) their delay due to random ticks.
There might even be more things affected by this bug but this is what we found so far.It's easy to show it in the snapshots since you can use the gamerule randomTickSpeed. Just to make sure: The bug also appears if the randomTickSpeed is on the default value (3). The gamerule is just to make it more likely and nicely visible.
Steps to reproduce
1. Place a chain of redstone torches.
2. Set the randomTickSpeed really high: "/gamerule randomTickSpeed 50000"
3. Power the first torch in the chain so that the others change their state, too.What I expect to happen:
The torches change their state with the normal delay.What really happened:
The torches change their state almost instantly.This video shows how to reproduce it for the other affected components: https://www.youtube.com/watch?v=JBICFHdTBNk
The timing of redstone components shouldn't rely on random ticks but be consistent so you can work with it.
Possible fix in short:
Make the affected blocks only process random ticks if there are no scheduled ticks queued up for them.Possible fix (in 5 steps):
1. Add an extra method to Block.java which should get called for random ticks instead of the normal update method.
On default this method should just call the other one. So normal behavior stays the same.Level.java[…] /** * Performs a random update tick on a block. */ public void randomTick(Level level, int x, int y, int z, Random rand) { this.updateTick(level, x, y, z, rand); } [...]2. In the "server-subclass" of Level.java (One of the main classes. It has a server and a client subclass) change the call it does on Block.java for randomTicks to the method from step one.
3. Add a method to Level.java
On default it can just return false.Level.java[...] /** * Checks if a scheduled update is waiting to get processed for a certain block. */ public boolean scheduledUpdateOnTheWay(int x, int y, int z, Block block) { return false; } [...]4. In the server subclass of Level.java we override the method to check if a block is getting ticked already. For the client subclass we just don't override it.
WorldServer.java[...] @Override public boolean scheduledUpdateOnTheWay(int x, int y, int z, Block block) { return this.pendingTickListEntriesHashSet.contains(new NextTickListEntry(x, y, z, block)); } [...]5. In the classes of blocks which are affected by the bug we override the randomTick-method to only perform an update tick if there is no scheduled tick waiting to get processed.
Block*.java[...] @Override public void randomTick(Level level, int x, int y, int z, Random rand) { if (!level.scheduledUpdateOnTheWay(x, y, z, this)) { this.updateTick(level, x, y, z, rand); } } [...]In MCP the classes I changed in this step are called:
- BlockRedstoneTorch.java
- BlockButton.java
- BlockBasePressurePlate.java
- BlockRailDetector.java
- BlockTripWire.java
- BlockTripWireHook.java (I'm not sure if it's needed here but it wouldn't hurt either)
Thanks for your time
- Panda
Redstone torches, wood/stone/iron/gold pressure plates, wood/stone buttons, tripwire and detector rails sometimes skip (or shorten) their delay due to random ticks.
There might even be more things affected by this bug but this is what we found so far.It's easy to show it in the snapshots since you can use the gamerule randomTickSpeed. Just to make sure: The bug also appears if the randomTickSpeed is on the default value (3). The gamerule is just to make it more likely and nicely visible.
Steps to reproduce
1. Place a chain of redstone torches.
2. Set the randomTickSpeed really high: "/gamerule randomTickSpeed 50000"
3. Power the first torch in the chain so that the others change their state, too.What I expect to happen:
The torches change their state with the normal delay.What really happened:
The torches change their state almost instantly.This video shows how to reproduce it for the other affected components: https://www.youtube.com/watch?v=JBICFHdTBNk&list=PLkg2LgCHsnWUtCmXSYzGwaG76J0om_T2z
The timing of redstone components shouldn't rely on random ticks but be consistent so you can work with it.
Possible fix in short:
Make the affected blocks only process random ticks if there are no scheduled ticks queued up for them.Possible fix (in 5 steps):
1. Add an extra method to Block.java which should get called for random ticks instead of the normal update method.
On default this method should just call the other one. So normal behavior stays the same.Block.java[…] /** * Performs a random update tick on a block. */ public void randomTick(Level level, int x, int y, int z, Random rand) { this.updateTick(level, x, y, z, rand); } [...]2. In the "server-subclass" of Level.java (One of the main classes. It has a server and a client subclass) change the call it does on Block.java for randomTicks to the method from step one.
3. Add a method to Level.java
On default it can just return false.Level.java[...] /** * Checks if a scheduled update is waiting to get processed for a certain block. */ public boolean scheduledUpdateOnTheWay(int x, int y, int z, Block block) { return false; } [...]4. In the server subclass of Level.java we override the method to check if a block is getting ticked already. For the client subclass we just don't override it.
WorldServer.java[...] @Override public boolean scheduledUpdateOnTheWay(int x, int y, int z, Block block) { return this.pendingTickListEntriesHashSet.contains(new NextTickListEntry(x, y, z, block)); } [...]5. In the classes of blocks which are affected by the bug we override the randomTick-method to only perform an update tick if there is no scheduled tick waiting to get processed.
Block*.java[...] @Override public void randomTick(Level level, int x, int y, int z, Random rand) { if (!level.scheduledUpdateOnTheWay(x, y, z, this)) { this.updateTick(level, x, y, z, rand); } } [...]In MCP the classes I changed in this step are called:
- BlockRedstoneTorch.java
- BlockButton.java
- BlockBasePressurePlate.java
- BlockRailDetector.java
- BlockTripWire.java
- BlockTripWireHook.java (I'm not sure if it's needed here but it wouldn't hurt either)
Thanks for your time
- Panda
is duplicated by
relates to
It is probably the same as MC-56541 which ZipKrowd members Kabo and Panda have provided a fix for,
OP (Chris) can you upload a zipped version of your world? Coders and mods are busy people and are more likely to implement a fix when you do as much of the work as possible, as demonstrated by MC-56541, which was reported and resolved within a week. Well, it could also be because of the cliquey, in-crowd nature of the Mojang inner circle (it seems the same crap the jocks were doing in high school is now the province of the nerds), but that could just be my suspicious nature talking.
Christopher, it's easier to build the setup from the picture then to download a world that contains it. MC-56541 got fixed so quickly because it was uploaded by a popular youtuber who asked the viewers to vote on the bug.
I guess it would help if I would provide a fix for this bug, but I'm not a coder, so I can't. So for now, votes are the only thing that help.
In response to Torabi and continuing from the old MC-6438 conversation:
"You say the behavior in MC-51662 is new, but how does it differ from MC-26356 (aside from yours being better written)?", Torabi
All tick variations now seem to break blocks (not just 2 as in MC-26356). Shorter ticks seem to result in more pulses, resulting in a higher chance of the block breaking, but all tick lengths, when spammed, break blocks.
"What did the sand do before?", Torabi
It didn't break. In the latest 1.7 version witch farms work all day without issue.
"You say there that "In snapshots up until 14w10c the piston disappears", so when did it actually work?", Torabi
It worked in every release of 1.7 before the 14w branch, and in all versions of 1.7 after the fork. From 14w04a MC-46225 started breaking the machines. Then, from 14w11b machines were breaking because of both MC-46225 and MC-51662.
Unfortunately, this issue is now four months old for me, so my imperfect memory is now a complication. The description should likely read:
"In snapshots up until 14w10c the piston disappears (as in MC-46225), but from 14w11b the piston now can display either behaviour, either disappearing as in MC-46225 or breaking sand as described above."
If that makes sense to you I will update the description.
Also, the behaviour has evolved over the snapshots. In 14w11b the blocks break aggressively while you are present, now it takes a two tick pulse to do it in front of you, but a chunk unload, by teleporting away or portal travel, triggers it (or MC-46225) fairly predictably (as long as you are aware of the spawn chunks and take their impact into account) no matter the pulse length.
Really, the best bet at this stage is to download the machine from MC-46225 (it has many improvements so I'll post it here too and remove the old one) and load it into 14w11b and step forward from there, as the behaviour seemed to subtly evolve over time. If you need me to do that process it will have to wait until the weekend for me to have enough time to dedicate to that sort of testing.
As of 14w25b, it is much more likely for the sand to break than piston disappear. I can't even get pistons to disappear in the test world on SP any more, but if I download our server files to a local test server and run them in 14w25b they do disappear on chunk unloads, but not at the same rate they used to (circa 14w10c).
"Regardless, both are likely caused by one of the following:
Sand falling onto a moving (extending or retracting) piston head, treating it like a non-solid block (such as a torch, rail, etc) and breaking.
Sand falling into an extending/extended piston head (MC-4789) and breaking because it has nowhere to land (MC-6438).
Sand falling into the empty space while the piston is retracted, and breaking rather than being pushed when it extends.
I think that falling sand, as an entity, would be pushed by the piston, and only break when landing on a non-solid block.", Torabi
I concur that all of these are possibly related. It needs a serious investigation to straighten it out. There may be an underlying tick processing issue, as was recently demonstrated by Panda in reference to Redstone Torch processing (MC-56541).
Related to
MC-54216Exact duplicate even, but this one is more detailed. Making it the main ticket.
@Mustek Sorry, I must have overlook the other post. Thanks for linking it
Hopefully this gets fixed soon.
This is a real problem, hopefully it will get fixed soon.
@Panda I did some testing as well, and very, very rarely, this seems to happen with daylight sensors too.
@Panda
Minor typo in the main report, but it makes it confusing. You labeled the code which should be "block.java" "level.java".
It should be this:
Thanks.
@Pokechu22 Thank you I changed it.
I found two more bugs which refer to the same issue:
https://bugs.mojang.com/browse/MC-9033
https://bugs.mojang.com/browse/MC-18450
@Panda I would prefer it if random and scheduled update ticks had completely separate methods if possible, I was making a mod and could not have random and scheduled ticks on the same blocks. Your fix would prevent random updates while waiting for scheduled and that would limit potential functionality. Adding the new function and having the random update selector call a different method would make it cleaner and then refactoring blocks using natural updates, dirt, farmland, ice ect.
@Tristan That's what we recommended in the post too. A new method in block for random updates.
We just would make it call the normal update method on default as that makes existing functionality stay the same. Of course you could use them as different methods then too. That was also one of our thoughts. It allows for cleaner and more flexible programming of new features.
Also the limitation you are speaking of would just happen for the redstone components which are listed in the post. And for these you don't want random updates while they are still on the scheduled list because the random ticks for these redstone components are to make sure that they don't stay in a glitched out (for torches also burnded) state. But if there is a scheduled update on the list the thing isn't glitched out. Only if the scheduled update got lost somehow and the component is in an invalid state it needs to be "fixed" by a random update.
Or it could be changed to avoid randomly ticking certain blocks which it already does. See the bottom of g() at https://github.com/Bukkit/CraftBukkit/blob/master/src/main/java/net/minecraft/server/WorldServer.java (line 402 depending on when you're viewing it). Each block has an isTicking method which returns whether the block should be affected by random block ticking. Among other blocks, redstone torches return true. It just needs to be made to return false. But, as said by Panda, if random ticking is needed, then it should be made to check if the block is already queued.
I'm glad this was reported. I've often encountered torches behaving oddly and found that changing isTicking to false fixed the problems I was having.
You need random ticks for reactivating redstone torches after burnout, because .. it has always been like this.. well by the way I don't even know any use of this feature (exept a really impractical and buggy random number generator I once built), so it should be OK if they don't reactivate with random ticks after they burned out. This change would also turn some compact piston doors I've seen, which use torch burnout mechanics, 100% reliable and less buggy! So I believe it could be great if simply the redstone components don't receive the random ticks at all.
Testing it in 14w25b, burnt out redstone torches no longer reactivate without receiving a block update. So they do ignore random ticks altogether now. I had been using them as random approximate-minute-period clocks (mainly because they consume essentially no server resources whatsoever when idle, unlike hopper clocks), so it wasn't a completely useless mechanic. Oh well.
Are burnt out torches still being randomly updated to repair? A report on redit seems to indicate the they just stopped random update repair!
http://www.reddit.com/r/Minecraft/comments/28vnpy/