-
Bug
-
Resolution: Fixed
-
Minecraft 1.7.9, Minecraft 14w20b, Minecraft 14w21a, Minecraft 14w21b, Minecraft 1.7.10-pre1, Minecraft 1.7.10-pre2
-
None
-
Community Consensus
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