In certain fairly common situations, the game spawns mobs in caves at any depth as surface mobs and counts them toward the surface density cap. This can leads to fewer surface mobs and more cave mobs being spawned than intended, unbalancing the game. I have attached a world save file, "Surface & cave spawns.mcworld", that demonstrates this.
World Description:
The world has 3 locations you will use: A Spawn Room, a Testing Room, and the Surface. Command blocks are provided to teleport you between these locations.
The world is designed so that only monsters can spawn in it, and only on the spawn floor. (Technically, bats, slimes, and wandering traders can also spawne, but they're immediately killed by repeating command blocks.)
You spawn on the surface in front of a blue square centered in a yellow ring and, farther out, a purple ring. The spawn floor is at Y=6 below the blue square; it is one chunk in size. The purple ring encloses the density cap measurement area for spawns on the spawn floor; it is 9 x 9 chunks in size. The yellow ring encloses the area you need to stay within to prevent mobs from spawning outside the density cap area.
Except for the Spawn Room and the Testing Room, which are mobproofed, the density cap area is entirely filled with stone. This ensures that only monsters can spawn during the test and they can only spawn on the spawn floor. It also ensures that there are no unknown monsters taking up part of the density cap.
The Testing Room is at Y=30, just outside the spawn floor chunk. It's like an AFK room in that when the player is within it, all blocks of the spawn floor are within spawning range The Testing Room also has a lever that controls the "mobspawning" game rule, and a repeating command block that every 10 seconds reports what mobs are present on the spawn floor.
Steps to reproduce:
1. Open the attached world Surface & cave spawns.mcworld.
2. Press the button to teleport to the Spawn Room. Verify that there are no mobs on the spawn floor or in the mob holding pen. If there are, use the Kill All Mobs button to get rid of them.)
3. Go to the Testing Room and flip the lever to enable mob spawning. A repeating command block will start outputing a list every 10 seconds of any mobs found on the spawn floor. Wait until 8 mobs are listed; it should take less than 5 minutes. (The density cap for hostile mobs is 8, so no more will spawn if you wait longer.)
4. Disable mob spawning.
5. Go to the Spawn Room. You should see 8 mobs on the spawn floor. Use the button to teleport them to the holding pen. (Note that the pen is outside the spawn floor chunk, but still inside its density cap area.)
6. Go to the surface.
7. Place a stair, bottom slab, or leaves in front of the bottommost observer. Command blocks will replicate your block over the entire chunk, so that every block of the spawn floor has your block on the surface above it.
8. Return to the Testing Room and enable mob spawning again. Wait a few minutes to see if any monsters spawn.
Expected results:
Since the mob density cap is filled by the monsters in the holding pen, no more monsters spawn.
Actual results:
More monsters spawn, up to 8 of them if you wait long enough. What's happening is that the first set of 8 monsters were tagged as cave spawns and were counted under the cave density cap, which was filled to capacity. However, placing the blocks on the surface allowed another set of 8 monsters to be spawned and tagged as surface spawns. This can be verified by checking the Surface property of the entity for each mob.
Stairs, bottom slabs, and leaves are not the only blocks that cause cave spawns to become surface spawns. So far, other blocks I've identified that this do this include Farmland, Grass Path, Lantern, Chest, Cactus, Turtle Eggs, and Lectern. (Note that slabs are a special case: Top slabs do not cause surface spawns, only bottom slabs.)
It's particularly noteworthy that this bug will always cause spawns under farmland, village paths, trees, and platforms made of bottom slabs on the ground, no matter how deep the cave is. My experiments tell me that all that's required is to have an unbroken column of solid blocks, topped by one of the triggering transparent blocks, above the spawn block. As the demo world shows, this can cause surface spawns to occur at any depth, which can reduce the number of monsters spawning on the actual surface as well as increase the number of mobs found in caves.
Related issues
is blocked by
relates to
testing discovered
Attachments
Comments

Thank you for your report!
However, this issue has been temporarily closed as Awaiting Response
Is this still an issue in the latest version?
This ticket will automatically reopen when you reply.
Quick Links:
đ Issue Guidelines â đŹ Mojang Support â đ§ Suggestions â đ Minecraft Wiki

Yes, it is. Using my test world, I was able to spawn hostile mobs with Surface:1 at Y=40 and Y=8 in 1.12.1. Due to the change that limited mob spawning to a 54-block radius around the player, I had to adapt where I stood while waiting for them to spawn, but the issue still exists.

I attached a new demo world and rewrote the Description with steps that make it easier to reproduce the bug in a plainly visible way.
This appears to be fixed in 1.13.

It isn't fixed for me as of 1.13.Â

