You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This crate is awesome! It's solving exactly the problem that was driving me nuts when trying to represent intents & actions in a turn-based roguelike prototype I'm using to play around with bevy.
An architecture for representing behaviors emerged pretty directly from the way bevy_eventlistener is set up. I'm sharing it here because 1. maybe it's useful for someone 2. maybe it's generic enough to be supported with a bit of extra library code, either here or in a separate crate.
Goals
Minimal boilerplate and duplication
Intents (i.e. "I want to move here", "I want to skip this turn") should be EntityEvents
Behaviors triggered by these intents should be listener systems, and fully encapsulate all the logic
What it looks like
Prototype: abesto/treeffect@8bc7403 (this is a commit that moves from intents being components, and behaviors being regular systems)
Intent
Nothing interesting here, just so that the rest makes sense.
EntityEvents are registered in a plugin with some macro magic for further DRY:
// short for "event listener plugins"macro_rules! elp {($app:ident, $($events:ident),+ $(,)?) => {
$($app.add_plugins(EventListenerPlugin::<$events>::default());)+
};}pubstructEventsPlugin;implPluginforEventsPlugin{fnbuild(&self,app:&mutApp){
app.add_event::<took_turn::TookTurn>();elp!(app,MovementIntent,AttackIntent,WaitIntent);}}
On reflection, elp should probably be replaced with an App extention trait with .add_intents or something more generic.
Side-track: that might actually be a meaningful separate feature request. app.add_entity_event::<WaitIntent>() is sensible. It still wouldn't be DRY enough, so I'd probably still have a similar wrapper macro.
Behavior machinery
A trait so we can hang logic somewhere, implemented for tuples (spoiler: think about bundles):
I'm ignoring event propagation here, because I'm not using entity hierarchies. I'm probably picking the wrong one out of (Listener, Target) somewhere.
behavior! is a simple macro that, if I was an adult, I'd implement as a derive macro. It's coupled very tightly to my naming conventions, unsure how feasible this would be as library code. It generates code like this:
You can pretty much figure this out from the rest, but for the record:
typeBehaviors = ActorBehavior;// Could add more specific behaviors here#[derive(Bundle)]pubstructPlayerBundle{
...
pubbehaviors:Behaviors,}implDefaultforPlayerBundle{fndefault() -> Self{PlayerBundle{
...
behaviors:Behaviors::behavior(),}}}
The text was updated successfully, but these errors were encountered:
This crate is awesome! It's solving exactly the problem that was driving me nuts when trying to represent intents & actions in a turn-based roguelike prototype I'm using to play around with
bevy
.An architecture for representing behaviors emerged pretty directly from the way
bevy_eventlistener
is set up. I'm sharing it here because 1. maybe it's useful for someone 2. maybe it's generic enough to be supported with a bit of extra library code, either here or in a separate crate.Goals
EntityEvent
sWhat it looks like
Prototype: abesto/treeffect@8bc7403 (this is a commit that moves from intents being components, and behaviors being regular systems)
Intent
Nothing interesting here, just so that the rest makes sense.
EntityEvents
are registered in a plugin with some macro magic for further DRY:On reflection,
elp
should probably be replaced with anApp
extention trait with.add_intents
or something more generic.Side-track: that might actually be a meaningful separate feature request.
app.add_entity_event::<WaitIntent>()
is sensible. It still wouldn't be DRY enough, so I'd probably still have a similar wrapper macro.Behavior machinery
A trait so we can hang logic somewhere, implemented for tuples (spoiler: think about bundles):
Simple Behavior
I'm ignoring event propagation here, because I'm not using entity hierarchies. I'm probably picking the wrong one out of (Listener, Target) somewhere.
behavior!
is a simple macro that, if I was an adult, I'd implement as a derive macro. It's coupled very tightly to my naming conventions, unsure how feasible this would be as library code. It generates code like this:Composed Behavior
I guess you could call this a behavior bundle.
Used in a Bundle
You can pretty much figure this out from the rest, but for the record:
The text was updated successfully, but these errors were encountered: