
Publisher
aendawyn
Godot Signals
Godot Signals is an advanced and powerful signal management system for the Godot Engine, designed to enhance signal handling and simplify communication between game components. This plugin brings flexibility, efficiency, and high performance to your Godot projects, allowing developers to create complex signal workflows with ease. Key Features: - Advanced Signal Processing: Build signal processing chains with filtering, transforming, and mapping capabilities. - Signal Broker System: Easily con...
A powerful signal system for Godot Engine that provides efficient signal handling with support for filtering, mapping, centralized event management, and high-performance signal processing.
๐ฃ๏ธ Roadmap
Here are some planned features and improvements:
- ๐ Broker Binding: Possibility to bind to the broker and receive a GSignal instance
- โก Extended Operations: Add more operations to GSignal such as debounce, merge, and more
- ๐ Suggest a feature by opening an issue on GitHub!
โจ Features
- ๐ Signal Processing: Create signal processing chains with filter and map operations
- ๐ก Signal Broker: Connect signals across your game without direct object references
- โก Smart Connection Types: Automatically optimizes for high or low frequency signals
- ๐ Pattern Matching: Subscribe to signals using wildcard patterns
- ๐ท๏ธ Alias System: Identify objects by name, groups, or custom aliases
- ๐ Optimized Performance: Reduced overhead and minimal allocations for efficient processing
๐ Quick Start
๐ Signal Processing
Create powerful signal processing chains with just a few lines of code:
# Filter, transform, and react to signals
GSignals.from(damage_signal)
.filter(func(amount: int) -> bool: return amount >= 10)
.map(func(amount: int) -> int: return amount * critical_multiplier)
.bind(func(final_damage: int): apply_damage(final_damage))
๐ก Signal Broker
Connect components without direct references:
# Broadcasting side: Register player node's signals with the broker
GBroker.broadcast_signals_of(player_node, "player")
# Listening side: Subscribe to player damage events anywhere in your code
GBroker.subscribe("player:damage_taken", func(amount): update_health_ui(amount))
๐ฅ Installation
- Download or clone this repository
- Copy the
addons/godot-signals
folder into your project'saddons
directory - Enable the plugin in Project Settings > Plugins
๐ Tutorial
๐ Signal Processing
๐ Basic Signal Connection
# Connect to a signal with a simple callback
GSignals.from(player.health_changed)
.bind(func(new_health): update_health_bar(new_health))
๐ Filtering Signals
# Only process signals where the value meets certain criteria
GSignals.from(enemy.attack)
.filter(func(damage: int) -> bool: return damage > 5)
.bind(func(damage): play_heavy_hit_sound())
๐ Transforming Signals
# Transform signal data before processing
GSignals.from(position_changed)
.map(func(pos: Vector2) -> float: return pos.distance_to(Vector2.ZERO))
.bind(func(distance: float): set_volume(100 - distance))
โฑ๏ธ Delaying Signals
# Delay signal processing by a specific time
GSignals.from(damage_taken)
.delay(0.5) # Delay by 0.5 seconds
.bind(func(amount): play_delayed_damage_effect(amount))
๐ Debouncing Signals
# Debounce rapid signal emissions
GSignals.from(mouse_moved)
.debounce(0.1) # Only process after 0.1s of inactivity
.bind(func(position): update_hover_effect(position))
๐๏ธ Connection Management
# Store and manage connections
var connection = GSignals.from(timer.timeout).bind(func(): spawn_enemy())
# Temporarily disable connection
connection.stop()
# Re-enable connection
connection.start()
๐ก Signal Broker
๐ฃ Broadcasting Signals
# Register an object's signals with the broker
GBroker.broadcast_signals_of(
player, # The object whose signals will be broadcasted
"player", # Alias for identifying the object (optional)
GBroker.GBrokerBroadcastFlags.SCRIPT_ONLY # Which signals to broadcast
)
๐ท๏ธ Setting Multiple Aliases
# Register with multiple aliases for more flexible subscription patterns
GBroker.broadcast_signals_of(
boss_entity,
["boss", "enemy", "entity"]
)
๐ Subscribing to Signals
# Subscribe to specific signals
GBroker.subscribe("player:health_changed", func(new_health): update_health_ui(new_health))
# Use wildcard patterns to subscribe to multiple signals
GBroker.subscribe("player:*", func(emitter, signal_name, args): print("Player signal: ", signal_name))
GBroker.subscribe("*:damage_taken", func(damage): update_global_damage_counter(damage))
๐งน Cleanup
# Clear all subscriptions and signal handlers when switching scenes
func _exit_tree():
GBroker.reset()
๐ฌ Advanced Broker Usage
๐ Callback Arguments Handling
The broker intelligently handles callback arguments depending on how many parameters your callback function accepts:
# Just receive the signal arguments (most common)
GBroker.subscribe("player:health_changed", func(health_amount): update_ui(health_amount))
# Receive emitter object, signal name, and arguments
GBroker.subscribe("player:*", func(emitter, signal_name, args):
print("Signal %s from %s with args %s" % [signal_name, emitter.name, args])
)
# Mixed patterns with different argument counts
GBroker.subscribe("enemy:hit", func(damage, hit_position):
spawn_particle(hit_position)
apply_damage(damage)
)
# Missing arguments are filled with null
GBroker.subscribe("*:*", func(emitter, signal_name, arg1, arg2, arg3):
# arg2 and arg3 will be null if the signal emits less than 3 arguments
print("%s emitted %s with up to 3 args: %s, %s, %s" % [
emitter.name, signal_name, arg1, arg2, arg3
])
)
๐ Notes on argument handling:
- If the callback has fewer parameters than the signal provides, extra signal arguments are ignored
- If the callback has more parameters than the signal provides, extra callback parameters receive null
- The first callback parameter can receive the emitter object if an extra parameter is available
- The second parameter can receive the signal name if additional parameters are available
- Subsequent parameters receive the signal arguments
๐ง Advanced Features
โก Custom Signal Frequency Optimization
# Optimize for high-frequency signals (e.g., position updates)
GSignals.from(position_changed, GSignals.GSignalsBindFlags.HIGH_FREQUENCY_HINT)
๐ค Automatic Alias Detection
When no alias is provided, the broker automatically uses:
- ๐ฅ The node's groups (except internal groups)
- ๐ The node's name
- ๐ค Snake case version of the node's name
# For a node named "PlayerCharacter" in group "characters"
GBroker.broadcast_signals_of(player_node)
# This will automatically register with aliases:
# - "characters" (from group)
# - "PlayerCharacter" (from name)
# - "player_character" (snake case conversion)
โ๏ธ Performance Considerations
- ๐ Chain operations carefully as each adds processing overhead
- ๐๏ธ Use the
HIGH_FREQUENCY_HINT
flag for signals that emit multiple times per frame - ๐ง The pattern matching system uses caching to optimize frequent signal matches
- ๐ Direct signal connections with GSignals are more efficient than broker subscriptions when you have direct references
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.