Best practices for fetching values of nodes passed by reference

Godot Version

Godot 4.2.1

Question

I have a question regarding fetching information from nodes that are being passed by reference at run-time (that is, not a hard referenced in code).

I’ve worked with Unreal Engine for a while now and in that engine you can use interface functions to fetch information from objects by pasing references. I want to do something similar in Godot but since I’m not super used to how it works I’ve come up with a way that technically works but I want to get some feedback on whether this is a good way of doing it or not.

My goal is: I want to be able to request the inventory of any object that has one (player, npc, container, etc.). Since Godot doesn’t use interfaces I have to rethink how I go about things and this is what I’ve come up with:

I have a script on autoload that contains the following code:

func RequestInventory(targetObject) -> Array:
	return targetObject.call("_Request_Inventory")

And this is the callable that is being called on the object, I intend to reuse the same function name on every object that has an inventory that can be fetched:

func _Request_Inventory() -> Array:
	return player_inventory.inventory

and this is how I request the inventory in other nodes, in this case the inventory window UI node:

if item_owner:
	item_object = SCharacterData.RequestInventory(item_owner)[item_index]

This works right now, I get the info I want, but I’m curious about what some more experienced users think about this approach. Is it good practice or are there other ways to go about it? I was looking into using signals for this but from my limited understanding you can’t request information with signals, only emit it from the source.

If someone have thoughts on this I’d be delighted to hear it.

Thank you

Maybe you can use an autoload file (e.g. InventoryDataSet) to conclude all your inventories inside?

For example, you can save the inventories like this in that file:

#here use Arrary to contain Dictionary, because items may have orders in an inventory
{
  {"Player":[ {"Money":100}, {"Sword": 1}]},
  {"NPC_one": [{"Stick": 5}], {"Apple": 5}]}
}

and in another autoload file (Item_Dictionary), you can have information of every item like:

{
  "Apple":{
        "Type": Consumables,
        "Max_Stack": 99
             }
}

Thus, when you want to fetch an item, you can straightly use the class name of InventoryDataSet and the owner’s name to locate specific items. For details about an item, you can check Item_Dictionary by using item’s name.

I’m not expert either, this is just another way to achieve your goal, hope it can be useful to you…

If you’re going to have a _Request_Inventory() function on every object with an inventory then you could call that directly, no need for an autoload:

item_object = item_owner._Request_Inventory()[item_index]

or just
item_object = item_owner.inventory[item_index]
if the inventory is actually called “inventory” for every object.

But your way works too, it’s up to your personal preference I guess.

Thank you for your reply! While it’s a great idea (I do a similar thing with storing item tables and such) I don’t think it’s very scalable. The whole idea is that I want to fetch data from objects that aren’t written in code (like spawned objects).

Like this:

Object A to Object B: “Hey can I get your health value?”
Object B to Object A: “Sure, here have it”

I should clarify that I’m asking about a general way to fetch pretty much any information (position, inventory, health, class, dialogue, etc.) and that my solution does work, I’m just curious if there are better ways to do it.

Thank you Monday, that’s a great simplification of the code. I didn’t know you could call functions like that on dynamically typed classes.

1 Like