How to collect all values sent by signals

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

We’re building a 4X game where there’s a resource node that emits a signal on every Timer.timeout (tick) to signal to the Player class that it has “gained” more resources. On the Player’s _ready() call, we add the resources by get_tree().get_nodes_in_group(x) whose property overlord, which is a connected node export, matches the Player class so only the Player gets the resources that belong to them.

How does one collect all values send by these signals so the UI can reflect a total amount of resources collected? E.g.:

gold: 242 (x), wood: 211 (x), food: 137 (x), where x is value we want to collect the total of.

enter image description here

We haven’t tried these solutions but thought of a few:

Using an ID system to detect if the resource has been collected already this tick, but this could result in dropped resources leaving them a tick behind. We thought then maybe a queue in addition to this could be implemented but that could leave it open to overload and an ever expanding list of nodes queued up. If you clear the queue then we’re back to the problem of dropped resource values.

Using a resources_total and resource_current variables to store the max resources connected to the Player class and every time the signal is called it would increment the resources_current variable until the total was hit and reset. This isn’t a good solution due to it could allow for the same resource to fire a signal prior to another resource that should be collected first. This doesn’t really solve the issue.

Moving the tick function to the Player class is an option but not the preferred solution. E.g.:

var for_collection := []
var resources := Vector3.ZERO
@onready var tick_timer : Timer = get_node("TickTimer")
_ready():
  for resource in get_tree().get_nodes_in_group("resources"):
    if (resource.overlord == self):
      collection.append(resource)
  tick_timer.connect("timeout", collect_resources)
return

func collect_resources():
  var collect = Vector3.ZERO
  for resource in collection:
    collect += collection.collect_resource()

This should work, but we’d like to keep game super modular in the designer, which is the best practice to go for in this scenario?

Open to all suggestions.

:bust_in_silhouette: Reply From: Inces

Why can’t resources emit signal when they are collected ? Why is timer even needed ?