Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-217834

Copper takes longer to oxidize when other copper in the same stage is around it

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Works As Intended
    • None
    • 21w08b
    • None
    • Community Consensus
    • (Unassigned)

      Hello! It's been a while. Sorry if this feature has already been reported, but the search feature isn't very good and I also had a hard time coming up with a good brief keyword to search this by

      As we know, copper has been changed to oxidize based on random ticks, and Mojang cleverly implemented a system to keep the "wave" effect the old oxidizing system had, by pausing copper oxidation to let others "catch up". But if you place many copper blocks next to each other, it takes much longer than one copper block on its lonesome, even if they all are on the same level and shouldn't pause each other.

      Yes, I know that copper in a different stage nearby directly speeds up the copper. This is NOT what I am referring to. I'm specifically referring to copper in the same stage nearby causing a slowdown, which makes no sense. I analyze the code later and determine there is definitely something missing.

      HOW TO REPRODUCE
      Take one copper block, place it on the ground
      Place a large cube of copper blocks using /fill or by hand. Do something 4x4x4 or larger. Make sure the cube is at least 4 blocks away from the single copper.
      Set random tick speed to 5000

      Observe: The singular block oxidizes immediately but the ones in the cube take a very, very long time even though the random tick speed is up. According to the code, the copper should go a little faster to "keep up" with the block which oxidized, but due to the missing checks for copper in the same stage, it takes much longer instead. 

       

      I know why this happens, so if it's a bug the devs know exactly where to go to fix it. Let's look at the code.

         default void tryDegrade(BlockState state, ServerWorld world, BlockPos pos, Random random) {
            int i = this.getDegradationLevel().ordinal();
            int j = 0;
            int k = 0;
            Iterator var8 = BlockPos.iterateOutwards(pos, 4, 4, 4).iterator();      while(var8.hasNext()) {
               BlockPos blockPos = (BlockPos)var8.next();
               int l = blockPos.getManhattanDistance(pos);
               if (l > 4) {
                  break;
               }         if (!blockPos.equals(pos)) {
                  BlockState blockState = world.getBlockState(blockPos);
                  Block block = blockState.getBlock();
                  if (block instanceof Degradable) {
                     Enum<?> enum_ = ((Degradable)block).getDegradationLevel();
                     if (this.getDegradationLevel().getClass() == enum_.getClass()) {
                        int m = enum_.ordinal();
                        if (m < i) {
                           return;
                        }
                        if (m > i) {
                           ++k;
                        } else {
                           ++j;
                        }
                     }
                  }
               }
            }      float f = (float)(k + 1) / (float)(k + j + 1);
            float g = f * f * this.getDegradationChanceMultiplier();
            if (random.nextFloat() < g) {
               world.setBlockState(pos, this.getDegradationResult(state));
            }
         }
      > Code provided from the Fabric Loom decompiler

      As we can see, this code gets all blocks within 4 blocks of each direction. We can see if any copper that can degrade is in a lower stage, "return;" is called to stop the oxidizing process so it can wait for the other blocks to "catch up".

      If another copper is in a higher stage, K is added to, meaning the float value that stores the final chance of it oxidizing to the next stage, "g", becomes higher, effectively speeding up the oxidizing a little. However, if neither conditions are met for that copper block, that means the copper block being checked is in the same copper oxidation stage. We can see it then adds to the value "j". This causes the chance to get divided downwards for every copper block in the same stage that is nearby in the 4x4x4 radius, making the copper oxidize exponentially slower for every copper block in that range that's in the same oxidizing stage, which makes no sense.

      This doesn't seem quite right, this seems like an oversight to me.

            Unassigned Unassigned
            Roadhog360 Roadhog360
            Votes:
            4 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: