godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.43k stars 21.26k forks source link

Resource.get_property_list() returns different values depending on being run as standalone or editor. #99722

Open jefvaia opened 23 hours ago

jefvaia commented 23 hours ago

Tested versions

Tested in Godot 4.3 Stable (with Steamworks recompile and all optional build features for windows. Also, mono is enabled but not used)

System information

Windows 10 (Ryzen 5 5600X, Nvidia RTX 4060, 32GB RAM, SSD), Vulkan, Driver version 560.94

Issue description

For networking purposes, I am reading all the important data from a custom resource(non-standard values and script name/hint). During testing, I came across the issue that exported builds of the project, with out without debug, lack certain properties that I unfortunately need. Things like the types it inherits from, and specifically the scripts I made it inherits from.

Steps to reproduce

Create a custom resource and give it a class name. It doesn't matter if it's a whole inheritance chain. Get the properties of the resource through any script. Export the project and it will lack some information.

Minimal reproduction project (MRP)

Godot Resource Properties Bug.zip

jefvaia commented 8 hours ago

I also tested it with Godot 4.1 Stable. The bug still appears.

Mickeon commented 3 hours ago

Could you elaborate on exactly what kind of information is missing? My hunch is that this is somewhat intentional

jefvaia commented 2 hours ago

I have the following custom resource:

extends Resource
class_name NetworkMessage

@export var time_sent: float

This resource gets used by all networking resources. Because of networking reasons, I need to make this resource into an Array[Dictionary] and have all the values of it, including the scripts it's based on. And I use Resource.get_property_list() for this.

This is what the editor returns:

[
  {
    "name": "RefCounted",
    "class_name": "",
    "type": 0,
    "hint": 0,
    "hint_string": "RefCounted",
    "usage": 128
  },
  {
    "name": "Resource",
    "class_name": "",
    "type": 0,
    "hint": 0,
    "hint_string": "Resource",
    "usage": 128
  },
  {
    "name": "Resource",
    "class_name": "",
    "type": 0,
    "hint": 0,
    "hint_string": "resource_",
    "usage": 64
  },
  {
    "name": "resource_local_to_scene",
    "class_name": "",
    "type": 1,
    "hint": 0,
    "hint_string": "",
    "usage": 6
  },
  {
    "name": "resource_path",
    "class_name": "",
    "type": 4,
    "hint": 0,
    "hint_string": "",
    "usage": 4
  },
  {
    "name": "resource_name",
    "class_name": "",
    "type": 4,
    "hint": 0,
    "hint_string": "",
    "usage": 6
  },
  {
    "name": "resource_scene_unique_id",
    "class_name": "",
    "type": 4,
    "hint": 0,
    "hint_string": "",
    "usage": 0
  },
  {
    "name": "script",
    "class_name": "Script",
    "type": 24,
    "hint": 17,
    "hint_string": "Script",
    "usage": 1048582
  },
  { // Note this value
    "name": "network_message.gd",
    "class_name": "",
    "type": 0,
    "hint": 0,
    "hint_string": "res://structs/network_message.gd",
    "usage": 128
  },
  {
    "name": "time_sent",
    "class_name": "",
    "type": 3,
    "hint": 0,
    "hint_string": "",
    "usage": 4102
  }
]

This is what an exported version of the project returns:

[
  {
    "name": "RefCounted",
    "class_name": "",
    "type": 0,
    "hint": 0,
    "hint_string": "RefCounted",
    "usage": 128
  },
  {
    "name": "Resource",
    "class_name": "",
    "type": 0,
    "hint": 0,
    "hint_string": "Resource",
    "usage": 128
  },
  {
    "name": "Resource",
    "class_name": "",
    "type": 0,
    "hint": 0,
    "hint_string": "resource_",
    "usage": 64
  },
  {
    "name": "resource_local_to_scene",
    "class_name": "",
    "type": 1,
    "hint": 0,
    "hint_string": "",
    "usage": 6
  },
  {
    "name": "resource_path",
    "class_name": "",
    "type": 4,
    "hint": 0,
    "hint_string": "",
    "usage": 4
  },
  {
    "name": "resource_name",
    "class_name": "",
    "type": 4,
    "hint": 0,
    "hint_string": "",
    "usage": 6
  },
  {
    "name": "resource_scene_unique_id",
    "class_name": "",
    "type": 4,
    "hint": 0,
    "hint_string": "",
    "usage": 0
  },
  {
    "name": "script",
    "class_name": "Script",
    "type": 24,
    "hint": 17,
    "hint_string": "Script",
    "usage": 1048582
  },
  {
    "name": "time_sent",
    "class_name": "",
    "type": 3,
    "hint": 0,
    "hint_string": "",
    "usage": 4102
  }
]

And I just happened to need the "name": "network_message.gd" and it's other values.

jefvaia commented 1 hour ago

I have found a solution to my problem: using Resource.get_script().resource_path gives the script object form where I can get the values I need. I do think it will be nice if Resource.get_property_list() has a note in the documentation about this, because it does look to be intentional but it's not clear.