#stats #bevy #serialization

bevy_stat_query

bevy引擎的过度设计RPG状态查询系统

4个版本

0.0.4 2024年4月15日
0.0.3 2024年4月3日
0.0.2 2024年3月6日
0.0.1 2024年3月6日

#726 in 游戏开发

MIT/Apache

125KB
3K SLoC

bevy-stat-query

bevy引擎的过度设计RPG状态查询系统。

合格状态

我们将每个状态描述为一个Qualifier和一个StatStat是一个具体的名词状态,如StrengthMagic等。Qualifier是基于标志的形容词,描述了该Stat可以应用于什么。

例如在FireMagicDamage中,Fire|Magic是修饰符,DamageStat

这意味着如果效果提高了Fire|DamageMagic|Damage或仅仅是Damage,该效果将应用于状态,但Sword|DamageFire|Range的效果将不会应用于状态。

修饰符

Qualifier与效果相关联,并提供了上述的all_of。此外,还提供了any_of来模拟条件效果,如Elemental|Damage,这意味着Fire or Water Damage而不是Fire and Water Damage

每个Qualifier只能有一个any_of组,这是当前的一个限制。

示例

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匹配我们角色上所有符合我们查询条件的Qualifiers

QualifierQuery::Aggregate收集所有符合查询的修饰符。

例如,假设我们正在寻找(Fire|Burn|Magic, Damage)

  • (), Damage)符合条件。
  • (Fire, Damage)符合条件。
  • (Fire|Magic, Damage)符合条件。
  • (Fire|Burn|Magic, Damage)符合条件。
  • (Elemental, Damage) 允许。
  • (Fire|Sword, Damage) 不允许。
  • (Fire|Burn|Magic, Defense) 不允许。

QualifierQuery::Exact 允许我们拒绝更通用的限定符。

例如,为了模拟以下语句

Add 50% of the character's magic damage to physical damage.

查询 (Magic, Damage),其中包含 ((), Damage),并添加到 (Physical, Damage) 将导致重复。

因此查询应该是

QualifierQuery::Exact {
    any_of: None,
    all_of: Magic,
}
  • 你的意思是什么?我的 DarkFireFire 完全不同,应该是独立的。

创建一个新的限定符 DarkFire 而不是 Dark|Fire

入门指南

将标记组件 StatEntity 添加到 Entity。如果您需要缓存,还可以添加 StatCache。但是,当状态改变时,您需要手动清除缓存。

  • 实现 IntrinsicStream 使实体的组件可查询。
  • 实现 ExternalStream 使子实体的组件可查询。

例如,我们可以将 BaseStatMap 添加到 Entity 作为基础统计数据,如果我们将其包含在 querier! 宏的 intrinsic 部分中。

查询器

StatQuerier 是查询统计信息的 SystemParam,手动定义它相当困难,因此推荐的方法是使用 querier! 宏定义一个 类型。此外,我们还可以使用带有 World 访问的 StatExtension 来实现类似的功能。

示例

querier!(pub UnitStatQuerier {
    qualifier: MyQualifier,
    intrinsic: {
        Allegiance,
        Position
    },
    external: {
        Weapon,
        Ability,
        Effect,
        Potion,
    }
});

无序统计流

bevy_stat_query 使用无序操作来构建统计数据。这包括 addmultiplyminmaxor。这确保在查询统计数据时不需要显式的排序。

每个统计数据都有其 StatValue 组件形式,例如 (12 * 4).min(99).max(0),以及其评估形式,例如 48。您可以通过实现自己的 StatValue 来实现自定义行为。StatOperation 存储可以写入 StatValue 的单个操作。

统计数据关系

我们可以使用组件形式或评估形式创建不同统计数据之间的关系。StatStream 允许查询其他统计数据或其他实体。由于统计数据操作是无序的,无法解决依赖循环。如果检测到循环,将抛出错误。

实体关系

IntrinsicStream 可以用来提供双实体关系,例如 distanceallegiance。这可以用来模拟基于范围的影响。

您可能会在实现这些时发现 StatOnce(types::StatOnce) 有用。

注意

  • StatQuerier 需要读取统计数据系统中的所有组件,因此当我们将其作为参数时不能进行任何修改。在这种情况下,使用系统管道或某种类型的延迟命令队列进行修改可能更合适。

  • 该软件包在底层大量使用动态分发,因此不是完全反射兼容的。支持的序列化方法是通过 bevy-serde-project 软件包,有关更多信息,请查看该软件包。

  • 如果 StatValue::Bounds 是浮点数,它们的默认值可能是 -infinf,这在 json 中不是有效值。这意味着 serde_json 将它们序列化为 null 并在反序列化时失败。如果使用 FullStatMap,请选择不同的格式。

版本

bevy bevy-stat-query
0.13 最新版

许可证

根据以下任一项许可

任选其一。

贡献

除非您明确说明,否则您根据 Apache-2.0 许可证定义的任何有意提交以包含在作品中的贡献,将根据上述方式双许可,不附加任何额外的条款或条件。

依赖关系

~17–56MB
~886K SLoC