@unknown: What exactly do you see that tells you it's not fixed (I'm assuming you mean in 1.13.0.17)? The specific bug I was reporting, that monsters spawned in deep caves were being marked as surface mobs, no longer happens for me. Most players wouldn't be able to tell that without using a 3rd party tool or something similar to the world I attached. Did you use something like that? If so, what did you find from it?
Although it does appear that the reported issue was fixed, the way they fixed it was to not allow monsters to spawn at all if the surface has a bottom slab, stair, etc. on it. I don't think that was a good idea: It means you can now create a perimeter just by slabbing the surface and not bothering to light up caves at all. I will be creating a new ticket for that.
There's also a problem with lighting that was introduced, and it's severe. Apparently, if there's a stair or bottom slab on the surface, any solid block below, all the way to bedrock, will have sky light if it has air above it. My cave at Y=6 is sealed, but it's light or dark depending on what time of day it is. I will creating another ticket for that.

After studying the lighting problem, I realize now that it was that that give the appearance of this bug being fixed, and also caused no monsters to spawn after stairs were placed on the surface above my spawn floor at Y=6.
This bug is not fixed! When I placed stairs above the spawn floor, nothing spawned (because of MCPE-52887), but after I reloaded the world monsters started spawning again (because it caused all lighting to be recalculated). And the monsters that spawned were once again tagged as surface mobs. Note that MCPE-52887 makes this look like it's fixed, until you unload and reload the world after placing stairs on the surface.

It is worth noting that if âsurfaceâ did not mean âthe first solid block directly under empty blocksâ (rather than just âthe first solid block under the skyâ), then youâd have cave spawns under tree limbs.
I doubt there is a consistent logic that captures what we intuitively think of as surface. Iâm ok with the current system, but not with so many kinds of blocks triggering âundergroundâ surface spawns. Maybe it could be reduced to just leaves, unless there is some compelling reason to include other blocks.

I think reducing the test to just leaves wouldn't work very well. That would produce caves spawns in lots of places we think of as "surface", most pointedly inside buildings, under roofs, and under any cantilevered or floating structure, such as a mob farm build high above the ground.
Slabs and stairs trigger surface spawns because experienced players almost always use them to build roofs. I think those should be kept as triggers, at least. I would just suggest that there should be a limit (say, 20 blocks) to how far below them a spawn can be surface, and also an absolute check that the Y level is no lower than, say, 60, because it's very rare that the actual dry surface is ever below that. But I'm not sure how to handle water mobs; they might need different rules.

This ticket was left open pending fixes for several related issues that it interacted with. Those issues have since been closed and there have been no further reports of this problem, nor can I reproduce it in 1.14.0, so I am resolving this issue and closing the ticket at this time.

I did some testing and have found that in 1.14 slabs, stairs, leaves, and farmland on top of solid blocks no longer trigger surface spawns underneath. However, carpet still does!
Consequently:
If you have a monster farm that was designed to take advantage of surface spawns in a dark, enclosed area during the day, you will  need to replace the slabs or or whatever on the top with carpet.
Monsters now spawn on top of stairs, leaves, etc. Theyâve been all over the roofs of my village. Not sure if this applies to naturally generated tree leaves, but it definitely applies to placed leaves. Lower slabs and carpet are the only spawn-proof blocks as far as I can tell.
In my opinion, theyâve swung the pendulum too far in the other direction. At least we still have carpetâ maybe donât tell the devs they overlooked it!
Edit: Just realized you are now tracking this at MCPE-58670 and MCPE-54241.

