Sending messages between nodes in a database

So I have a dictionary that’s an autoload/global and I have ‘actors’ or game entities that inherit from class_name DEMO_actor for the time being that registers to the dictionary upon _ready() and assigns them a unique ID as their dictionary key and I’m trying to send information to and from each actor within the dictionary.

I want use this system so if, say:

  1. actor1 lands a hit on actor2 in the form of a message
  2. so then actor2 knows that actor1 got them
  3. so actor2 can send another message to actor1 to affect some value within actor1 (like incrementing a score or something).

I’d prefer to use system over using signals, I personally find it more flexible and easier/quicker to set up. Also keeping a database like this allows me to read and write the positions, states and other variables of each game actor for a save/load system

I have been trying to test this out, this is my code…

actor_manager.gd: (this is the autoload)

class_name Actor_Manager extends Node

var validID :int

var actor_Database :Dictionary

func RegisterActor(appli :DEMO_actor) -> void:
	actor_Database[appli] = validID
	appli.AssignID(validID)
	validID += 1 #increment ID for next actor

func GetActorFromID(request :int) -> DEMO_actor:
	return actor_Database.get(request)

test_base_actor.gd: (abstract base class)

class_name DEMO_actor extends Node3D

var actor_ID :int 

func RegisterToManager() -> void:
	ActorManager.RegisterActor(self)
	print("Registered to database with ID of ", actor_ID)

func AssignID(given_id :int) -> void:
	actor_ID = given_id

func GetMessage(msg_Type :int) -> void:
	pass #used by inheriting classes

and the two inheriting/concrete classes…
dummy_actor.gd: (this class RECEIVES messages)

class_name Dummy_actor extends DEMO_actor


func _ready() -> void:
	RegisterToManager() #register to database


func GetMessage(msg_Type :int) -> void:
	
	match msg_Type:
		1:
			print("got message type 1")
		
		2:
			print("got message type 2")
		
		3:
			print("got message type 3")
		
		_:
			print("unknown message type")

msg_actor.gd: (this class SENDS messages)

class_name Message_Actor extends DEMO_actor

func _ready() -> void:
	RegisterToManager()

func _process(delta: float) -> void:

	if Input.is_action_just_pressed("button_1"):
		SendMessageToActor(0,1)  #send message type 1 to ID 0
	if Input.is_action_just_pressed("button_2"):
		SendMessageToActor(0,2)  #send message type 2 to ID 0
	if Input.is_action_just_pressed("button_3"):
		SendMessageToActor(0,3)   #send message type 3 to ID 0

func SendMessageToActor(msg_To :int, mssg_Type :int) -> void:
	ActorManager.GetActorFromID(msg_To).GetMessage(mssg_Type)

The problem is

I got two Node3Ds, one has dummy_actor attached and the other msg_actor.gd and when I run the scene and push a button I get a Invalid call. Nonexistant function 'GetMessage' in base 'Nil'. in the Stack Trace. I clearly have a GetMessage function in my DEMO_actor class so what am I getting wrong here? please help :frowning:

Thank you!

You are setting the DEMO_actor as key, I think this should be like this with the ID as key.

actor_Database[validID] = appli

Since the id is the key used to get the object.

If you still want the object as key then you need to get the keys/values as an array and do a custom search for the id related to the msg.

1 Like

oh you’re right! of course it had to be the simplest of mistakes. Yeah I was making the nodes themselves the key instead of the int like I wanted, whoops… works as intended now, thank you so much for that! :+1: