Mobs that normally react to sunlight will catch on fire in the end if there is no block above them and sufficient light at their head. This effects:
Zombies (and subclasses)
Skeletons (and subclasses)
Endermen (but note that the lighting has to be at head level; a torch at ground level does not produce enough light). Also note that the behavior of enderman is to randomly teleport when in sun, not to catch on fire; endermen lit in this way will teleport but unlit ones will not.
Might relate to:
MC-47365 ❓
Code analysis (@unknown):
The code that's responsible for mobs catching on fire hasn't any major logic changes since the mechanic was introduced (introduced Februrary 14th 2010 indev; it did change on February 18, 2010 indev but hasn't changed in a significant way since). Here is the logic for each entity:
AbstractSkeleton.java
public void onLivingUpdate()
{
if (this.world.isDaytime() && !this.world.isRemote)
{
float f = this.getBrightness();
BlockPos blockpos = this.getRidingEntity() instanceof EntityBoat ? (new BlockPos(this.posX, (double)Math.round(this.posY), this.posZ)).up() : new BlockPos(this.posX, (double)Math.round(this.posY), this.posZ);
if (f > 0.5F && this.rand.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.world.canSeeSky(blockpos))
{
boolean flag = true;
// Snip: logic to set flag to false if wearing a helmet
if (flag)
{
this.setFire(8);
}
}
}
super.onLivingUpdate();
}
EntityZombie.java
public void onLivingUpdate()
{
if (this.world.isDaytime() && !this.world.isRemote && !this.isChild() && this.shouldBurnInDay())
{
float f = this.getBrightness();
if (f > 0.5F && this.rand.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.world.canSeeSky(new BlockPos(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ)))
{
boolean flag = true;
// Snip: logic to set flag to false if wearing a helmet
if (flag)
{
this.setFire(8);
}
}
}
super.onLivingUpdate();
}
Note how in all cases it:
Checks if
world.isDayTime
Checks the brightness of the monster and compares it to .5 (this corresponds to light level 11, I think)
Checks whether the block can see the sky (this is a heightmap check, not effected by e.g. glass)
Does some RNG stuff
The brightness of the monster is computed by the max of the skylight (minus a factor) and block light. So, it can be above .5 even without sunlight if the monster is right next to a light source. Heightmap information is correct (the heightmap debug renderer can be used to verify this). So, that leaves only world.isDayTime
.
This method might have an incorrect name due to MCP, or it might be named similarly in the actual codebase; all it does is check whether skylightSubtracted
(the previously noted skylight offset factor) is less than 4. The logic responsible for setting that variable is somewhat convoluted (MCP method is World.calculateSkylightSubtracted
) but a key factor is the "celestial angle"; for the overworld this is a calculation of the position of the sun (I think) but the nether hardcodes it to return .5
always, and the end has it always return 0
. This actually causes the end to be considered daytime (0
and 1
are high noon, and .5
is midnight).
Basically, for some reason, the end is considered as being in daylight and thus mobs can burn. However, to me, it seems wrong that the code checks if it is day and then how bright the monster is to determine if they're exposed to sunlight; it would make much more sense to only check the sunlight value (modified by skylightSubtracted
) and use that to check whether they are exposed. That may not have been possible in indev, but it is now...
Linked issues
is duplicated by 2
relates to 1
Attachments
Comments 5
Hm, I initially remember having trouble with it, apparently back in 18w43a (the first 1.14 snapshot, which did the lighting engine rewrite). Though I thought I checked and it looked like the relevant code still existed, just with the lighting engine behaving differently. I'll look into it again.
Can confirm for MC 1.12.1.