Passing struct between functions C ++

How about this?

Player StartNewPlayer(string name)
{
    Player player;

    player.name = name;
    player.level = 1;
    player.exp = 0;
    player.hp = 20;
    player.mp = 5;
    player.shield = 0;

    return player;
}

void game_board(Player player)
{
    cout << "Hello!" << player.name;

    (...)
}

int main ()
{
    Player player = StartNewPlayer(new_game());
    game_board(player);
}

Do not create extra copies of the data with complex datatypes by using pass-by-value

Use pointers instead to pass the address of the variable that can be modified in the function. The changes will be reflected in the caller's function as well.

void StartNewPlayer(string name, Player *player)
{
    player->name = name;
    player->level = 1;
    player->exp = 0;
    player->hp = 20;
    player->mp = 5;
    player->shield = 0;
}

void game_board(Player* player)
{
    cout << "Hello!" << player->name;

    (...)
}

int main ()
{
    Player player;
    StartNewPlayer(new_game(), &player);
    game_board(&player);
}

Alternative using pass-by-reference:

If you're a fan of references, (which is just a clever compiler-trick that makes use of pointers internally again):

void StartNewPlayer(string name, Player& player)
{
    player.name = name;
    player.level = 1;
    player.exp = 0;
    player.hp = 20;
    player.mp = 5;
    player.shield = 0;
}

void game_board(Player& player)
{
    cout << "Hello!" << player.name;

    (...)
}

int main ()
{
    Player player;
    StartNewPlayer(new_game(), player);
    game_board(player);
}

I would suggest returning a pointer to a Player struct. If you return a "reference" like you are doing right now, it will call the copy constructor of Player which can lead to further complications.

Normally, at the end of StartNewPlayer(...), the Player you declared there will cease to exist as the object scope will end, so when you return it, the c++ compiler gets that you want to keep the object alive and will create a copy for you, invisibly. If you return a pointer to it, you really are returning the object you allocated in your function.

Suppose that you have pointers in your Player structure, such as

struct Player
{
  int level;
  char* name; //lets assume you did it like that
}

When you are returning the Player, the int will be copied, but the char* will not. ints are easy to handle while char* need all kind of tricky functions like strlen and strncpy. The more complex your Player struct becomes, the more problem you will face by using the default copy constructor.

Another solution would be to declare a copy constructor yourself for the Player struct ( really, you could use classes since they are mostly interchangeable in c++ ).

Player(const Player& p)
{
    name = p.name;
    level = p.level;
    // and so forth
}

So I would use

Player* StartNewPlayer(std::string name)
{
    Player* player = new Player();
    player->name = name;
    player->level = 1;
    // snip 
    return player;
}

At the end of your program, be sure to delete player otherwise you will have a memory leak