I'm sorry if this sounds vague or idiotic, but consider the following:
if I have a main function like so:
int main(void)
{
   int red_wins = 0;
  game_loop(&red_wins); 
  // code 
  printf("red has %d wins\n", red_wins); 
} 

then have a a game_loop function which calls another function that uses red_wins:
void game_loop(int *red_wins)
{
  // code 
  particle_move(red_wins);
}

and then another function called particle_move which uses this red_wins variable:
void particle_move(int *red_wins) 
{
  // code 
  if (such and such)
  {
    *red_wins+= 10; 
  } 
}

where red_wins is only modified in the particle_move function and particle_move is only called from the game_loop function, would it be better to do it as shown above or by passing a pointer to a pointer in the particle_move function? Or, but I've been told it's bad practice, by using a global variable red_wins? Or is there another, better, way that I've overlooked?

Does it make a difference to pass a pointer to a pointer as an argument or simply pass the first pointer?
You only need to pass a pointer to pointer in the following situations:

Where the called function is updating the pointer value, not the thing being pointed to:void update( T **p )
{
  *p = new_TStar_value();
}
int main( void )
{
  T *var;
  update( &var ); // updates var
}

Where the pointer is pointing to the first in a sequence of pointers:void foo( int **p )
{
  // do something interesting
}
int main( void )
{
  int **p = malloc( sizeof *p * ROWS );
  if ( p )
  {
    for ( size_t i = 0; i < ROWS; i++ )
      p[i] = malloc( sizeof *p[i] * COLS )
  }
  foo( p );
  return 0;
}

In your case, particle_move is updating the same thing that game_loop is updating, so you don't need to add another layer of indirection.  You're doing it right, here.
