How to implement a gravity system like Puzzle Uo Poko?

TL;DR:
How can I implement a gravity system similar to the one in the game Puzzle Uo Poko?
Gameplay Example

As a first project to practice, I’m trying to recreate the game Puzzle Uo Poko.
Despite several attempts and different solutions, I haven’t been able to create a system that simulates gravity and manages all the various scenarios.

Currently, the game is in 3D, and I’ve created a Grid (Array) containing Tiles, which are cells where the spheres can be positioned.
The only feature I’ve implemented so far is that if a sphere touches the ground, it uses a MultiBoxTrace to find the nearest Tile.

Are you set on solving in via physics\gravity? Since the system in the video has nothing to do with one:

  • You just have a grid (stored as 2d array) - the State, and have a function like Evolve(State);
  • Evolve(State) analyse the state and if any moves are possible - performs it.
    • Probably it have a feature like “process only top element of each column per Evolve(State) call”, but it’s something you may experiment with later;
  • The move is a something like:
    • Check Grid[i][j] element:
      • If it’s a stone and it have a place to go left - go left
        • In code it’s something along the lines “check i’m the stone, check left, check left and down, perform”: if(Grid[i][j].NotEmpty() && Grid[i+0][j+1].Empty() && Grid[i+1][j+1].Empty()) {PerformMove(i,j,i+1,j+1);};
      • if it have a place to go right - go right
      • if it have no places to go - do nothing
    • repeat for every Grid[i][j] (optimizations are possible, but it’s the simplest solution)
  • perform is a two steps:
    • make actual move of element Grid[i][j] to Grid[i+1][j+1]
    • animate the move
      • once animation is over - go for next iteration of Evolve(State)
  • Once Evolve(State) not changing the State anymore - you may let user perform input and add a new element into the Grid

Note that the Grid in the video have an offset of 0.5 element for odd rows - your manipulations with indexes of the Grid have to properly handle this feature.
Well, overall it’s something like this.