Loading Custom Resources breaks _to_string() function

Godot Version

v4.7.1.stable.official [a13da4feb]

Question

I made custom Resource:

class_name CharacterResource extends Resource


static var autogen_outline: Callable = func (color: Color) -> Color:
	return color

static var outline_size: int = 1


@export var name: String
@export var color: Color
@export var outline_color: Color


func _init(
	set_name: String,
	set_color: Color,
	generate_outline: bool = false,
	set_outline_color: Color = TYPE_NIL
	) -> void:
	self.name = set_name
	self.color = set_color
	if generate_outline:
		outline_color = autogen_outline.call(color)
	elif set_outline_color:
		outline_color = set_outline_color


func save(path: String) -> void:
	ResourceSaver.save(self, path)

static func load_res(path: String) -> CharacterResource:
	if not FileAccess.file_exists(path):
		return
	var ret: CharacterResource = load(path)
	return ret


func _to_string() -> String:
	return "{}, colored {}".format([name, color], "{}")

I was testing the save/load functions and when I print them they give different results:

@tool
extends EditorScript

func _run() -> void:
	_test_character_res()


func _test_character_res() -> void:
	var test_char_res:= CharacterResource.new("TestName", Color("#703"))
	var path:= "res://Saves/%s.tres" % [test_char_res.name]
	test_char_res.save(path)
	var new_char_res:= CharacterResource.load_res(path)
	print(test_char_res)
	print(new_char_res)

#Result
TestName, colored (0.4667, 0.0, 0.2, 1.0)
(res://Saves/TestName.tres):<Resource#-9223368432269844612>

When I checked what objects they are they are not the same:

print("***")
print(var_to_str(test_char_res))
print("---")
print(var_to_str(new_char_res))
print("***")

#Result
***
Object(Resource,"resource_local_to_scene":false,"resource_name":"","script":Resource("uid://dacllbwd7slro", "res://VNTools/Objects/character_res.gd"),"name":"TestName","color":Color(0.46666667, 0, 0.2, 1),"outline_color":Color(0, 0, 0, 0))

---
Resource("uid://dojmrqmsbm1og", "res://Saves/TestName.tres")
***

How can I load resources so that it wouldn’t override _to_string()function?

Any errors reported by the engine?

When overriding _init() with a function that takes arguments, you should always provide default values for all arguments. Otherwise the constructor cannot be called by the engine.

I’ve added the defaults to _init

func _init(
	set_name: String = "Name",
	set_color: Color = Color("#000"),
	generate_outline: bool = false,
	set_outline_color: Color = TYPE_NIL
	) -> void:

but nothing changed.

And the were no errors.

Try declaring the exact static type for new_char_res

I’ve done some testing and found that when you get it as a return from a function (any function not just static) it is a Resource(“UID, PATH”) that overrides your functions and when you declare it in local scope it gives you an Object(Resource, …).

So I don’t understand why it behaves that way and how can I use it without always redeclaring it…

I was thinking about it and just gave up. The best I can do is make It a different class so that Resources can’t override any function and use another class that extends Resources just to save/load data.