How to save and load a game in Godot 4: FileAccess
By Eduardo Orellana · Updated
Open the file with FileAccess.open("user://save.dat", FileAccess.WRITE), write your data with store_var(), and read it back with FileAccess.open(path, FileAccess.READ) and get_var(). Godot 3's File class is gone: File.new() fails to parse with Identifier "File" not declared in the current scope.
AppImage, x86_64. Ubuntu 22.04, Debian 12, Fedora 39 or newer.
Intel or AMD Chromebook, with Linux turned on.
What Godot is checking
Godot 4 replaced File with FileAccess, opened through a static open() that returns the file or null. The file closes when the last reference to it goes, at the end of the function here.
store_var() writes any Variant, a Dictionary of your game state included, in Godot's binary format, and get_var() reads it back with its types. Objects are not stored unless you allow it, which is safer for save files.
user:// is the per-user data folder Godot gives each project, writable in exported games, unlike res://.
Reproduce it
A Godot 3 save, in a Godot 4 project.
extends Node
func _ready():
var file = File.new()
file.open("user://save.dat", File.WRITE)
file.store_var({"level": 3})
file.close()
What Godot 4.7.2 prints
Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org
SCRIPT ERROR: Parse Error: Identifier "File" not declared in the current scope.
at: GDScript::reload (res://answers/how-to-save-a-game-in-godot-4/repro.gd:4)
SCRIPT ERROR: Parse Error: Identifier "File" not declared in the current scope.
at: GDScript::reload (res://answers/how-to-save-a-game-in-godot-4/repro.gd:5)
ERROR: Failed to load script "res://answers/how-to-save-a-game-in-godot-4/repro.gd" with error "Parse error".
at: load (modules/gdscript/gdscript_resource_format.cpp:46)Fix it
Save a Dictionary to user:// and load it back.
extends Node
const SAVE_PATH := "user://save.dat"
func save_game(state: Dictionary) -> void:
var file := FileAccess.open(SAVE_PATH, FileAccess.WRITE)
file.store_var(state)
func load_game() -> Dictionary:
if not FileAccess.file_exists(SAVE_PATH):
return {}
var file := FileAccess.open(SAVE_PATH, FileAccess.READ)
return file.get_var()
func _ready() -> void:
save_game({"level": 3, "coins": 120, "position": Vector2(64, 32)})
var state := load_game()
print(state)
print(typeof(state["position"]) == TYPE_VECTOR2)
What the fixed script prints
Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org
{ "level": 3, "coins": 120, "position": (64.0, 32.0) }
trueSaving as JSON instead
JSON is readable and editable by hand, but it has no Vector2 or int: every number comes back a float. Use JSON.stringify() to write and JSON.parse_string() to read, and convert the types yourself.
Saving Resources
A custom Resource with @export properties saves with ResourceSaver.save(res, "user://save.tres") and loads with load(). Loading a .tres can run scripts, so only load save files your game wrote.
Verified on Godot 4.7.2
Both scripts on this page were run headless on Godot 4.7.2 (4.7.2.stable.mono.official.ed1daf0bf) on 18 October 2026, and the output above is what Godot printed, unedited.
Where the check lives in Godot's source: [gdscript_analyzer.cpp line 4689, the message](https://github.com/godotengine/godot/blob/4.7.2-stable/modules/gdscript/gdscript_analyzer.cpp#L4689), [FileAccess in the class reference](https://github.com/godotengine/godot/blob/4.7.2-stable/doc/classes/FileAccess.xml).
Questions
- Where is user:// on Windows?
- %APPDATA%\Godot\app_userdata\<project name>\ by default, or %APPDATA%\<project name>\ when the project sets a custom user dir. OS.get_user_data_dir() prints it.
- Why did FileAccess.open() return null?
- The path is not writable or the folder does not exist. FileAccess.get_open_error() says why.
Related
- How to parse JSON in Godot 4
- Identifier "…" not declared in the current scope
- Every verified Godot 4 answer
- Trying to return a value of type "…" from a function whose return type is "…" in Godot 4
- Invalid type in static function '…' in type '…'. Cannot convert argument in Godot 4
- Cannot get return value of call to "…()" because it returns "void" in Godot 4
- Invalid access to property or key '…' on a base object of type 'Dictionary' in Godot 4
- Can Mistral Large 4 write working Godot 4 code? 12 of 15 on the first try
Flockbay's agent reads Godot's debugger output and fixes errors like this one in your project, on the official Godot.
Download Flockbay free