-1
\$\begingroup\$

I am making a 2D action-adventure platformer video game using the C++ computer programming language and the Simple DirectMedia Layer 2.0 (SDL 2.0.5) development library.

So far I have created over 50 levels, added enemies (with A.I.), assigned controls, animations, and of course, added the player.

As you know one of the most important features of a video game is the game save feature, in which the game software actually stores the data in the computer memory.

Is there any way to add this feature to my game using SDL 2? If so, please answer in detail with the nessecary code.

Thank you. You have been the most helpful.

Here are the items I'm using:

  • Microsoft Windows 10 (O.S.)
  • Microsoft Visual Studio Community 2017 (I.D.E.)
    • VSX 17 C/C++ Compiler (Compiler)
    • C++ (Programming Language)
    • Simple DirectMedia Layer 2 (Version 2.0.5) (Development Library)

Thanks again.

\$\endgroup\$
  • \$\begingroup\$ How detailed do you want the saves to be? From the start of the level? Or mid-level with checkpoints? Or perfect state inside the level? Is there something that's preventing you from just simply saving the name of the current level the player is in? \$\endgroup\$ – Tyyppi_77 Sep 25 '17 at 12:47
  • \$\begingroup\$ I just want a 'continue game' option in my menu to start at last saves (manual saves, no autosaves). Also, if the player dies, he will restart at last manual save. \$\endgroup\$ – Aditya Chandra Sep 25 '17 at 12:50
  • 2
    \$\begingroup\$ Yes but what's the data that you need to save? That's the most important question you need to ask yourself, the implementation is trivial. \$\endgroup\$ – Tyyppi_77 Sep 25 '17 at 12:57
  • \$\begingroup\$ @Tyyppi_77 Basically I need to save the game progress so far and any changes in the player. That includes loading the level at which the last manual save took place, the current level of the player, inventory and some score statistics needed to complete achievements. Other data like current health, last weapon, etc are to be discarded. \$\endgroup\$ – Aditya Chandra Sep 26 '17 at 11:04
2
\$\begingroup\$

You can either write your own save format and save file reader & writer, or use an existing parser like an XML or JSON one. You can store the save data in a GameSave class at runtime either as a tree of the file format you chose, or inside direct member variables. I myself us the latter, as then it's easier to save data (while reading becomes a bit more tricky). It also abstracts setting of the save data with the writing of the save data.

class GameSave
{
public:
    GameSave() { }
    GameSave(const std::string& filename) 
    { 
        // Load save data...
    }

    void Write(const std::string& filename)
    {
        // Write save data...
    }

    std::string CurrentLevel;
    std::vector<std::pair<std::string, int>> Inventory;

    // More save data...
protected:
private:
}

Here's a very basic example of what your save class could look like. The details or writing and loading and the filename management depends on if you want to support multiple saves or not, and if you want to predefine a few save slots or allow the player to chooce their own filenames etc.

So, when the player saves the game, you need to write the required data to the file. This can be done in a few ways: you could ask each object to save its own data to the file, or you could have a parent object (like your level / gamestate) save the required data. Since your data needs seem quite small, I'd go with the latter option and write something along the lines of:

void GameplayState::SaveGame()
{
    GameSave save;

    save.CurrentLevel = m_Level->GetName();
    Player* player = m_Level->FindPlayerEntity()->GetLevel();
    save.PlayerLevel = player->GetLevel();
    for (InventoryItem* item : player->GetInventory()->GetItems())
        save.Inventory.push_back(std::make_pair(item->Name, item->Amount));

    save.KilledEnemyCount = GameStatManager::KilledEnemyCount;

    save.Write(AskPlayerForSaveSelection());
}

Finally, to continue from a save, you just have to load the data in and pass it to the correct owners. This could be done by passing the whole GameSave around, or simply by passing the required members of the save to the constructors/methods.

void GameplayState::Continue(GameSave* save)
{
    // Use save data:
    m_Level = new Level(save->CurrentLevel);
    m_Level->CreatePlayer(save->PlayerLevel, save->Inventory);
}

This is the basic high-level architecture of a basic game save setup that I've found that worked well enough for me, when the data that I need to save is quite small and can be handled as such. Were you need more data and more dynamic data, then you'd have to start assigning unique identifiers to objects and allowing each object to save/load its own data.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.