You can unzip the game and learn how it's made but basically: Floor is recreated each time you enter a room and each tile is a separate object that gets a **delay** property calculated on creation. Then if floor's time is below the delay I do nothing to given tile. Otherwise update the tile's z property. It's kinda reversed: 400 when it's way down and 0 when it's on final position, so all I do is multiply it by 0.8 each frame.

It's rather boring code:

function Floor:getTileDelay(x, y) local lrand = love.math.random -- if the player was already there in this room let's not animate tiles entrance if self.room.isExited then return 0 end -- first room you drop to from above if not self.prevRoom then return math.abs(x) * 0.06 + math.abs(y) * 0.08 + lrand() * 0.3 - 0.1 end -- comming from another room: bring tiles from that direction: if self.prevRoom == self.room.n then return (self.yMax + y) * 0.08 + lrand() * 0.3 - 0.1 end if self.prevRoom == self.room.e then return (self.xMax - x) * 0.05 + lrand() * 0.3 end if self.prevRoom == self.room.s then return (self.yMax - y) * 0.08 + lrand() * 0.3 - 0.1 end if self.prevRoom == self.room.w then return (self.xMax + x) * 0.05 + lrand() * 0.3 end return 0 -- should never happen end