Add score when the enemy is killed

Godot Version

4.2.2

Question

I am making a space shooter where the score is added to the score system when player kills the enemy. I have an architectural question - what would be the best approach to do that?
I can think of a couple of different ways:

  1. Expose a public method from ScoreSystem that would be called by the enemy right before it’s queue_freed. That sounds bad to me, because Enemy class should not be dependent on ScoreSystem.
  2. Make enemy emit a signal right before it’s queue_freed. I have tried that briefly and it appears to be working. That sounds good in terms of design and simplicity, is it a good practice though? Can it cause some issues, like signal not being sent/handled properly?
  3. Emit a signal from the enemy and then “soft delete” it, for example disable rigidbody and sprite so that it appears as destroyed to the player. Call queue_free() in a deferred manner.

What would be the best way to approach that problem?
Should I delay a queue_free() call on the enemy when it’s emitting a signal?

I wouldn’t call this “bad” necessarily (I’ve written way worse things during gamejams), but it’s certainly not optimal when you want to keep your code modular and as decoupled as possibel, yes.

Yes!

Unlike you run into a bug or the game crashes, the signal should always be sent! The handling of the signal has to be implemented elsewhere (e.g. in your ScoreSystem), so of course things could go wrong there. You might run into trouble when you try to access the (by then potentially free’d) node, but this is usually easy to avoid by providing all necessary information as arguments to the signal, e.g.:

signal killed(worth)

var worth_in_points := 5

func _on_death():
    emit_signal("killed", worth_in_points)

No. queue_free already is delayed until the end of the current frame (and in case you called any deferred functions from that node, even longer!). Again: Just provide all necessary info as arguments to the signal, and you shouldn’t be running into any trouble while doing approach #2. :slight_smile:

1 Like

That’s what I wanted to know, thanks!