You already described most of their characteristics.
I most likely use signals in GUI elements, or re-usable scenes, because there are an elegant way of sending events to whatever node is using them. Want a level selector? Fine, instantiate it where you want and listen to level_selected
, done. Want two level selectors? Same, it just works. And most importantly, they are scoped and named with signal my_signal
, so you are less likely to do a mistake.
I used groups when I was too lazy to find a design where a node has to communicate an event to a node which is far away in the hierarchy. I think the use case where multiple nodes listen to the same event is the best, because you simply don't have to come up with boilerplate code to dispatch the event.
But... in general I try to avoid groups whenever I can because they have no scope (global), their name is global (another problem for addons), and when you open a project, nothing tells you which groups are in use and which functions are called on them unless you read all the script files and scenes.
You could say "this is my project, I know everything", but come back 1 month later and you'll be like "did I made a group for that thing?".
In small projects they can still be of use, because it's less tedious to listen for global messages. Maybe they are going to be improved in the future, but at least I try to have a .gd file listing all groups to have auto-completion and self-documentation.