Events & Registry¶
The Pedre framework uses an event-driven architecture to decouple plugins. The EventRegistry allows dynamic discovery and registration of event types by name.
How Events Are Loaded¶
Pedre uses a plugin-style architecture for loading events. When the game initializes, the EventLoader automatically imports event modules specified in your settings, which triggers their @EventRegistry.register decorators to execute and register the events.
INSTALLED_EVENTS Setting¶
Events are configured through the INSTALLED_EVENTS setting, which is a list of Python module paths containing event classes.
Default built-in events:
INSTALLED_EVENTS = [
"pedre.plugins.audio.events",
"pedre.plugins.camera.events",
"pedre.plugins.dialog.events",
"pedre.plugins.inventory.events",
"pedre.plugins.particle.events",
"pedre.plugins.scene.events",
"pedre.plugins.npc.events",
]
Adding Custom Events¶
To add your own custom events, extend the list in your project's settings.py:
from pedre.conf import global_settings
INSTALLED_EVENTS = [
*global_settings.INSTALLED_EVENTS, # Include built-in events
"myproject.custom_events", # Your custom events module
"myproject.plugins.weather.events", # Plugin-specific events
]
You can also replace built-in events with your own implementations by omitting the built-in module and adding your custom one instead.
EventRegistry¶
The EventRegistry maps string names (like "npc_interacted") to Event classes. This enables the scripting plugin to subscribe to events defined in JSON without importing the actual Python classes.
Location¶
Creating Custom Events¶
To add a new event type that scripts can listen for:
1. Define the Event Class¶
Use the @EventRegistry.register decorator to associate a unique name with your event class.
from dataclasses import dataclass
from pedre.events.registry import EventRegistry
@EventRegistry.register("weather_changed")
@dataclass
class WeatherChangedEvent:
weather_type: str
intensity: float
2. Publish the Event¶
Publish the event from your plugin using the context's event bus.
def set_weather(self, type, intensity):
self.current_weather = type
# ... apply changes ...
# Notify other plugins/scripts
self.context.event_bus.publish(WeatherChangedEvent(type, intensity))
3. Use in Scripts¶
Scripts can now trigger on this event using the registered name:
{
"react_to_rain": {
"trigger": {
"event": "weather_changed",
"weather_type": "rain"
},
"actions": [
{
"type": "dialog",
"speaker": "Villager",
"text": ["Looks like rain again..."]
}
]
}
}
Best Practices¶
- Naming: Use lowercase, underscore_separated names for event keys (e.g.
item_dropped). - Data: Keep event classes simple (dataclasses are recommended).
- Scope: Events should represent significant state changes or interactions, not every frame update.