Hi there, I wondering how to handle savegames in Unity? Usually this should be encrypted. As a game engine I expected that Unity has buildin features to do this. But I don't found stuff about it. So I implemented a save game with the BinaryFormatter and / or JsonUtility. It works to serialize a class which stores the values. BUT how to encrypt this to avoid cheating? By using System.Security.Cryptography? I looking for a efficient but simple solution. Less code is more.
Its not possible to protect save games from being modified (cheating). Everything the game could possibly do to the data, it has to undo when loading it again. And thus an attacker could simply do the same thing (the same operations) as well. Encryption does literally nothing. It takes like 5-10minutes to simply hook into the cryptography routines with cheat-engine or any other debugger of your choice to get the password and IV bytes. The good news is that in a single player game you don't have to care about people cheating as it won't influence others. If you have some sort of multiplayer component in your game and are actually concerned about cheating, then saving data on the client / the players computer is the wrong approach anyway. In multiplayer games only the server saves stuff. Or to put it into even more direct words, the actual game that is being played happens exclusively on the server, the client your players use just do the graphics and stuff around that (that's how it works in every MMO, and almost every shooter). That makes cheating impossible. Everything on the client can be hacked/cheated. If you just want some basic protection against noobs then yea, just save the file and then encrypt it. There are thousands of tutorials about that on the internet already, not sure why Unity would build something so simple (and specific) into the engine though... Assuming they did, I'd take just a few hours for tons of people to show up asking how to customize the system and do things differently, so what would even the point
Thanks for your post, but I have no idea why is this request always assumed to a 100% protected system. This isn't possible. Everybody should know it. Every system can be broke with a great ambition. But it is a difference to store your savegames as plaintext or encrypted binary. In best case with a hash to avoid lucky successively byte change attemptions. ... Whatever. This keeps the most people away. Sorry I did not specified my goal. I do not want a most secured savegame system for a online game. Just a simple savegame protection like all other games have. Indeed a proprietary format can be more secure. Maybe someone will decrypt the savegame and build a editor for cheating. I'm a bit disappointed that this topic is always blocked by people saying "oh, it's not secure. You can't protect your data." xD In fact it's a request to avoid plain-text save data. btw. BinaryFormatter is also plain-text with a bit byte coded values. Conclusion: Encrypt data by obfuscating. Develop your own encrypted savegame system. You can use C# AES as a good base. 100% protection is impossible. This should everybody know. For those who claim it is safe only against noobs: Let's bet you can't decrypt it.
I would ask first, is this strictly for single player? If so, why concern about cheating? You can encrypt saves, but players perhaps start using cheat engine, for whom is more determined. Let player do whatever they like with their purchased game.
Most games doesn't even encrypt it. Just don't store it as text / xml / json. (Any human-readable format). Do a binary serialization. So, most of the people won't be able to modify it via notepad. People that hack will hack it anyway. Singleplayer games doesn't need obfuscation / encryption, and you're simply wasting your development time.
I hope this helps: https://stackoverflow.com/questions/37872255/encryption-and-decryption-of-a-text-file .Net has a built in encryption and decryption. Just create a function that will write your data as a encrypted text file data and when loading just de-crypt it. Youtube has tons of examples as well. I'll try to find a code snippet for you. Going to meeting right now
Look up Xor obfuscation, and you can just as easily use it on strings as you can on byte arrays. The people who really know what they are doing you are not going to be able to stop with really anything, but this is super simple to implement and will deter pretty much anyone who is just casually looking at what they can play with.
Yeah, just use System.Security.Cryptography. It's there; might as well use it. It's like 3 lines of code. This is a nice tutorial with code: https://developingsoftware.com/how-to-securely-store-data-in-unity-player-preferences It describes storing the resulting encrypted data in PlayerPrefs, but there's no reason you couldn't write it to a local disk file or send it to a server.
Something I used in the past is compression, i.e. save the data as png (using unity standard api) - good enough as a simple barrier
I will try translate for you. If I see some random gibberish images, which suppose to be saved data, but I don't know about it, yet the take a lot of space, I will be keen to delete them, to release space.
who says this will happen? - just call what you save "savegame.dat" - they should take less space than uncompressed Spoiler: edit: something like this Code (CSharp): // the serialized data you want to save byte[] saveData; // compress the data using a 4 color channel texture int dim = Mathf.CeilToInt(Mathf.Sqrt(Mathf.CeilToInt(saveData.Length / 4))); Texture2D t = new Texture2D(dim, dim, TextureFormat.RGBA32, false); byte[] temp = new byte[dim*dim*4]; System.Array.Copy(saveData, temp, saveData.Length); t.LoadRawTextureData(temp); // i think no need to apply since no gpu use temp = t.EncodeToPNG(); // save to disk - there will be some "empty" space at the end when you decompress System.IO.File.WriteAllBytes(Application.dataPath + "/savegame.dat", temp);
Who goes around deleting random files in their game directories, that a recipe for disaster Also who makes savedata that takes gigabytes. Neither of these scenarios seems likely to me.
Just don't name it .png, and don't use .jpg or lossy formats would make it about right to me. Not quite understand why would do all that extra operations for it instead of using binary. But its up to you.
I merely just been translating. But occasionally I delete temp and save files, if they grow out of control.
Witcher 2 save system is an abomination example of how to not to do save system. At the end of the playthrough I've ended up with 1k+ save files, each of them were about 4MB. That's what I did as well. Went and deleted some of them. Not to mention that it also loaded ALL data of them without paging involved. (Probably including screenshots as well) Single list for 500+ items were lagging so hard, that it caused almost 5+ seconds to open load menu on SSD. So yeah, imagine if that were the images stored in the folder with .png extension. What would any user do? Without CS education behind their back ofcourse.
You can save PNG compressed data into any file you want. Like Unity is able to save tar gz files into .unitypackage files. BTW, I would not and I do not do any of these things, I save games into simple binary with my own format with version control. If you want a quick tutorial I use similar what @Jasper-Flick describes in his tutorial: https://catlikecoding.com/unity/tutorials/hex-map/part-12/
I try and keep my saved data as humanly readable as possible IE: Code (CSharp): PlayerName = "Sparrow" Funds = 1000 I WANT that players with no proggraming knowledge what so ever be able to now only read it but understand intuitively how to modify them, you may think it makes the game "breakable" i say it add a whole lot. as others have probably said(havn't read all the posts) unless you save data to your own server you can't get around this problem, you can only make it hard for people that want to do that type of stuff this is all provided we're talking singleplayer/local multiplayer and not online matchmaking type stuff Isn't compressing and uncompressing a saved game image(which is super weird to me to begin with) is like super prone to data corruption?
The solution I proposed is by no means the only solution but depending on what the criteria are, it can be a feasible one. I have used it before, because it made sense in that scenario. It's a while back but as far as I recall the criteria where: local save (no network connection), works on supported platforms (.net compression was not supported at the time), ease of implementation, good compression of the saved data, simple obfuscation (in my view better that binary / custom binary format as the data layout will not change). OP was asking for something simple (build in) and some obfuscation, so it might work in his/her scenario as well. Encryption could be added on top, but if someone puts the energy to tinker with the compressed format, they would likely also break the encryption (since they can get to the key). OP came across as knowledgeable enough to not use a lossy compression format, nor store GB of savegame data as PNG files, etc...
No. PNG supports lossless data compression. (which is not true in case of JPEG files for example) The other possibility is just zip it. (ZLib compression) Also you don't have to call it .zip file. I don't use text files because parsing text is super-slow all the time. I use binary, which can be reloaded and evaluated more quickly.
I like readability in my project. But for storing not only saves and data driven configurations, I use local data base files. Slow in this case is relative term. If we talking about 50 variables for example, this will not hurt at all. But if your save is 4MB size, then yes, you may need different data format.
You are lucky, for some reason this popped up in another thread last week and someone posted an updated version (apparently new versions of unity have some issue with RGBA) see here https://forum.unity.com/threads/lzf...pression-for-unity.152579/page-2#post-6402043
Yes I just read it. Anway, it seems that the conversion process is slow, so maybe its better to stick with LZF. https://forum.unity.com/threads/lzf...pression-for-unity.152579/page-2#post-6402361
It really depends on your use case. Simple enough to just try if it suits or not... not advocating this method but it’s something I used for simplicity