一键导入
flecs-dylib-modules
Hot-reloadable Flecs modules as Rust dylibs. Covers module architecture, component vs system modules, and inter-module dependencies.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Hot-reloadable Flecs modules as Rust dylibs. Covers module architecture, component vs system modules, and inter-module dependencies.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | flecs-dylib-modules |
| description | Hot-reloadable Flecs modules as Rust dylibs. Covers module architecture, component vs system modules, and inter-module dependencies. |
Hot-reloadable Flecs modules as Rust dylibs.
Use this skill when you need to:
In Flecs, it's idiomatic to separate:
This separation enables:
crates/module/
├── time-components/ # WorldTime, TpsTracker (components only)
├── time-systems/ # Systems that tick WorldTime (imports time-components)
├── network-components/ # Connection, PacketBuffer, etc.
├── network-systems/ # Ingress/egress systems
└── play/ # Game systems (imports time-components, network-components)
// crates/module/time-components/src/lib.rs
use flecs_ecs::prelude::*;
#[derive(Component, Debug)]
pub struct WorldTime {
pub world_age: i64,
pub time_of_day: i64,
}
#[derive(Component)]
pub struct TimeComponentsModule;
impl Module for TimeComponentsModule {
fn module(world: &World) {
world.module::<TimeComponentsModule>("time::components");
// Register component and singleton
world.component::<WorldTime>().add_trait::<flecs::Singleton>();
world.set(WorldTime::default());
// NO SYSTEMS HERE - just components
}
}
// crates/module/time-systems/src/lib.rs
use flecs_ecs::prelude::*;
use module_time_components::{TimeComponentsModule, WorldTime};
#[derive(Component)]
pub struct TimeSystemsModule;
impl Module for TimeSystemsModule {
fn module(world: &World) {
world.module::<TimeSystemsModule>("time::systems");
// Import component module (ensures components exist)
world.import::<TimeComponentsModule>();
// Define systems
world.system_named::<&mut WorldTime>("TickWorldTime")
.each(|time| {
time.world_age += 1;
time.time_of_day = (time.time_of_day + 1) % 24000;
});
}
}
System modules depend on component modules via Cargo:
# crates/module/time-systems/Cargo.toml
[lib]
crate-type = ["dylib"]
[dependencies]
flecs_ecs.workspace = true
module-time-components = { path = "../time-components" }
Each module dylib exports:
#[unsafe(no_mangle)]
pub fn module_load(world: &World) {
world.import::<MyModule>();
}
#[unsafe(no_mangle)]
pub fn module_unload(world: &World) {
if let Some(e) = world.try_lookup("::my_module") {
e.destruct();
}
}
#[unsafe(no_mangle)]
pub fn module_name() -> &'static str { "my_module" }
#[unsafe(no_mangle)]
pub fn module_version() -> u32 { 1 }
// WRONG - just registers component
world.component::<WorldTime>();
// RIGHT - register as singleton AND set value
world.component::<WorldTime>().add_trait::<flecs::Singleton>();
world.set(WorldTime::default());
world.import::<Module>() is idempotent - safe to call multiple times:
impl Module for PlayModule {
fn module(world: &World) {
world.import::<TimeComponentsModule>(); // Ensures components exist
world.import::<NetworkComponentsModule>();
// Now safe to query WorldTime, PacketBuffer, etc.
}
}
All modules must link to the SAME shared flecs libraries:
libflecs.dylib (C library)libflecs_ecs.dylib (Rust wrapper)Symlink dylibs to modules/ directory:
ln -s target/debug/libmodule_time_components.dylib modules/
ln -s target/debug/libmodule_time_systems.dylib modules/
Rebuild updates dylib, file watcher triggers hot-reload.
With component/system separation:
time-systems → systems restart with existing component datatime-components → resets singletons (use sparingly)