Demo
Team Context
YetAnotherEvent was developed for Skén, our horror game project, where puzzle chains and story-driven gameplay reactions needed to change frequently during development and playtesting. As team lead and gameplay systems developer, I built the system to support our team’s workflow: gameplay programmers and designers needed a way to connect switches, doors, lights, audio cues, and story events without creating fragile direct references between every actor. The goal was to make event-driven puzzle setup faster to iterate on, easier to understand in the editor, and easier to debug when chains became more complex.
Responsibilities
Get Reusable Event Framework
Target is Responsibility
Designed a reusable Unreal Engine event framework for Skén to make puzzle chains and story-driven gameplay reactions easier to prototype, update, and maintain without hard references between every sender and receiver.
Flexible Global Event Workflow
Built a flexible global event workflow where GameplayTags define events and channels, payloads carry event data, and listener gates control when reactions are allowed to fire.
Designer & Programmer Usability
Created designer-friendly broadcaster/listener components for editor-based setup, while also adding UEVENT code generation tooling to expose typed C++ events to Blueprint and reduce repeated delegate/wrapper boilerplate.
Get Debugging & Event Visibility
Target is Responsibility
Added debugging and visualization support so complex puzzle chains were easier to inspect, including where events were sent, which listeners reacted, and why a reaction did or did not trigger.
System Overview
As Skén’s puzzle chains became more complex, event flow needed to be visible and understandable instead of hidden across Blueprint references and actor logic. I created the system overview diagrams to show the plugin from multiple angles: the high-level architecture, the designer setup workflow, and the runtime event flow through C++ and Blueprint. The goal was not to show every class, but to make the system’s structure and workflow easy to understand at a glance.
High-Level Architecture
Designer Workflow
Runtime Event Flow
Before / After Coupling
System Breakdown
Local vs. Global Events
Broadcasting Events
Listening & Gates
Payloads, Channels & Debugging
Problem
Not every gameplay event should use the same communication style.
Some systems need small, strongly typed C++ events. Other systems, especially puzzle chains and level interactions, need decoupled communication where multiple actors can react without hard references.
Using only global messages would make simple C++ communication heavier than necessary. Using only Unreal delegates would still require repeated wrapper code when events need Blueprint exposure.
Solution
I split the system into two event layers.
Local typed events use TEvent for direct C++ communication with explicit event handles and weak UObject-aware listener support.
Global GameplayTag events are used for Skén puzzle and level workflows, where senders broadcast intent and receivers decide whether they care.
For typed events that need Blueprint access, UEVENT code generation creates the Unreal-facing wrapper code automatically.
Implementation
Local C++ Event
LightControllerComponent.cpp

Programmer Facing
Strongly typed, zero-overhead, direct references.
Global GameplayTag Event
UE Editor

Designer Facing
Loose coupling via GameplayTags, Channels, and Payloads.
Result
A compact typed C++ event declaration can be bridged into Blueprint-facing wrapper code through UEVENT generation.
Designer Workflow
A typical designer-facing setup follows this flow:
Define Event Identity
Create or select a global event tag, with an optional channel for a specific puzzle group or gameplay context.
Configure Broadcaster
Add a broadcaster component to the sender actor and assign the event tag and channel.
Add Event Data
Optionally create and assign a payload so the event can carry structured data.
Configure Listener
Add a listener component to the receiver actor and assign the matching event tag and channel.
Set Reaction Logic
Configure the Blueprint reaction or listener gate that should run when the event is received.
Use Payload Context
Optionally read the payload data inside the reaction to drive more specific behavior.
Event flow needed debugging support
Global events reduce hard references, but they can become hard to trace without tools showing what fired and who reacted.
Challenge
Codegen needed reliable testing
The generator had to be stable before production use, because codegen issues could cause problems later in development.
Challenge
Component listening limitation
Global events could be broadcast from Blueprint and components, but listening currently relies on just components, so widgets are not supported yet.
Challenge
Codegen convenience vs header cleanliness
Generated wrapper code had to be inserted into headers for Unreal reflection, so I used custom regions to keep it separated.
Tradeoff
Flexibility vs clarity
Tags, channels, payloads, and gates made setup flexible, but required naming conventions and debugging tools to stay understandable.
Tradeoff
Flexibility vs performance
The custom event layer added safety and usability features, but was slower than raw Unreal delegates in local performance tests.
Tradeoff
Impact
Made Skén puzzle chains easier to update after playtest feedback by replacing one-off direct actor references with reusable broadcaster/listener setups.
Improved iteration speed for the gameplay programmer by centralizing event configuration through tags, channels, payloads, and listener gates instead of spreading puzzle logic across multiple hardwired Blueprints.
Made event relationships easier to inspect than default Blueprint actor references by exposing event setup through a consistent workflow and supporting debugging/visualization tools.
Reduced repeated Blueprint delegate boilerplate by generating Blueprint-facing wrappers from typed C++ event declarations.
Reduced repeated Blueprint delegate boilerplate by generating Blueprint-facing wrappers from typed C++ event declarations.
Made multi-step puzzle conditions faster to configure by using event gates instead of custom per-instance Blueprint boolean logic.
What I Learned
A reusable gameplay system is only useful if the workflow around it is clear enough for the team to use without constant programmer support.
Global event systems need naming conventions early. Without clear GameplayTag rules, flexible event communication can become difficult to reason about.
Debugging tools are not optional for designer-facing systems. Silent failures, missing tags, or mismatched payloads can waste a lot of time if the system does not explain what happened.
Tool workflows need their own form of playtesting. Watching how teammates use the system reveals unclear setup steps that are easy to miss as the developer who built it.
What I Would Improve
Build a clearer event debugger showing fired tags, senders, listeners, channels, payload types, and gate results.
Add a visual graph view that shows event connections between broadcasters and listeners, with search and filtering for larger puzzle chains.
Add a play mode developer view that shows nearby event-driven puzzle objects and lets developers trigger or skip specific event conditions through debug hotkeys, making longer puzzle chains faster to test.
Add stronger payload validation so event tags can define or warn about expected payload types.
Add async Blueprint listener nodes so widgets and other non-component contexts can react to global events without needing listener components.
Replace header-injected generated code with a cleaner workflow if Unreal reflection allows it in the future.
Add sample scenes and documentation showing recommended naming conventions, puzzle setup patterns, and debugging workflows.
Explore per-instance method binding from the Details panel so designers can choose specific receiver methods without writing custom Blueprint glue for every reaction.
prove networking support so selected events can be routed over the network through explicit 'UEVENT' flags, such as server-only, client-only, or multicast/networked event broadcasts.
