- Home /
Storing unit data for an RPG
Hello,
We're making a game where the player will have many units/heroes under his control. Those units will level up and evolve and their stats will change over time. We need to be able to store that in a save file of some sort and retrieve that data when required (that data will also be progression, previous choices made etc). What is the best course to follow for something like this? We're pretty new to unity and the only other platforms we've played with so far are like Game Maker and RPG Maker that do all the saving themselves.
Please be a little more specific since we're kinda new to this. We read about PlayerPrefs but it seems that people don't like it and it is kinda slow on mobile OSes + windows doesn't like it. We also read about using SQL but got no idea on how to go about it (if it is relevant that is). Generally I'm also looking on a general method to solve this.
Thanks in advance!
you mean sorting in middle of game? use class for that
if you mean saving the data well, ... I'd create my own save binary and load binary witch might get very complicated depends on what way you'll go.
I'd say this way the number is 011010 don't know what's the number of the top of my head
so let say: - 0 weapons - 1 armor - 1 skill magic - 0 armor skill - 1 has weapon in heand - 0 has armor
so now you have a sorting and he knows ok 1. is weapon but we don't have it so we don't load the wrong one:
binary 32bit string is number of what player has or hasn't
binary is how many armor we have (5)
binary is what armor we have
untill the end of 5 armor
what magic skill number we have so we read the 32bit binary number of exp
and so on and so on
remember when ever you read that's 0 you must go on and not load it in to it otherwise you'll get:
0 weapons we read armor we load armor in to weapons and you'll end up with bunch of nulls and errors
so the way you sort it that way you have to retrive the data
you can also go the hard way
write ALL data posibbilities:
0 ID weapon, 0 ID weapon, 0 ID weapon, 0 ID weapon, 0 ID waepon
154 ID armor, 115 ID armor, 0 ID armor, 0 ID armor, 0 ID armor
65496 magic skill
0 armor skill
257 ID of weapon
0 ID of armor
I don't really get what you mean. I'll read it again...
What I'm looking for is like the example below:
The player plays 5 hours of the game. His 2 characters get to level 6, have 576 hp and one uses Sword of Heroes and the other has Lance of Dragons equiped. They have also each skilled Twisting Slash and Jump Attack respectively in their skill trees. Once they close the game, this data gets lost. How do I save it and retrieve in the next playthrough?
PlayerPrefs is great for a one player game there are valid reasons not to use it which you can find with a little research. The fast and simple way though is to implement playerPrefs. I would even recommend this method if you are just starting out as it's a great way to learn about the logic of storing and retrieving values.
If your game is a $$anonymous$$ultiplayer game you will have more negative feedback if you make it easy for some players to cheat and you should consider implementing a more technical solution.
So in short is this a one-player or $$anonymous$$ultiPlayer game?
@Jokeaccount - like Glister writes, PlayerPrefs is an excellent solution for single-player or co-op RPGs. You can record all your save data in a single string, something as simple as "6,576,3,42,6,576,4,55" where the first "6,576,3" translates to "level 6, hit points 576, weapon index 3=Sword of Heroes, skill index 42=Twisting Slash". This kind of solution is really easy to implement and works basically the same across the board on all platforms. Your string can be up to 1$$anonymous$$B long (for web player, which has the lowest maximum), so you can store a lot of information.
You'll probably want to store the string in a more robust format, not just comma-delimited, maybe using an X$$anonymous$$L serializer so it would look something like:
< character id=1 > 6 < /level > 576 < /hp> 3 < /weapon > (or "Sword of Heroes" for readability) ... < /character >
To just get a prototype working quickly, comma-delimited format is messy but really fast to implement. You can use string.Split() to separate on commas. And you can switch to X$$anonymous$$L or something later if you want. Although a binary stream might be more compact, I recommend a human-readable text-based string. It makes debugging much easier.
For multiplayer, unless you store the saved game on your own server, the data is always vulnerable to cheaters. Depending on your requirements, you might consider PlayerPrefs even for multiplayer.
I do like this idea. I don't know why I haven't thought to try something like that. This would at least allow you to store an item within one PlayerPref although retrieving all those variables still seems like it could be problematic for performance on mobile platforms for example.
At least this would limit the number of playerPrefs which seem to be the main performance limitation. You would still need to deal with a ton of variables to retrieve that data but I suppose you could add those all to a list at run time.
Still seems like something I may try thanks for the idea.
For the robust answer you can convert use JsonUtility.ToJson to get a json from the public and serialized fields of a class.
Then use JsonUtility.FromJsonOverwrite to restore the values.
Answer by JoshuaMcKenzie · Jan 18, 2016 at 07:53 PM
Do not use PlayerPrefs. PlayerPrefs is designed more for a players prefences (hence the name) on game configurations (audio volume, screen gamma, hotkey setup, etc.). they're also not very secure and easily hackable (which for normal player configurations is fine, but not for game data).
You're going to want to look into Serialization, more specifically Unity's serialzation with scriptableObjects. No, its not simple programming, but with the requirements I'm hearing that you've set forth in your game, this is the best course of action.
Using Serialized ScriptableObjects comes with its own advantages not normally available in homemade Serialization implementations such as:
dual-referencing (where two variable reference one object and if its edited through one reference the other updates properly)
Polymorphism normal serialization doesn't support it
Collections Normal Serialization has problems with things like Lists and Dictionaries, forcing you to convert to and from arrays while you serialize/deserialize. while complex collections (mutidentional or jagged collection) might take some work its still easier to work with through scriptable Objects
And (speaking from personal experience) it is worth it for you to try and figure this out early as not only will it set you on you way to understanding how unity manages its data, but serialization and ScriptableObjects are also closely tied to tools making which will be a great help to your designers and artists early in the project.
Take a look at these videos for some helpful info into Unity's Serialization
Persistence Data Saving and Loading sfbaystudios already posted this. I agree that its quite useful in getting you started with general serialization. It doesn't go into using Unity's Serialization however
Introduction to ScriptableObjects another useful video focusing on the basics around the ScriptableObject itself.
Serialization In-Depth This video will be highly educational in helping you harness Unity's Serialization. comes with the added bonus with some examples in making editor tools.
Answer by infinitypbr · Jan 17, 2016 at 09:47 AM
Learn from me: Do not use player prefs for an RPG! Even a smaller single player one. It gets VERY tedious VERY fast, and there's no real easy way to clean it up, and certainly no easy way to send the saved game over the web -- for debugging or allowing players to continue their game on another platform.
The other day I watched this: https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/persistence-data-saving-loading
And that started me on a great new path. I've been putting up tutorials and unity packages as I make a new RPG: http://forum.unity3d.com/threads/1st-person-rpg-tutorial-series-infinitypbr-com.379255/
I've been saving binaries of the data -- right now I have the "game data" in one file, and one file for each scene (dungeon etc).
I haven't yet decided on how to save enemies and their states, or pickups, inventory etc - -but the suggestions above are pretty good.
If each Enemy Model Type has a unique ID, and you have a "enemy control" object that doesn't move (even if the model does), then you really have unique names considering they're in unique and non-changing positions, if you use their positions as a key-name. Like "Enemy0.2|2.2|583" (xyz position). And then follow that with all the values you'd like, comma between each, so you can break down that (Very) long string into an array. Go through the array, and if you know each enemy has maybe 50 spots, then every 1st and 51st spot would be a new enemy.
It's tedious to set up, but if you stay organized it should be pretty straight forward.
It should also be possible to write an editor extension to manage all that in a more visual way.
Answer by RyanZimmerman87 · Apr 17, 2013 at 01:08 AM
Unfortunately PlayerPrefs do not work directly to store information with Lists or Arrays. Meaning any extensive use of PlayerPrefs will require rediculous amounts of tedious manual programming to retrieve/save hundreds of PlayerPrefs with custom names.
This is also a problem because using a ton of PlayerPrefs is reportedly slow for performance.
I have been dealing with a similar problem lately after I designed my player's inventory system. I realized that having randomized loot like any respectable RPG could potentially require hundreds of playerPrefs even with only around 20 inventory slots.
This problem sounds very similar to yours if you want many individual units to have multiple stats saved.
One possible solution I found is this:
http://wiki.unity3d.com/index.php/ArrayPrefs2
But judging from their description it sounds like using PlayerPrefs in arrays like they have programmed is only recommended for somewhat small lists like 10 entries. I am not sure if it would work effectively for complex systems that many Unity users will probably need eventually depending on their game type.
It seems that saving with standard binary IO type stuff is the only reasonable solution. But I currently know literally nothing about that and am in no rush to start.
Maybe if enough people request this kind of feature to store complex data structures permanently in a user friendly manner they might try to develope a better built-in solution for Unity.
I think it's still possible to do with PlayerPrefs if you are extremely meticulous with your functions and planning. But the amount of time to program this compared to being able to simply retrieve playerPrefs from a list is crazy talk.
Here's hoping for some Unity innovation to allow new programmers to save data in a reasonable fashion :)
From what you're saying Ryan it seems that there is no best practice atm? This seems weird... Almost every game requires you to save data even if it is only for player progression...
This is quite a big discussion topic and there are numerous ways that you can save data depending on what exactly it is you need to save. There are arguments standing for almost any different type of method as to why it is the best and why others don't work.
I would take any information you get on this subject with a grain of salt.
There is no one "easy" and readily available solution that I have seen. Your best bet is to do a search similar to This One and read through every entry for at least 2-3 search page results and read through many of the posts that they suggest in those forums and from there decide what method you think will work best with your $$anonymous$$ms set of skills balanced with your games needs.
$$anonymous$$any people make arguments for and against PlayerPrefs, Binary saves, PHP, PERL, Webplayer Vs Standalone, serialize, serialize to PlayerPrefs, Cross or single platform considerations, and the list goes on. Ultimately your best bet of getting something that you think will be easy will be looking at what options that exist finding ones that meet your needs and choosing one that matches your skill set.
Answer by Internet Friend · Jan 18, 2016 at 05:46 PM
Unity is a game engine, not a storage engine. If the complexity of your data is high, you will need an actual data storage solution. What that solution that might be depends on your game and your target platforms, but trying to push complex data into comma separated strings is a fools errand.
Search for an external solution that meets your needs, do not try to stretch Unity into doing something it's not designed to do.
Answer by Disastercake · Sep 27, 2018 at 02:00 PM
Here is a video tutorial by Unity regarding persistent data: https://unity3d.com/learn/tutorials/topics/scripting/persistence-saving-and-loading-data