mojira.dev
MC-217834

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

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.

Comments 16

This was marked as "Works as Intended". Why is this intended? This mechanic doesn't make much sense, why should copper take longer because other is around it?

I think it should be slowed down based on the amount of exposed faces, if anything. Even if you space out all copper within the detection zone to not touch, it takes a very long time compared to a lone block even if all faces are exposed, which seems pretty silly.

As no answer as been given on how this bug-like behaviour is intended, I'd like to offer a solution in the case it was incorrectly marked. If the mark is still someow correct, then ignore this, I guess.

if (m == i) {
continue;
    }

Could be added below the brackets with m < i, which would keep the chance the same instead of making oxidation slower for every copper block in the same stage. Other blocks that are below or ahead would still affect the chance.

Still no words on why this is intended? I still can't think of a single reason this makes sense at all.

its because larger area means you need more mass so its slower

 

6 more comments

Still awaiting developer confirmation, added further explanation to clarify that a missing check is probably needed.

Please stop, they do not have to explain their choices in public, and it's been months since this has been resolved. They aren't going to reply, at all. Lack of features doesn't make things a bug. The blocks get ticked, and then based on chance increase the oxidation state, that's how it works, that's how it is designed. There's nothing to imply the exposed faces not being considered is unintentional.

While there is nothing to imply this is intentional, there is nothing that implies it isn't either. This is not a lack of feature, but clearly missing functionality if you read my thorough explanation and realize this has nothing to do with exposed faces too.

look it up its intended stop trying to get a response because it has been documented in some changelogs.

Oh, I didn't know that, I only knew about changelogs which mentioned if the copper was in the further stage, or lower stage affecting the rates. Can I please see where this is documented?

Roadhog360

(Unassigned)

Community Consensus

(Unassigned)

21w08b

Retrieved