Saving player progress is essential for most games. Godot's resource format lets you do it with minimal code, and it works naturally with the same data structures you already use in your game.
The resource format is what Godot uses internally to store all project files: scenes, animations, materials, particles, and more. For save games, it has clear advantages over formats like JSON because it natively supports Godot value types like vectors, it requires less code, and it only loads once by default, even if you load the file from multiple places. You can even nest resources inside other resources, and Godot will pack everything into a single save file automatically.
To build a save system with resources, you create a script that extends Resource and add @export variables for each piece of data you want to save. That can be numbers, strings, dictionaries, or other resources such as character stats, inventory, and map data. To write the file, call ResourceSaver.save(). To read it back, call load(). Godot loads each unique resource only once, even if it is referenced in multiple places.
Note that resources and most other Godot-native save methods support objects, which means they can contain and execute code! If your game lets players load save files or mods from external sources, be careful: loading a resource from an untrusted source could easily run malicious code. In that case, consider using FileAccess.store_var() and FileAccess.get_var() for binary serialization without object support, or a community plugin that implements safe resource loading.
JSON works for exchanging data between programs, but it has friction when used with Godot. It doesn't support Godot types like Vector2Vector2 or ColorColor natively, so you have to convert everything manually. Resources skip that conversion entirely and require significantly less code to set up.