When the difficulty is set to peaceful, trial spawners will never try to spawn mobs and will get stuck in the waiting_for_players state. This occurs even with passive mobs such as a pig, which is inconsistent with regular monster spawners.
There was a similar bug report about this MC-266556, however this wasn't properly fixed as now the trial spawner gets stuck in the waiting_for_players state and won't actually try to spawn mobs, instead of staying inactive
Steps to reproduce:
Set the difficulty to peaceful
Place a trial spawner in a grassy area
Right-click on the trial spawner with a pig spawn egg
Go into survival mode
Look at the trial spawner with the F3 screen enabled
Notice how the trial_spawner_state never changes from waiting_for_players
Expected result:
The trial spawner should go into the active state and spawn mobs which are passive.
Code analysis:
In net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerState#tickAndGetNext
, when the state is WAITING_FOR_PLAYERS the TrialSpawner#canSpawnInLevel
method is called.
case 1 -> {
if (!trialSpawner.canSpawnInLevel(serverLevel)) {
trialSpawnerData.resetStatistics();
yield this;
}
if (!trialSpawnerData.hasMobToSpawn(trialSpawner, serverLevel.random)) {
yield INACTIVE;
}
trialSpawnerData.tryDetectPlayers(serverLevel, blockPos, trialSpawner);
if (trialSpawnerData.detectedPlayers.isEmpty()) {
yield this;
}
yield ACTIVE;
}
The canSpawnInLevel
method in net.minecraft.world.level.block.entity.trialspawner.TrialSpawner
always returns false on peaceful difficulty and doesn't check if the mob is passive, resulting in the spawner never trying to spawn passive mobs
public boolean canSpawnInLevel(ServerLevel serverLevel) {
if (this.overridePeacefulAndMobSpawnRule) {
return true;
}
if (serverLevel.getDifficulty() == Difficulty.PEACEFUL) {
return false;
}
return serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING);
}
Can confirm this behavior in 1.21.3