Reopening because the fix for MCPE-59682 in 1.14.20 Hotfix caused a regression of this issue and added a new problem.
What happens now is that when the surface top block is a slab, stair, glass, or leaves, the first spawnable space below it will spawn a cave mob (that's the new problem) and subsequent spawnable spaces below that will spawn a surface mob.
The impact is that mobs spawning below a transparent block on the surface will be regulated by the wrong density cap, so the number of mobs spawned near the surface is skewed upward while the number spawned deeper in caves is skewed downward.
Edit: The preceding observations were made with a test environment that was set up wrong. They should be disregarded. I have corrected and re-tested, and the results now appear below.

I cannot reproduce the above behavior in my tests (see attached world and screencap). When slabs pass the surface spawns down, the next available spawning location is a surface spawn, and those after that are not. I believe that the spawning algorithm has reverted back to 1.13 mechanics. Patrols and other surface only mobs are likely to spawn inside bases and in caves again.
[media][media]
@unknown: Very interesting! The reason your results are different is apparently because you are only set up to test animal mobs, while I only tested monsters. That suggests that animal and monster spawns use two distinct versions of the surface/cave identification logic, something I never knew before and something that makes this whole issue even more intricate.
 I'm going to modify my test rig to work for animals instead of monsters and see if I get the same results as you. Meanwhile, I'd appreciate it if you could translate "reverted back to 1.13 mechanics" into specific differences I should be testing for. There's no way I can trust my memory of how 1.13 spawning worked.

Ok, I can confirm that I get the same results as you for animal mobs.

Note: I've looked at a disassembly of core spawning functions and I'm not finding any differences between 1.13 and 1.14.20.
Monsters are harder to test since they spawn on both the surface and cave. However, monsters and passive mobs are by the same algorithm. If looking at hostile mobs that can spawn on both the surface and cave, its best to check the NBT to see what they are marked as.
Theses are the changes to spawning in 1.14.
1.14.0: surface spawn attempts are no longer passed downwards by non-spawn blocks (glass, leaves, bottom slabs, etc.) Carpet is the one exception. A side effect of this change is that non-spawn blocks (except bottom slabs) now spawn mobs.
1.14.1: non-spawn blocks (except carpet) that are the block with sky access no longer spawn mobs. A side effect of this change is that they also block all spawning for that tick in that chunk.
1.14.20: the changes to spawning in 1.14.0 and 1.14.1 are reversed and the mechanics are back to 1.13. Slabs etc pass surface spawns attempts down.

I test this stuff with 3 1-chunk stone platforms over a lava ocean that is wider than the density check area. 2 of the platforms are positioned one over top the other so that the bottom one is always cave. Over these 2 I put a roof and try different transparent blocks on top of the roof. The third platform is diagonal to the other two and open to the sky. This setup allows comparison of surface and cave monster spawns with different rooftops.
Update: I can confirm the behavior Reed Cartwright describes, that we have reverted to 1.13 behavior with non-solid blocks passing surface spawns down to the next solid block with air above it. I tested carpet, lower half-slabs, leaves, glass, and fence posts, in the setup described above, and each time got 8 total spawns between the two "surface" platforms, and 8 spawns on the cave platform (disregarding pillagers and zombie villagers, which don't count toward monster density caps đ).
@Auldrick it looks like you got confused or something went wrong in your tests earlier, but I want to say thank you for taking the lead on this and trying to figure out what the developers meant by "reverted the changes." It's been a confusing couple of days. On the upside, maybe now they'll consider your suggestion of adding a limit to the Y distance surface spawns can be passed down. I haven't been able to think of anything better.

My test rig is functionally similar to GoldenHelmet's. I have 3 platforms, each 16 x 16, one on the surface (Y=73), one at Y=60, and one at Y=6, all vertically aligned with each other. They are surrounded out to the density cap area limits by solid stone. I have observers set up to replicate whatever I place above the spawn floor so I can try out various roof configurations.
In reconciling Reed's results with mine, I noticed I made a major mistake in how I set up my test environment. I'm currently working on doing mine again, from scratch.

I've completed my testing after correcting my mistake and I now concur that 1.14.20 has reverted to the 1.13 behavior. However, I have a couple of questions and a new observation.
Neither of you made a distinction between bottom slabs and top slabs for triggering surface spawns below them. I find that bottom slabs trigger surface spawns but top slabs don't. Do you agree?
My tests indicate that carpet, leaves, glass, and even lanterns on the surface now work the same way as bottom slabs and stairs do. My recollection from 1.13 is that only leaves, bottom slabs and stairs triggered surface spawns below them. I was building a dual layer mob farm at the time and I remember experimenting with several other kinds of transparent blocks and finding that none of them had the same effect. I might be remembering wrong, though. How certain are you that other transparent blocksâsuch as carpet, glass, and lanternsâworked the same way before. (I feel like this is a difference from the 1.13 behavior.)
The new observation is this: I noticed that several mobs almost always spawned on my deep ("cave") spawn floor before any spawned on my shallow ("surface") spawn floor. There was only one exception in all my dozens of tests. I can't explain this, as the way I understand it the spawn logic should be searching downward and spawning as it goes. Do either of you have any insight to offer?
GoldenHelmet discovered that zombie villagers aren't counted against their density cap during spawning (see MCPE-62030).

Re: (1) agreed, monsters spawn on top of top slabs, and top slabs do not trigger surface spawns below.
Re: (2) your description of this bug above mentions "Stairs, bottom slabs, and leaves are not the only blocks that cause cave spawns to become surface spawns. So far, other blocks I've identified that this do this include Farmland, Grass Path, Lantern, Chest, Cactus, Turtle Eggs, and Lectern." I'm pretty sure that text was there when I first commented on this bug back in November. Last night I tested (and confirmed) fence posts because I've see farm designs that use them, and I just tested trapdoors and they pass surface spawns down too.
I started thinking maybe any block that you don't walk right through (like grass or redstone dust) would pass surface spawns down, so I tested repeaters and found that they do not pass surface spawns down! Nothing spawns on repeaters, but the platform immediately below a ceiling covered by repeaters produces cave spawns.
Re: new observation: Yes, I am also observing that cave spawns happen more quickly than surface nowâoften, but not always, all 8 cave monsters will spawn before any surface monsters spawn. However, I am confident that before this update cave monsters would sometimes spawn without a surface spawn occurring on a spawnable block above them at the same time. It gave the appearance that the algorithm was choosing random Y-values to begin searching downward from, or else only searching for spawnable cave blocks on some attempts.Â
Â

Well, that's embarrassing! I should have head my own description, obviously. I'm still convinced all the extra blocks didn't trigger surface spawns at the time I built my mob farm, so I guess that must have been before 1.13.
I am pretty sure all those extra transparent blocks shouldn't be triggering underground surface spawns, though, and it consider it part of this bug that they do.

The list of blocks in 1.14 can be found here: https://docs.google.com/spreadsheets/d/1OXB5wKnD2GNZEhDC8dPo_zsM7djPblf8wZI77oTa1Tk/edit?usp=sharing.
Blocks with SpawnBlock=TRUE are those that mob spawns can be attempted on. Block with SpawnBlock=FALSE will pass surface spawns down if MaterialBlocksMotion = TRUE. (This is from memory and may be slightly off.)
I've looked the assembly code of several functions in 1.14.20 and I can confirm that the changes in 1.14.0 and 1.14.1 have been reverted to 1.13 status. I'm going to need to see a really convincing test world before I believe that mob spawning is different between 1.13 and 1.14.20.
Based on my knowledge of the spawning algorithm in 1.12 onwards, I believe that the following can be implemented without too many changes.
Search for spawning blocks starts from the top of the dimension and proceeding downwards. (current behavior)
A spawnable block is one of the blocks listed in the spreadsheet above with right amount of air (or water) above it (including blocks like saplings or tall grass).
The first spawn location found is a surface spawn (current behavior), unless this location doesn't have direct sky access (1.14.0-1.14.1 behavior)
All other locations found are cave spawns (current behavior)
Carpets should be the only block that pass surface spawns down, modifying #3 (1.14.0-1.14.1 behavior). Carpets don't spawn naturally as part of the terrain and are unlikely to be used as roof material in houses by non-technical players.
For the purpose of #3, leaves should not block sky access (current behavior that is not implemented correctly). E.g. the area below the canopy in roofed forest should use surface spawning rules and caps.

Iâm inclined to agree with Auldrick, against Reed on #5, that leaves, lower slabs, and stairs should pass spawns down. Leaves need to pass spawns through tree branches, and stairs and lower slabs are commonly used to make secure roofs that are not intuitively though of as surfaceâespecially in naturally generated villages. These do create a problem of surface spawns underground under tree trunks and house walls, which has 2 noteworthy impacts: raids spawn underground in these places (MCPE-45183) and regular monsters spawn underground and fill the surface cap and never despawn due to the light level requirement for despawning (which should just be eliminated, but thatâs another issue) leading to the appearance of low spawn rates (MCPE-21856). I would suggest dealing with these complications by adding a short distance limit (say, 1â5 blocks) to passdowns, or a block type checkâonce you hit a dirt, sand, gravel, clay, or stone/granite/diorite/andesite, or ore block, the surface pass down stops.

I think we're getting too meta about this. All we need to do is write a description of how spawning is working under 1.14.20, how we expect it to work, and a list of steps that demonstrate how to reproduce the buggy behavior. How it used to work is irrelevant, and while how we expect it to work is relevant (since it determines the expected behavior), it doesn't matter if we disagree because ultimately, only Mojang can determine what the intended behavior is.
I think we're all in agreement on how spawning is working after the regression, and therefore how to write the Steps to Reproduce and Actual Results parts. Apparently there are minor differences in what we think is the intended behavior, and I'll try to accommodate all our viewpoints in the Expected Results part.
The bug was originally reported under 1.8.0 (coincidentally, exactly 1 year ago today). Since then, both the spawning algorithms and the discussion on this ticket have evolved, so a lot of what appears above is too dated to be informative. Because of this, I was thinking it might be a good idea to start over with a new bug report for the regressed behavior. I have since changed my mind, because this ticket has 25 watchers and 103 upvotes, and those connections to the community would be lost if we started a new ticket. Instead, I intend to write a brand new description of the bug in a comment, one that doesn't refer to or depend on anything going before it, and update the original description with a prominent link to the revised description. I'll try to write the new description soon, but right now I need a little time to clear my brain and integrate our test results.

Needs to be updated, this bug also occurs in the 1.16.0.59 beta!!

Can you please show how this bug is still affecting the latest beta?

Didn't this get fixed in 1.16.0.59.

Yeah, and it did. At least from my testing. All of my mob farms that previously exploited this bug are now getting spawn rates it used to get.
Resolving issues that were marked as fixed in the 1.15 and 1.16 Betas, now that 1.16.0 is being released.