Crate bevy_stat_query
source ·Expand description
A pedantic RPG stat system for the bevy engine.
§Qualified Stats
We describe each stat as a Qualifier
and a Stat
.
Stat
is a concrete stat noun like Strength
, Magic
, etc.
Qualifier
is a flags based adjective that describes
what this Stat
can be applied to.
For example in FireMagicDamage
, Fire|Magic
is the qualifier,
Damage
is the Stat
.
What this means if an effect boosts Fire|Damage
, Magic|Damage
,
or simply just Damage
, the effect will be applied to the stat,
but an effect on Sword|Damage
or Fire|Range
won’t be applied to the stat.
§Qualifier
Qualifier
is tied to effects, and provides the aforementioned all_of
.
In addition any_of
is provided for modelling conditional effects like
Elemental|Damage
, which means Fire or Water Damage
instead of Fire and Water Damage
.
Each Qualifier
can only have one group of any_of
which is a limitation currently.
§Examples
let fire = Qualifier::all_of(Flag::Fire);
let fire_magic = Qualifier::all_of(Flag::Fire|Flag::Magic);
let elemental = Qualifier::any_of(Fire|Water|Air|Earth);
let elemental_magic = Qualifier::any_of(Fire|Water|Air|Earth)
.and_all_of(Magic);
§QualifierQuery
QualifierQuery
matches all Qualifiers
on our character that
qualifies as the query we are looking for.
QualifierQuery::Aggregate
collects all qualifiers that matches the query.
For example, suppose we are looking for (Fire|Burn|Magic, Damage)
:
((), Damage)
qualifies.(Fire, Damage)
qualifies.(Fire|Magic, Damage)
qualifies.(Fire|Burn|Magic, Damage)
qualifies.(Elemental, Damage)
qualifies.(Fire|Sword, Damage)
does not qualify.(Fire|Burn|Magic, Defense)
does not qualify.
QualifierQuery::Exact
allows us to deny
more generalized qualifiers.
For example, in order to model a statement like so:
Add 50% of the character's magic damage to physical damage.
Querying (Magic, Damage)
, which contains ((), Damage)
,
and adding to (Physical, Damage)
would cause a duplication.
Therefore the query should be:
QualifierQuery::Exact {
any_of: None,
all_of: Magic,
}
- What do you mean? My
DarkFire
andFire
and totally different things and should be independent.
Create a new qualifier DarkFire
instead of Dark
|Fire
.
§Getting Started
Add marker component StatEntity
to an Entity
.
If you need caching, add a StatCache
as well.
You need to manually clear the cache when the state is changed, however.
- Implement
IntrinsicStream
to make components on the entity queryable. - Implement
ExternalStream
to make components on child entities queryable.
For example we can add BaseStatMap
to the Entity
as base stats, if we include
it in the intrinsic
section of the querier!
macro.
§Querier
StatQuerier
is the SystemParam
to query stats, it is quite difficult to
define one manually so the recommended way is to define a type
with the
querier!
macro. Additionally we can also use the StatExtension
with World
access
for similar functionalities.
§Example
querier!(pub UnitStatQuerier {
qualifier: MyQualifier,
intrinsic: {
Allegiance,
Position
},
external: {
Weapon,
Ability,
Effect,
Potion,
}
});
§Unordered StatStream
bevy_stat_query
uses unordered operations to build up stats. This includes
add
, multiply
, min
, max
and or
. This ensures no explicit ordering is
ever needed when querying for stats.
Each stat has its components form StatValue
, e.g. (12 * 4).min(99).max(0)
,
and its evaluated form, e.g. 48
. You can implement your own StatValue
to achieve custom behaviors. StatOperation
stores a single operation
that can be written to a StatValue
.
§Stat Relation
We can create relations between different
stats using either their components form or their evaluated form.
StatStream
s are allowed to query other stats or other entities.
Since stat operations are unordered, dependency cycles cannot be resolved.
If a cycle is detected, an error will be thrown.
§Entity Relation
IntrinsicStream
can be used to provide bi-entity relationship
like distance
or allegiance
. This can be used to model range based effects.
You may find StatOnce
useful in implementing these.
§Note
-
StatQuerier
requires read access to all components in stat system so we cannot mutate anything while having it as a parameter. Using system piping or some kind of deferred command queue for mutations might be advisable in this case. -
The crate heavily utilizes dynamic dispatch under the hood, and is therefore not fully reflect compatible. The supported serialization method is through the
bevy_serde_project
crate, Check out that crate for more information. -
if
StatValue::Bounds
is a float, their default values are likely-inf
andinf
, which are not valid values injson
. This meansserde_json
will serialize them asnull
and fail when deserialized. IfFullStatMap
is used (optional btw), choose a different format.
Re-exports§
pub use types::StatValue;
Modules§
Macros§
- Construct a
StatQuerier
type alias from arguments. The result can be used as aSystemParam
.
Structs§
- A map containing associated output value of stats.
!Send
resource for running stat queries on theWorld
- Represents a fractional number.
- A map containing associated
StatValue
of stats. - Data side qualifier for a stat.
- Erased querier with a typed interface.
- This component acts as a cache to stats.
- The core marker component. Stat querying is only allowed on entities marked as
StatEntity
. - A map containing associated
StatOperation
s of stats. - A
SystemParam
that allows the user to query stats byEntity
. - Optional, enable queriers on the
World
. - Opaque type that contains a stat and a mutable value.
- An unqualified view of a stat map.
Enums§
Traits§
- Component and context based stat streams on children of
StatEntity
. - A type that can be treated as flags.
- Trait for a floating point number or a
Fraction
. - Trait for an integer.
- An item that can be used to generate stats when directly added to
StatEntity
. - A flags like
Qualifier
for stats, normally bitflags or a set. - Alias for
Clone + Debug + Send + Sync + 'static
. - Alias for
Clone + Debug + Send + Sync + 'static
. - Implement this on your types to qualify them as a
Stat
. - A generalized object safe stat relation.
- A generalized object safe stat relation that can be serialized.
- A generalized object safe stat relation.