How to save/load Vector2?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Meyerjc

So, I’ve found that if I use the following code, then I can store all of the variables I want EXCEPT a the Vector2 variable for “last_position”.

var file = File.new()
var savePath = "user://save_file.save"

var last_position = Vector2(0,0)
var player_initial_map_position = Vector2(160, 160)
var player_facing_direction = "down"
var current_scene = "res://Source/Levels/LevelOne.tscn"

var arrow_count = 0
var bomb_count = 0
var gold = 0


var player_inventory_items: Array = [
	null, null, null, null, null, null,
	null, null, null, null, null, null,
	null, null, null, null, null, null,
	null, null, null, null, null, null,
];

var collected_pickups = {}
var trading_seq = "String"
var traded_items = {}

func saveGame():
	var dict = {
		"arrow_count": arrow_count,
		"bomb_count": bomb_count,
		"player_inventory_items": player_inventory_items,
		"collected_pickups": collected_pickups,
		"trading_seq": trading_seq,
		"traded_items": traded_items,
		"health": health,
		"gold": gold,
		"current_scene": current_scene,
	}
	file.open(savePath, file.WRITE)
	file.store_line(to_json(dict))
	file.close()
	
func loadGame():
	if file.file_exists(savePath):
		file.open(savePath, file.READ)
		var tmp_data = file.get_as_text()
		file.close()
		var dict = {}
		dict = parse_json(tmp_data)
		arrow_count = dict["arrow_count"]
		bomb_count = dict["bomb_count"]
		player_inventory_items = dict["player_inventory_items"]
		collected_pickups = dict["collected_pickups"]
		trading_seq = dict["trading_seq"]
		traded_items = dict["traded_items"]
		health = dict["health"]
		gold = dict["gold"]
		current_scene = dict["current_scene"]

I’ve tried adding

file.store_var(last_position)

but unfortunately it seems to cause errors with loading the dictionary.

Any help is appreciated!

:bust_in_silhouette: Reply From: Inces

You can store everything, including Vector2. Perhaps You forget that storing to json will turn all of variables to strings. So they print correctly, but are no longer integers or floats. You have to retranslate them using var2str and str2var methods, or manually
save :

dict = {"last_position" : var2str(last_position)}

load:

last_position = str2var(dict["last_position"])

Thanks! That definitely solved my Vector2 problem, but now my player_inventory_items Array isn’t loading?

Meyerjc | 2022-05-13 19:06

I am not sure how nulls are saved hehe. What data type is it supposed to be if not null ? You know You will never save nodes ?
What is printed now if you try to load inventory items ? Is it empty array ?

Inces | 2022-05-13 20:35

So, my inventory items are saved as resources, and are printed out as follows:

player_inventory_items:[[Resource:1481], [Resource:1487], [Resource:1499], Null, Null, Null, Null, Null, Null, Null, Null, Null, Null, Null, Null, Null, Null, Null, Null, Null, Null, Null, Null, Null]

The Null’s get changed to the resources as items are collected or moved around throughout the inventory.

Meyerjc | 2022-05-13 21:52

You will also never save Resources, just like nodes. These can only be saved and loaded while project is running, and won’t be saved to file. You need to use other variable, that marks your resource when saving and creates it anew when loaded. If your inventory items are not complicated You can use just their names in Strings and load them like this :
example names : “spoon” “needle” “sword”
load:

inventory_items = []
for entry in dict["inventory_items"] :
      inventory_items.append( load("res://items/" + entry + ".tres"))

Too bad if you have complicated, RPG style items, with many properties. If this is so, You will have to encrypt each unique property and save it all within some nested dictionary

Inces | 2022-05-14 07:50