I need to create different files for saving and settings, I have seen that I can assign anything but I would like to know if there is no problem using .tits for example
and how could I put the .tits in an array different from the .config?
I need to create different files for saving and settings, I have seen that I can assign anything but I would like to know if there is no problem using .tits for example
and how could I put the .tits in an array different from the .config?
See here for how to save files. The extension can be anything, but saving JSON would be the easiest thing. https://docs.godotengine.org/en/stable/tutorials/io/saving_games.html
You can also manually save and load whatever you want. See here: https://kidscancode.org/godot_recipes/basics/file_io/
Also be sure to specify which file formats are saved on export (check the export settings).
i mean i need something like this
var saves = get_files(.save, not others)_in_dir("user://) for i in saves: do stuff()
See this answer. You'll just need to check that the file ends with ".save". https://godotengine.org/qa/5175/how-to-get-all-the-files-inside-a-folder?show=5176#a5176
ok, this works, ty
func probaBuscaFiles():
var path = "user://"
var saves = []
var dir = Directory.new()
dir.open(path)
dir.list_dir_begin()
while true:
var file = dir.get_next()
if file == "":
break
if file.begins_with("save"):
saves.append(file)
dir.list_dir_end()
print(saves)
a question about json,
lets say i got big data i want to store, many types of data; many resources, many types of techs, factions relations, all that cool stuff and, many types of buildings with persist, that everyone is a little line in the file, like a city builder game and need to read the information and location of 500? buildings and i want to read all that information fast in every scene change
can i store all that information in a single big dictionary (long line) like "all_player_data" or its better way to work to store all the info in differents dictionarys (shorts lines) like "player_resources", "player_techs", "player_stats", etc
i am confused, my files are .tits but the stored info is json? or the .tits is really a .json?
how workflows the json? the size (line) matters? is fast? can handle all the info without problems? should i use some different files?
does the number of lines matter?
can the engine handle many read-files at time? or is better workflow read the files one-by-one?
So Dictionaries (or JSON files) really have no limit. You could probably store millions of data values with no problem. However, accessing files and parsing them can be slow, so what you want to do is load the file at startup (using JSON.parse() for example) and then only work with the Dictionary itself when you need to access data. It is random access, so you can get any value individually if you know the key (usually the object name or the property name).
ok im not sure what do you mean with random access
@cybereality said:
It is random access, so you can get any value individually if you know the key (usually the object name or the property name).
what im doing right now is store the 'choosen one' entry of the dictionarys with a 0 so im sure it will be in the 1st position because the info is stored alphabetically
var playerData = {
"0scene" : "savedata",
"credits": "0",
"total_population": 0,
etc
etc
}
var buildingData = {
"0scene" : "building",
"population": 0,
etc
etc
}
and then when i open the file json for read the data i proceed like this:
var location = "user://autosave.tits"
save_game.open(location, File.READ)
while save_game.get_position() < save_game.get_len():
var current_line = parse_json(save_game.get_line())
if current_line["0scene"] == "what im looking for":
do my things()
save_game.seek_end()
save_game.close()
so if the first entry is not the choosen one, it jumps to the next line without keep reading the actual line
this works or im doing a nonsense?
No Dictionaries are not Arrays, there is no guarantee of an order or that one entry is before another. And you don't access it line by line, you parse the whole file at once. See this example for loading the JSON file: https://www.reddit.com/r/godot/comments/7wj5p3/need_help_reading_data_from_a_json_file/du0vmoe/?utm_source=reddit&utm_medium=web2x&context=3 At the end you have a variable "data" which contains everything (again, not in any particular order). So you could do something like this:
var population = data.population
if data["scene"] == "building":
# do something for buildings
i make this for overwrite a savegame slot from the autosave
var file= File.new()
if not file.file_exists(Datos.autosavemap01):
return # Error! no save to load.
else:
var file1 = File.new()
var file2 = File.new()
file1.open(Datos.autosavemap01, File.READ)
file2.open(Datos.saveID_map01, File.WRITE_READ)
while file1.get_position() < file1.get_len():
var current_line = parse_json(file1.get_line()) # read a line in file 1
if current_line == null:
continue
file2.store_line(to_json(current_line)) # store the line in file 2
file1.close()
file2.close()
print("data map 01 saved:", Datos.autosavemap01)
sometimes i get this error i am not sure if because the script or what
ERROR: File must be opened before use.
No, that still doesn't really make sense. I would recommend checking out the links I posted again. As I mentioned, JSON is not a line-by-line data format. You save and load the whole file at once. If you don't wish to do that, then don't use JSON. You can also save and load individual variables, which maybe easier for this. Check the original two links I posted in this thread.
Also, if you just want to copy a file you get get the string and then store the string:
var file1 = File.new()
var file2 = File.new()
file1.open(Datos.autosavemap01, File.READ)
file2.open(Datos.saveID_map01, File.WRITE)
file2.store_string(file1.get_as_text())
file1.close()
file2.close()
that woks so much better, thanks Cyb
I just realized, i am saving the game data in a .json in the user 'player' folder
What prevents the player from editing those files with notepad ++ and adding 1 million "credits" to their game, in example?
@Zelta said: What prevents the player from editing those files with notepad ++ and adding 1 million "credits" to their game, in example?
any ideas?
You could encrypt the file first using JSON: https://docs.godotengine.org/en/stable/classes/class_crypto.html
Also, if you're worried about overhead, you could always store your files in binary. Check out the File object: https://docs.godotengine.org/en/stable/classes/class_file.html?highlight=File The file object has functions like "get_32" and "store_32" for getting and storing values. It also stores different kinds of strings. Of course, then you have to design your own binary file format.
which method is easier? or more efficient when reading / applying the data in-game?
@Zelta said: which method is easier? or more efficient when reading / applying the data in-game?
JSON is probably easiest from a security perspective, since it's a human-readable format prior to encryption. This makes it a lot easier to verify the data that is being decrypted is the same as the data you passed to be encrypted. Looking at the example in the crypto class, I do not think it would be too difficult to get working, you'd just need to make sure the key and certificate are usable and have a condition if they are missing, since you wouldn't be able to read the file without it.
Storing the data as binary using the File class also is a usable solution, and one I've opted for a few times for saving user data. It's binary, so the potential of someone simply opening it and modifying it are a lot lower, as they would need to use a Godot instance or a program that allows them to read and write the binary data Godot stores. It's not completely fool proof and probably not quite as secure as using JSON with the crypto class, but it would probably prevent all but the most determined. Storing in binary also would be easier for Godot to read at runtime, as it's already in the correct format. JSON is a little slower because it has to be parsed into Godot data types, while with the binary data stored in the File class, it can just be retrieved and used.
If I was going to choose one of the two, I'd probably use the File class. Then you don't need to worry about storing keys and certificates to open and use the data, most everyone will not be able to cheat and modify the values, and the data is pretty well optimized to being used in Godot. You can even use store_var
and get_var
to store variables directly, as long as it's a Godot type. But that's just what I would do, I would recommend you choose what you think will work best for your project and go with that :smile:
This tutorial (posted earlier) shows how to do it. https://kidscancode.org/godot_recipes/basics/file_io/
It's honestly secure enough, and most people unless they were hackers would not know how to cheat.
@cybereality said: and most people unless they were hackers would not know how to cheat.
Or programmers, or computer(hardware) scientists. Or very dedicated enthusiasts. But I guess 'hacker' can be attributed to any of them as well.
it's as simple as replacing store_string() with store_var(), and get_as_text() with get_var() ?? or am I missing something?
How can I bring back the persistent nodes this way?
i got no problems to store and load the data
but i cant bring back the persistent nodes
im getting continues -Unicode error: invalid skip -ERROR: Error when trying to encode Variant -ERROR: decode_variant: Condition "len < 4" is true. Returned: ERR_INVALID_DATA
Are you storing the entire node using store_var
? I think what you may want to do is store the node data (maybe in a dictionary?) and then have the persistent node either reset itself by reading the values, or have the persistent nodes delete themselves and make new nodes using the save data as their initial values.
@TwistedTwigleg said: Are you storing the entire node using
store_var
? I think what you may want to do is store the node data (maybe in a dictionary?) and then have the persistent node either reset itself by reading the values, or have the persistent nodes delete themselves and make new nodes using the save data as their initial values.
Yes, I was used to loading and saving as it says in the docs, now there is something that I am not doing well and I do not get the point. For example with the autosave, if the data is empty it crashes when I tell it store_var () Other times it stores the data encrypted but also unencrypted ... I have a hell of a mess i keep fighting
lol i create a savegame test i stored a test dictionary with store_var() credits = 50
in the file looks something like this
then i edited the FILE in the notepad \ credits 150
and i open the game and load the savegame
the player has 2000000 credits
ive done with this, looking for other ways
Does it really matter if people cheat?
@cybereality said:
Does it really matter if people cheat?
yes bro, we have to protect the world order https://docs.huihoo.com/godotengine/godot-docs/godot/tutorials/engine/encrypting_save_games.html
i just use the simple way written there and everything is working again, and 'protected', it just took me half an hour rewrite all the codes.
I agree with what the article says. When I have used cheats in a game I have ended up losing interest in it. Not always, but most of them. That's why I never use cheats.
The world is full of hateful cheaters. Not in my game.
And as Sid says, we have to protect the players from themselves.
@Zelta said: lol i create a savegame test i stored a test dictionary with store_var() credits = 50
in the file looks something like this
then i edited the FILE in the notepad \ credits 150
and i open the game and load the savegame
the player has 2000000 credits
ive done with this, looking for other ways
Huh, that’s interesting! I’ve always seen the data like it is in the screenshot, but I guess notepad can translate the binary. In that case, you made need to look at encryption using the Crypto class or a different method for securing the data.
Edit: by in the screenshot, I mean with the null data blocks and all that. I don’t think it showed the variable name or value.
@TwistedTwigleg said:
Edit: by in the screenshot, I mean with the null data blocks and all that. I don’t think it showed the variable name or value.
I shouldn't, right? I don't know how I did it, really. Maybe that file was already contaminated from so many tests, or i didnt code the well the thing. in any case trying to save my game with store_var has been pure hell.
I have too many persistent nodes in different scenes. In this case saving and reading in the files by the documentation way with a password is just what I needed.