Extending Pedre¶
Pedre is designed for extensibility. You can add custom actions, events, conditions, and even entire game plugins without modifying the framework code.
Extension System Overview¶
The Pedre extension system uses a plugin-style architecture with automatic discovery and registration:
- Define your custom component (action/event/condition/plugin)
- Register it using decorators (
@ActionRegistry.register,@EventRegistry.register, etc.) - Configure it in your project's
settings.pyto be loaded - Use it in your JSON scripts or game code
What Can You Extend?¶
Actions¶
Create custom script actions that can be triggered from JSON scripts.
Use Cases:
- Weather plugins (rain, snow, fog)
- Custom UI elements (tooltips, notifications)
- Game mechanics (crafting, combat, puzzles)
- External integrations (analytics, achievements)
Learn More: Custom Actions
Events¶
Define custom events that scripts can listen for and react to.
Use Cases:
- Custom player actions (jumping, crouching)
- Environmental changes (time of day, weather)
- Game state changes (level up, quest complete)
- System notifications (achievement unlocked)
Learn More: Custom Events
Conditions¶
Create conditional checks for script execution.
Use Cases:
- Player stats (health, level, attributes)
- Time-based conditions (day/night, season)
- Complex game state (quest progress, relationships)
- Resource checks (money, items, energy)
Learn More: Custom Conditions
Plugins¶
Build entire game plugins that integrate with the framework lifecycle.
Use Cases:
- Quest management
- Combat plugin
- Crafting plugin
- Weather/time plugin
- Relationship/faction plugin
Learn More: Custom Plugins
Extension Workflow¶
1. Create Your Extension¶
Define your custom component in a Python module:
# myproject/custom_actions.py
from pedre.actions import Action
from pedre.actions.registry import ActionRegistry
@ActionRegistry.register("custom_action")
class CustomAction(Action):
def __init__(self, param: str):
self.param = param
self._executed = False
@classmethod
def from_dict(cls, data: dict):
return cls(param=data["param"])
def execute(self, context) -> bool:
if not self._executed:
# Your custom logic here
self._executed = True
return True
def reset(self):
self._executed = False
2. Register in Settings¶
Add your module to the appropriate INSTALLED_* setting:
# settings.py
from pedre.conf import global_settings
INSTALLED_ACTIONS = [
*global_settings.INSTALLED_ACTIONS, # Include built-in actions
"myproject.custom_actions", # Your custom actions
]
3. Use in Scripts¶
Your extension is now available in JSON scripts:
{
"my_script": {
"trigger": {"event": "scene_start"},
"actions": [
{
"type": "custom_action",
"param": "value"
}
]
}
}
Configuration Settings¶
INSTALLED_ACTIONS¶
List of Python module paths containing action classes.
INSTALLED_ACTIONS = [
"pedre.plugins.audio.actions",
"pedre.plugins.camera.actions",
"pedre.plugins.dialog.actions",
"myproject.custom_actions", # Your custom actions
]
INSTALLED_EVENTS¶
List of Python module paths containing event classes.
INSTALLED_EVENTS = [
"pedre.plugins.npc.events",
"pedre.plugins.dialog.events",
"myproject.custom_events", # Your custom events
]
INSTALLED_CONDITIONS¶
List of Python module paths containing condition checker functions.
INSTALLED_CONDITIONS = [
"pedre.plugins.inventory.conditions",
"pedre.plugins.npc.conditions",
"myproject.custom_conditions", # Your custom conditions
]
INSTALLED_PLUGINS¶
List of Python module paths containing plugin classes.
INSTALLED_PLUGINS = [
"pedre.plugins.audio.plugin",
"pedre.plugins.dialog.plugin",
"myproject.plugins.weather", # Your custom plugin
]
Best Practices¶
Naming Conventions¶
- Actions: Verb-based, lowercase with underscores (e.g.,
set_weather,spawn_enemy) - Events: Past tense, lowercase with underscores (e.g.,
weather_changed,enemy_spawned) - Conditions: Question-based, lowercase with underscores (e.g.,
is_raining,has_quest) - Plugins: Noun-based, PascalCase with "Plugin" suffix (e.g.,
WeatherPlugin,QuestPlugin)
Documentation¶
Always include docstrings explaining:
- What the component does
- What parameters it accepts
- Return values and side effects
- Usage examples
Error Handling¶
- Actions: Return
Falseto keep action active,Truewhen complete - Conditions: Return
Falseif checks fail, don't raise exceptions - Events: Use dataclasses for clear data structures
- Plugins: Handle missing dependencies gracefully
Testing¶
Create unit tests for your extensions:
# tests/test_custom_actions.py
def test_custom_action():
action = CustomAction(param="test")
result = action.execute(mock_context)
assert result == True
Examples¶
Simple Weather Action¶
@ActionRegistry.register("set_weather")
class SetWeatherAction(Action):
def __init__(self, weather: str):
self.weather = weather
self._executed = False
@classmethod
def from_dict(cls, data: dict):
return cls(weather=data["weather"])
def execute(self, context) -> bool:
if not self._executed:
weather_plugin = context.get_plugin("weather")
if weather_plugin:
weather_plugin.set_weather(self.weather)
self._executed = True
return True
def reset(self):
self._executed = False
Weather Changed Event¶
@EventRegistry.register("weather_changed")
@dataclass
class WeatherChangedEvent:
weather_type: str
intensity: float
Weather Condition Check¶
@ConditionRegistry.register("is_weather")
def check_weather(data: dict[str, Any], context: GameContext) -> bool:
weather_plugin = context.get_plugin("weather")
if not weather_plugin:
return False
return weather_plugin.current_weather == data.get("weather")
Plugin Loader¶
The PluginLoader handles automatic loading and initialization of all extensions. It manages:
- Dependency resolution
- Initialization order
- Lifecycle management (setup, reset, cleanup)
- Event bus wiring
Next Steps¶
- Custom Actions - Create script actions
- Custom Events - Define game events
- Custom Conditions - Add conditional checks
- Custom Plugins - Build complete game plugins
- Plugin Loader - Understand the loading process
See Also¶
- API Reference - Framework architecture
- Scripting Guide - Using extensions in scripts
- Plugins Reference - Built-in plugins documentation