You calculate fall speed going down and check a 'ground line'. Say it's in pixels. If you are falling down at 6.345 pixels (fairly fast), check if it crosses the ground line. So,
if (player.y + 6.345 > ground) { /**/ }
if that is true, set player.y = ground (or otherwise his torso will be in the ground, and we wouldn't want that!). This is not too hard to do in a custom engine since for every platform all you need to do is keep track of it's 'ground' y-axis values. In Sphere's map engine we can do a simpler check, but we still need to know something about the ground line:
if (IsPersonObstructed(name, player.x, player.y+6.345)) {
player.y = ground_line;
}
Try it out with a constant value first (all tiles on platform are the same height).
The other solution is a tad more computational, but requires no knowledge about the ground line. The algorithm is similar to the top, but requires calling many obstruction checks:
if (IsPersonObstructed(name, player.x, player.y+6.345)) {
// we overshot the ground somewhere, backtrack until we are on top:
for (var i = 1; i <= 6; i++) { // 6 from Math.floor(6.345)
var y = player.y + (6 - i); // 6 from Math.floor(6.345)
if (!IsPersonObstructed(name, player.x, y)) player.y = y;
}
}
I haven't tested the code, it's purely theory.