简体   繁体   中英

How To Store Game Data Without An Online Database

I am working on a game that is intended to be played off line. For the past I had done games which required an online connection. We would store all relevant data online in a database, and I would fetch the database data, parse the data into objects, via JSON, and access them as needed.

For my offline environment, I'm not sure how I can best replicate storing all the types of game data. I really preferred the organization of the database and I don't want to create a whole bunch of game files and variables to manage everything. I'd prefer to mimick having a database, only it compiles with the game.

I considered using an excel file, but I feel that would be too easy to hack.

Do you have a suggestion on how I can mimick an offline database?

My specific engine is with Unity3D and I'm using C#.

Thanks

You can use a local database technology, they are used just like you would use an online database but the data is stored in a file stored on the local machine. If your in .NET two come to mind:

SQLite - http://www.sqlite.org/

This is the defaco local database technology, its open source and has very widespread use. There is even a library to connect unity to it: https://github.com/Busta117/SQLiteUnityKit

SQL CE

This is Micrsofts single file database. It is very similar to the features of SQL Server, its not open source but it has built in drivers already in the .NET framework so it maybe simpler to use. Issue with this could be if you want your game to run across platforms take a look here: http://answers.unity3d.com/questions/26118/can-you-use-sql-compact-35-with-unity.html

I would recommend going with SQLite as it seems there is more support for it in Unity

Unity can do this for you in the form of PlayerPrefs . According to the Unity documentation, it:

Stores and accesses player preferences between game sessions.

However, it can be and often is used to store things such as highscores, tutorial information, and various other offline data.

Simple example:

// this gets the value with the key "score"
// defaults to 0 if it doesn't exist
PlayerPrefs.GetInt("score"); 

// this sets the value with the key "score"
// previous values will be overritten
PlayerPrefs.SetInt("score", 9001);

Be aware that the values are not encrypted in any form automatically, however you can wrap the function as follows:

public static int GetIntData(string key, int value)
{
    if(PlayerPrefs.HasKey(key))
    {
        return YourDecryptionMethod(PlayerPrefs.GetInt(key));
    }
    else
    {
        return 0;
    }
}

public static void SetIntData(string key, int value)
{
    return PlayerPrefs.GetInt(key, YourEncryptionMethod(value));
}

You could take this even further and encrypt the keys if you wanted to. However for very large data sets, you should consider using a database instead (see this answer) .

Additional

If you like storing data as JSON, XML or some other format, there's nothing to stop you using one of the many parsers available for popular data formats with the same encrypt/decrypt wrapper solution.

For example if you're using C# and want to store data as XML, you can use System.Xml .

Take a look here for information on using external DLLs in your project, should you choose not to go with a Mono/.NET class.

Avoid using PlayerPrefs for game state that you are concerned about being easily hacked. PlayerPrefs are stored in plain text, they really should only be used for storing configuration related values.

If you are looking for a native way to handle it (ie not SQLite), you can regular .NET file IO. Simply have your data structure in a serializable POCO object model. When you save, you can use something like:

BinaryFormatter bin = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/savegame.dat", FileMode.Open);
bf.Serialize(file, mySerializablePoco);
file.Close();

That will write a binary file to disk that can be deserialized during a load process. You can add encryption if you want as well.

If you aren't caring to modify the data, but just want the structure of setting predefined objects, you can use ScriptableObject. I did one project where we did not want to use SQLite so we made something like:

public class MyRepository : ScriptableObject {
  public List<Car> Cars;
  public List<Driver> Drivers; 
}

[Serializable]
public class Car {
  public string Manufacturer;
}

... ect

ScriptableObject is created and designed during edit time. You actually create it with some editor code and it will write out an *.asset file into your project. At that point you can Resource.Load it at runtime or wire it up to a public variable on a MonoBehavior script.

Check out: http://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/scriptable-objects

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM