SuperAPI AI 工具集

bevy-genre-roguelike

编程与开发

查看项目

更新于 10-16 06:08

技能介绍

用途

Bevy Roguelike 是一个“类型路由”(thin router)技能,面向 Bevy 0.20 的 Roguelike 游戏开发。它本身不承担具体领域实现,而是把随机种子、房间生成、永久死亡标记等需求路由到对应的 Bevy 子技能。资料说明:当需要处理 run seeds、房间生成和 permadeath 标记时加载本技能。

主要能力与 ECS 结构

资料规定了几条 ECS 组织原则:

  • Component 以纯数据形式保存该类型的每实体标记,本文件不命名新的引擎类型。
  • Resource 通过 bevy-data-resources 保存整局范围的计数器(分数、波次索引、种子)。
  • 系统在 Update 或来自 bevy-master 的固定时间步读取这些组件;当后续系统必须看到前一个系统的结果时,用 .chain() 排序。
  • 玩法模式切换走 bevy-state-machines,不要自行发明类型插件。

路由目标包括:bevy-procedural-generation(种子与生成)、bevy-turn-system(回合制时的回合顺序)、bevy-inventory-system(局内战利品)、bevy-rpg-stats(局内属性)。

使用方式(资料中的代码示例)

依赖声明为 bevy = "0.20" 与 rand = "0.9"。

随机种子是一个资源,房间是实体,StdRng 在系统内部构建,使种子保留在资源上:

use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};

#[derive(Resource)]
struct RunSeed(u64);

#[derive(Component)]
struct Room {
    x: i32,
    y: i32,
}

fn carve(mut commands: Commands, seed: Res<RunSeed>) {
    let mut rng = StdRng::seed_from_u64(seed.0);
    for _ in 0..8 {
        commands.spawn(Room {
            x: rng.random_range(-6..6),
            y: rng.random_range(-6..6),
        });
    }
}

fn install_run(app: &mut App) {
    app.insert_resource(RunSeed(0x5EED))
        .add_systems(Startup, carve);
}

永久死亡是角色上的标记加一个整局资源,由一个系统同时写入两者:

#[derive(Component)]
struct Actor {
    hp: i32,
}

#[derive(Resource)]
struct RunOver(bool);

fn permadeath(mut actors: Query<&mut Actor>, mut over: ResMut<RunOver>) {
    for mut actor in &mut actors {
        if actor.hp > 0 {
            continue;
        }
        actor.hp = 0;
        over.0 = true;
    }
}

回合能量累积在资源上,行动消耗它;两个系统都写 TurnClock,因此需要链式排序:

#[derive(Resource)]
struct TurnClock {
    energy: f32,
}

fn charge(time: Res<Time>, mut clock: ResMut<TurnClock>) {
    clock.energy = (clock.energy + time.delta_secs()).min(1.0);
}

#[derive(Component)]
struct Actor {
    hp: i32,
}

fn spend(mut clock: ResMut<TurnClock>, mut actors: Query<&mut Actor>) {
    if clock.energy < 1.0 {
        return;
    }
    clock.energy = 0.0;
    for mut actor in &mut actors {
        if actor.hp > 0 {
            actor.hp -= 1;
        }
    }
}

fn install_turns(app: &mut App) {
    app.insert_resource(TurnClock { energy: 0.0 })
        .add_systems(Update, (charge, spend).chain());
}

地面战利品是实体,角色可按网格距离拾取:

#[derive(Component)]
struct Loot {
    value: u32,
}

#[derive(Component)]
struct GridPos {
    x: i32,
    y: i32,
}

#[derive(Component)]
struct Actor;

#[derive(Resource)]
struct RunSeed(u64);

fn pickup(
    mut commands: Commands,
    actors: Query<&GridPos, With<Actor>>,
    loot: Query<(Entity, &GridPos, &Loot)>,
    mut wallet: ResMut<RunSeed>,
) {
    for actor in &actors {
        for (entity, pos, item) in &loot {
            if actor.x == pos.x && actor.y == pos.y {
                wallet.0 = wallet.0.wrapping_add(u64::from(item.value));
                commands.entity(entity).despawn();
            }
        }
    }
}

资料特别说明:pickup 中的 RunSeed 只是占位计数器,使示例保持在单一资源内;金币钱包应属于 bevy-economy-system。permadeath 与 spend 都写 Actor,两者同时运行时需要链式排序。

适用场景

适用于 Bevy 0.20 的 Roguelike 项目,尤其是需要可复现的随机种子、房间生成、永久死亡、回合制能量与网格拾取等基础结构时。噪声与更大的地图路由到 bevy-procedural-generation;物品栏堆叠路由到 bevy-inventory-system。

限制与禁止事项

资料明确列出若干 NEVER 规则:

  • 不要在文档 URL 中固定 /0.20.0/,链接应保持在 latest,0.20 目标只在正文中说明一次。
  • 不要从两个无序系统可变查询同一组件,因为调度默认并行运行系统,除非用 .chain() 排序。
  • 不要在此发明物理、导航、网络或 XR crate,本技能只命名有文档的 Bevy crate 与模块。
  • 不要每帧用新种子重建 StdRng,run seed 应保留在 RunSeed 上以保证房间布局可复现。
  • 不要让 permadeath 与 spend 在未 .chain() 的情况下同时写 Actor。
  • 不发明类型 API,Bevy 代码保持惯用 ECS 并只使用有文档的 Bevy API。

关于 Bevy 版本、依赖版本与官方文档链接,资料给出:库固定在 bevy-master 上保持 0.20.0,官方页面保持在无版本号的 latest 分支。官方文档涵盖 Assets、Examples、ECS(Component、systems、Query、Startup、Update、.chain())、Plugins(Plugin、DefaultPlugins、MinimalPlugins、add_plugins)。前置技能为 bevy-master 与 bevy-ecs-composition;互补技能包括 godot-genre-roguelike、bevy-procedural-generation、bevy-turn-system、bevy-inventory-system、bevy-rpg-stats。本路由不拥有第二套实现,下游消费者为 None。