I read an article on the internet trying to understand how Minecraft chooses suitable coordinates to act as the world spawn. I learned some information about how that mechanic works including spawning within a certain area around this position.
It was implied that the game starts from the x/z 0,0 coordinates then explores around that position for a suitable area to start. I didn't see much in the way of detail about how it considers an area suitable. It doesn't seem like it is totally consistent either as I read that using the same seed, a world may be the same but the initial spawn location may still be different.
It would make sense for the game to not dump you in the middle of water / the ocean. Even better to put you somewhere on land with trees within a reasonable distance.
The world I am playing the world origin 0,0 is in the ocean and the spawn location is near the N/S zero line for the z axis but about 700 metres down the x axis. This is fair enough but there is land in a forest biome less than 200 blocks north (z < -200) which would seem a very suitable place to spawn but the game chose a location over twice as far away. It could make sense if it was a very simplistic algorithm that just moved down the positive x axis until it hit land. What I read implied it could be more complex.
I also read that in spite of trying to find a suitable location the game can sometimes dump you in the ocean or even on lava. I could experiment...for science....but wondered if anyone knows any more. It isn't something important for my playing enjoyment but my curiosity was piqued.
I once had a spawn in the middle of an ocean. It was on xbox 360 and it was an all water map with just a couple of small islands. One island had one tree on it. The island could not be seen from spawn and i only made it there without starving by pure luck. It was a great survival seed, very challenging.
I don't know about non-Java versions but the Java version first checks for a plains, forest, taiga (non-snowy) or jungle biome (including their hills variants, but not other variants) within a 512x512 area centered around 0,0, then chooses an initial point if found, then it checks to see if the block at that point is a grass block at sea level or higher and if so sets world spawn there (the actual area checked uses the biome generator's underlying resolution of 4 blocks, prior to smoothing, so coordinates are a multiple of 4. For example, the seed "-123775873255737467" in 1.6.4 has spawn at -92, 236, which is a multiple of 4 so this seed passes the first check).
If no grass block is found it starts a routine which checks up to 1000 points with a random offset of up to +/- 63 blocks from the previous point, which will randomly wander around and may get over 1000 blocks from the initially chosen location before it either gives up or finds a valid spot (in the case that it gives up spawn can be in a location like in the ocean with no land around, though this is rare in versions since 1.7). Unlike the biome check, this method actually generates chunks, which is why you sometimes see a long trail of chunks scattered from 0,0 to the world spawn, as in this example (in this case the game is unable to read blocks below normal sea level so it fails to find any grass blocks on default Superflat worlds):
Here is the actual code that finds the world spawn point (the comment given by MCP is a bit incorrect since it will only be within 256 blocks of 0,0 if the biome check passes and there is exposed land):
* creates a spawn position at random within 256 blocks of 0,0
protected void createSpawnPosition(WorldSettings par1WorldSettings)
this.worldInfo.setSpawnPosition(0, this.provider.getAverageGroundLevel(), 0);
this.findingSpawnPoint = true;
WorldChunkManager var2 = this.provider.worldChunkMgr;
List var3 = var2.getBiomesToSpawnIn();
Random var4 = new Random(this.getSeed());
ChunkPosition var5 = var2.findBiomePosition(0, 0, 256, var3, var4);
int var6 = 0;
int var7 = this.provider.getAverageGroundLevel();
int var8 = 0;
if (var5 != null)
var6 = var5.x;
var8 = var5.z;
this.getWorldLogAgent().logWarning("Unable to find spawn biome");
int var9 = 0;
while (!this.provider.canCoordinateBeSpawn(var6, var8))
var6 += var4.nextInt(64) - var4.nextInt(64);
var8 += var4.nextInt(64) - var4.nextInt(64);
if (var9 == 1000)
this.worldInfo.setSpawnPosition(var6, var7, var8);
this.findingSpawnPoint = false;
Also, the biome check is done by scanning the 512x512 biome map from the northwest corner to the southeast corner (from west to east, then back to the west and one south to the next row), which causes spawn to be biased to the south (it does not necessarily use the first valid point found but rather has a random chance of choosing a valid point, which starts at 100% and decreases as more points are found, and always checks the entire area).
Our 0,0 is surrounded by a ton of ocean but there is a huge desert biome just to the west. Our spawn point is 3788, 30. There are larger islands much closer to the spawn point but maybe this little land mass had all the other criteria.