From 33cb8e82d44a82245351744cd6c5d0af121ea095 Mon Sep 17 00:00:00 2001 From: Will Stuckey Date: Tue, 28 Oct 2025 12:31:59 -0500 Subject: [PATCH] Add ConfigurableEventManager implementation with example and guide --- EVENTS_GUIDE.md | 96 +++++++++++++++++++++++++++++++++++++ Scenes/Main.tscn | 8 +++- Scripts/EventExample.cs | 81 +++++++++++++++++++++++++++++++ Scripts/EventExample.cs.uid | 1 + 4 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 EVENTS_GUIDE.md create mode 100644 Scripts/EventExample.cs create mode 100644 Scripts/EventExample.cs.uid diff --git a/EVENTS_GUIDE.md b/EVENTS_GUIDE.md new file mode 100644 index 0000000..1fa4694 --- /dev/null +++ b/EVENTS_GUIDE.md @@ -0,0 +1,96 @@ +# ConfigurableEventManager Implementation Guide + +## What is ConfigurableEventManager? + +The ConfigurableEventManager is a Godot Node that provides a visual, inspector-based way to define and manage events in your game without writing code for each event. + +## How to Set It Up + +### Step 1: Add EventManager to Your Scene + +1. Open `Scenes/Main.tscn` in Godot +2. The EventManager node should already be added as a child of Main +3. Select the EventManager node in the scene tree + +### Step 2: Create GameEventResource Assets + +You need to create `.tres` resource files that define your events: + +1. In Godot, right-click in the FileSystem dock → **New Resource** +2. Search for **GameEventResource** and select it +3. Click **Create** +4. Save it in `Resources/Events/` (you may need to create this folder) + +Example event resources to create: + +#### GameStarted.tres +- **Event Name**: `GameStarted` +- **Description**: `Fired when the game begins` +- **Parameter Count**: `0` +- **Category**: `Game` + +#### ScoreChanged.tres +- **Event Name**: `ScoreChanged` +- **Description**: `Fired when player score changes` +- **Parameter Count**: `1` +- **Parameter1 Type**: `int` +- **Parameter1 Description**: `The new score value` +- **Category**: `Player` + +#### PlayerLevelUp.tres +- **Event Name**: `PlayerLevelUp` +- **Description**: `Fired when player gains a level` +- **Parameter Count**: `2` +- **Parameter1 Type**: `string` +- **Parameter1 Description**: `Player name` +- **Parameter2 Type**: `int` +- **Parameter2 Description**: `New level number` +- **Category**: `Player` + +### Step 3: Configure EventManager in Inspector + +1. Select the EventManager node in your scene +2. In the Inspector, find the **Events** array property +3. Click to expand it and set the **Size** to match your number of events (e.g., 3) +4. Drag your `.tres` event resource files into each array slot +5. Optionally enable **Enable Debug Logging** to see event activity in the console + +### Step 4: Use Events in Your Scripts + +See `Scripts/EventExample.cs` for a complete example of: +- Getting a reference to the EventManager +- Subscribing to events +- Raising events +- Unsubscribing from events + +## Key Benefits + +✅ **Visual Configuration** - Define events in the Inspector without code +✅ **Type Safety** - Still get compile-time checking in C# +✅ **Documentation** - Event descriptions and parameter info built-in +✅ **Debug Logging** - Optional logging for all event activity +✅ **Validation** - Warns if you subscribe with wrong parameter count + +## Usage Pattern + +```csharp +// 1. Get reference +_eventManager = GetNode("/root/Main/EventManager"); + +// 2. Subscribe +_eventManager.Subscribe("ScoreChanged", OnScoreChanged); + +// 3. Raise event somewhere +_eventManager.Raise("ScoreChanged", 100); + +// 4. Unsubscribe when done +_eventManager.Unsubscribe("ScoreChanged", OnScoreChanged); +``` + +## Next Steps + +1. Open the project in Godot 4.5 +2. Create your GameEventResource assets in the editor +3. Add them to the EventManager's Events array +4. Use the example script as a template for your game objects +5. Enable debug logging to see events firing in real-time diff --git a/Scenes/Main.tscn b/Scenes/Main.tscn index d4c8400..413692f 100644 --- a/Scenes/Main.tscn +++ b/Scenes/Main.tscn @@ -1,3 +1,9 @@ -[gd_scene load_steps=1 format=3 uid="uid://bvx8qw3yqn5yk"] +[gd_scene load_steps=2 format=3 uid="uid://bvx8qw3yqn5yk"] + +[ext_resource type="Script" path="res://Scripts/Main.cs" id="1_1"] [node name="Main" type="Node2D"] +script = ExtResource("1_1") + +[node name="EventManager" type="Node" parent="."] +script = ExtResource("ConfigurableEventManager") diff --git a/Scripts/EventExample.cs b/Scripts/EventExample.cs new file mode 100644 index 0000000..ac3cc69 --- /dev/null +++ b/Scripts/EventExample.cs @@ -0,0 +1,81 @@ +using Godot; +using EinSoftworks.Events; + +namespace Voider; + +/// +/// Example script demonstrating how to use the ConfigurableEventManager. +/// This would typically be attached to a Player, Enemy, or other game object. +/// +public partial class EventExample : Node +{ + // Reference to the ConfigurableEventManager in the scene + private ConfigurableEventManager _eventManager; + + public override void _Ready() + { + // Get reference to the ConfigurableEventManager node + // (Assumes it's named "EventManager" in your scene tree) + _eventManager = GetNode("/root/Main/EventManager"); + + // Subscribe to events + SubscribeToEvents(); + } + + private void SubscribeToEvents() + { + // Example: Subscribe to a simple event with no parameters + _eventManager.Subscribe("GameStarted", OnGameStarted); + + // Example: Subscribe to an event with one parameter (int score) + _eventManager.Subscribe("ScoreChanged", OnScoreChanged); + + // Example: Subscribe to an event with two parameters (string playerName, int level) + _eventManager.Subscribe("PlayerLevelUp", OnPlayerLevelUp); + } + + // Event handlers + private void OnGameStarted() + { + GD.Print("Game has started!"); + } + + private void OnScoreChanged(int newScore) + { + GD.Print($"Score changed to: {newScore}"); + } + + private void OnPlayerLevelUp(string playerName, int newLevel) + { + GD.Print($"{playerName} leveled up to level {newLevel}!"); + } + + // Example of raising events from code + public void SomeGameAction() + { + // Raise an event with no parameters + _eventManager.Raise("GameStarted"); + + // Raise an event with one parameter + _eventManager.Raise("ScoreChanged", 100); + + // Raise an event with two parameters + _eventManager.Raise("PlayerLevelUp", "Player1", 5); + } + + public override void _ExitTree() + { + // Always unsubscribe when node is removed + UnsubscribeFromEvents(); + } + + private void UnsubscribeFromEvents() + { + if (_eventManager != null) + { + _eventManager.Unsubscribe("GameStarted", OnGameStarted); + _eventManager.Unsubscribe("ScoreChanged", OnScoreChanged); + _eventManager.Unsubscribe("PlayerLevelUp", OnPlayerLevelUp); + } + } +} diff --git a/Scripts/EventExample.cs.uid b/Scripts/EventExample.cs.uid new file mode 100644 index 0000000..4fe43d2 --- /dev/null +++ b/Scripts/EventExample.cs.uid @@ -0,0 +1 @@ +uid://b4fnyaf5ok7hg