bevy_enum_event
General-purpose enum to Bevy event conversion macro.
Overview
bevy_enum_event provides derive macros that automatically generate Bevy event types from enum variants. For each variant in your enum, it creates a corresponding event struct organized in a snake_case module. Supports unit variants, tuple variants, and named field variants.
Starting with Bevy 0.17, there are two types of events:
Event: Global events that are not associated with any specific entityEntityEvent: Events that target a specific entity and can trigger entity-specific observers
This crate provides corresponding derive macros for both:
#[derive(EnumEvent)]- GeneratesEventtypes#[derive(EnumEntityEvent)]- GeneratesEntityEventtypes
Bevy Compatibility
| Bevy | bevy_enum_event |
|---|---|
| 0.17 | 0.2 |
| 0.16 | 0.1 |
Features
- Automatic event generation: One macro generates all variant events
- Support for data-carrying variants: Enum variants can contain data (tuple or named fields)
- Snake case module:
PlayerState→player_statemodule - Zero boilerplate: No manual event struct definitions needed
- Type-safe: Each variant gets its own distinct event type
- Generic-friendly: Works with lifetimes, generic parameters, and
whereclauses - Bevy integration: Generated events work seamlessly with Bevy's observer system
- Entity event support: Generate
EntityEventtypes with entity targeting and propagation - Deref support (optional, enabled by default): Automatic
DerefandDerefMutfor ergonomic field access
Installation
[]
= "0.2"
Part 1: EnumEvent - Global Events
Quick Start - Unit Variants
use *;
use EnumEvent;
This automatically generates:
Variants with Data
Enum variants can carry data using tuple or named field syntax:
use *;
use EnumEvent;
This generates:
Using Events with Bevy Observers
use *;
use EnumEvent;
Accessing Event Data
use *;
use EnumEvent;
Deref Feature (enabled by default)
The deref feature provides ergonomic access to event data by automatically implementing Deref and DerefMut:
- Single-field variants: Automatically get deref to the inner value
- Multi-field variants: Mark one field with
#[enum_event(deref)]for deref access - No annotation: Access fields directly by name
Example - Automatic Deref
use *;
use EnumEvent;
Example - Multi-Field with Deref Annotation
use *;
use EnumEvent;
Disabling Deref
If you prefer not to have Deref and DerefMut automatically implemented:
[]
= { = "0.2", = false }
When disabled, access fields directly:
Advanced: Generics & Lifetimes
The macro preserves generic parameters, lifetimes, and where clauses from your enum:
Generated types: generic_event::Borrowed<'a, T>, generic_event::Owned<'a, T>, generic_event::Done<'a, T>.
Unit variants automatically implement Default and get a new() helper when phantom markers are needed. Tuple and named variants with phantom markers also receive new(...) helpers that accept only the original fields.
Part 2: EnumEntityEvent - Entity-Targeted Events
EntityEvent types target specific entities and can trigger entity-specific observers, enabling fine-grained control over event handling.
Important Requirements
Before diving into examples, note these requirements for EnumEntityEvent:
- Named fields only: All variants must use struct-style
{ field: Type }syntax - Entity field required: Each variant must have either:
- A field named
entity: Entity, OR - A field marked with
#[enum_event(target)]
- A field named
- Triggering: Use
commands.trigger(event)orworld.trigger(event)
Basic EntityEvent Usage
use *;
use EnumEntityEvent;
// Global observer - runs for ALL player damage events
// Entity-specific observer - only runs for events targeting this specific entity
Custom Target Field
By default, EnumEntityEvent looks for a field named entity. You can use a different field with #[enum_event(target)]:
use *;
use EnumEntityEvent;
// This event will trigger observers on the attacker entity
Event Propagation
Event propagation allows events to "bubble up" through entity hierarchies, similar to DOM event propagation in web browsers.
Basic Propagation
Enable propagation with #[enum_event(propagate)]:
use *;
use EnumEntityEvent;
// Default propagation uses the ChildOf relationship
Auto Propagation
For events that should always bubble up without manual control:
Custom Propagation Relationships
Specify a custom relationship type for propagation instead of the default ChildOf:
use *;
use EnumEntityEvent;
;
;
// Propagate along CustomRelationship instead of ChildOf
// Note: Use absolute paths (::) or make the relationship public
Important: Custom relationship types must be pub or referenced via absolute paths (::bevy::, crate::, etc.) because they're accessed from the generated module.
Variant-Level Propagation
Override enum-level propagation settings for specific variants:
// Default for all variants
## Snake Case Conversion
The macro intelligently converts
The generated module exposes generic_event::Borrowed<'a, T>, generic_event::Owned<'a, T>, and
generic_event::Done<'a, T> types with identical bounds.
Unit event structs expose ergonomic constructors so you never have to juggle hidden PhantomData
markers by hand. Every unit variant implements Default, and when a phantom marker is required the
derive also emits a new() helper that seeds it for you. Tuple and named variants that require
phantom markers likewise receive new(...) helpers that accept only the original fields.
Use Cases
- State machines (see bevy_fsm)
- Game state transitions
- Entity lifecycle events
- Animation states
- Input modes
- Any enum-based event system
- Network message events
- Input/Output events with associated data
AI Disclaimer
- Refactoring and documentation supported by Claude Code
- Minor editing supported by ChatGPT Codex
- The process and final releases are thoroughly supervised and checked by the author
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.