0

I've been working on an saving system for my 2D RPG game, and I recently encountered an issue: my saving system uses PlayerPrefs, which I heard is supposed to be used for things such as settings. I've also heard that it isn't very secure and that people can exploit it. I was wondering whether there was a way to make my saving system more secure. Here's my inventory script that also holds the save function:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ItemInformation : MonoBehaviour { // These are the assets for the item to change public Text nameText; public Text descriptionText; public Text regenText; public Text amountText;

// This is the identifier for each item
public string identifier;

// These are the variables that change with the different items
public string itemName;
public string itemDescription;
public float itemRegeneration;
public int itemAmount;

// Starts on awake
void Awake()
{
    // Function to change the object's information and such
    nameText.text = itemName;
    descriptionText.text = itemDescription;
    regenText.text = "HEALS " + itemRegeneration + "HP";

    // Loads game data
    LoadDataIfNeeded();
}

// Function to save game data
public void SaveData()
{
    string jsonString = JsonUtility.ToJson(this);
    PlayerPrefs.SetString(identifier, jsonString);
    PlayerPrefs.Save();
}

// Loads data if needed
public void LoadDataIfNeeded()
{
    if (PlayerPrefs.HasKey(identifier))
    {
        string jsonInstance = PlayerPrefs.GetString(identifier);
        JsonUtility.FromJsonOverwrite(jsonInstance, this);
    }
    else
    {
        SaveData();
    }
}

// Updates on every frame
void Update()
{
    // Shows amount of item left
    amountText.text = "HAVE:" + itemAmount;
}

}

OKprogrammer
  • 512
  • 1
  • 7
  • 20
  • If this is for an offline game, you can make it only harder for the player but never prevent. If it is an online game, store it server side to a database. – Zibelas Jan 18 '21 at 14:32
  • @Zibelas It is an offline game. – OKprogrammer Jan 18 '21 at 14:36
  • @noobprogrammer Then what are you worrying about? When people hack their savegames, then the worst case is that they ruin their game experience. But they have no one to blame for that but themselves because every player should know that savegame hacking isn't the way you are supposed to play a game. But the best case is that they figure out how to create interesting situations they couldn't create otherwise and find completely new ways to squeeze even more enjoyment out of your game. – Philipp Jan 18 '21 at 14:57
  • @Philipp Ok, thanks! Maybe I could even put some secret stuff that you can’t get to unless you modify some hidden variable. :) – OKprogrammer Jan 18 '21 at 15:06
  • Players might even use savegame editing to work around your bugs and design problems. When a player finds themselves in a softlocked state (due to a bug or design oversight on your part) but no older savegame to load from, then they might rescue their run by modifying their savegame. Sure, the ideal solution would be for you to patch that problem, but that might take you some time. – Philipp Jan 18 '21 at 15:07
  • You might not have to intentionally add easter eggs which can only be found by savegame hacking. Many games end up with those naturally. Usually because the designer decides against using some piece of content a developer created, so they removed the way to reach that content from the game, but the content itself was never properly removed from the game, so it can still be reached by hacking. – Philipp Jan 18 '21 at 15:11
  • @Philipp Do you know how I could possible have a save file, so players could transfer progress if they wanted? – OKprogrammer Jan 18 '21 at 16:09
  • @noobprogrammer You are not the first to ask that question. This question might help you: Saving player's progress in a Unity game. But we also have many more questions about savegames in unity. – Philipp Jan 18 '21 at 16:15
  • I would suggest serializing the game data into binary and saving that file, rather than using PlayerPrefs to save the game, but for reasons that have little to do with security. – jhocking Jan 18 '21 at 17:00

2 Answers2

3

Since you wrote in a comment it is for an offline game, the short answer is: you can't.

If the player is the owner of the whole game (since it offline), any kind of mechnism can be prevented if he is dedicated enough to figure out how you obscured your data. You can only make it harder for him.

You need to prevent memory manipulation, else the player could either freeze his hitpoints, ammo, money, etc or increase it to his liking.

The second part is you need to protect the save file itself against manipulation. Since he can read it as well, you need to make it harder for him to read and change values. Binary files, custom formats and a hash of everything are doing the job. The draw back (if that is one for you) is, if he really tries to manipulate the file, he might create new run time errors when you try to read your own file since the format got broken (and the player will certainly blame it on you why all his items are gone)

There is the opinion that if the game is offline, you should let the player do what he wants. Maybe the game is too hard and he would otherwise stop playing. Maybe he is lacking time for farming. As long as he is the only player, all he can do is boost himself and has no effect on the play experience of other players.

Zibelas
  • 4,281
  • 2
  • 13
  • 22
0

First, I'd not recommend saving in PlayerPrefs for large saves, it would be better to save it in a file at PersistentDataPath instead.

As for preventing the player from modifying it, the simplest way would be to encrypt the file before saving it to the disk, and then decrypt it when loading. The encryption key would be hard-coded to your program so there wouldn't be any external file that the player can access in order to easily decode and modify your save file, but any decompiler can easily see your program's code and extract that key. It would require some more technical know-how, so most simple players would not be able to do that.

You can go even further by using a native plugin to hide your encryption key in, and add complex code that generates the key real-time (instead of simply entering a string which hackers can easily find).

All that said - if it's a single player game, there's no real reason to work so hard to prevent cheating. A simple encrypted save file will be very easy to implement and will do the trick nicely for most cases. Even that may be too much since if a player decided they want to cheat, why do you care, whatever makes the game more fun for them should be good for you.

tbkn23
  • 403
  • 4
  • 10