mojira.dev
MC-56541

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.

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

Linked issues

Comments 15

Dlawso the Really Lucky Rabbit

Related to MC-54216

Exact 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.

5 more comments

@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.

Evan A. Haskell

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.

Frank Steffahn

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.

Anthony Thyssen

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/

Panda4994

migrated

Community Consensus

Minecraft 1.7.9, Minecraft 14w20b, Minecraft 14w21a, Minecraft 14w21b, Minecraft 1.7.10-pre1, Minecraft 1.7.10-pre2

Minecraft 14w25a

Retrieved