sparze
Expert guidance for Sparze ECS apps including systems, queries, components, resources, events, and performance trade-offs.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Expert guidance for Sparze ECS apps including systems, queries, components, resources, events, and performance trade-offs.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | sparze |
| description | Expert guidance for Sparze ECS apps including systems, queries, components, resources, events, and performance trade-offs. |
Expert guidance for building high-performance ECS applications with Sparze.
World: ECS coordinator with compile-time component, resource, event, and group types.
const World = sparze.World(
.{ Position, Velocity, Health }, // Components
.{ DeltaTime, Score }, // Resources
.{ CollisionEvent }, // Events
.{ struct { Position, Velocity } }, // Groups
);
Entity: 32-bit handle [version:16 | index:16]. index selects dense slot; version invalidates stale handles. Use .index, .version, or getIndex() / getVersion(). Create via Entity.init(), serialize with toInt() / fromInt(u32).
Components: Data attached to entities. Tag components (empty structs) use 1 bit per entity.
Resources: Global singletons injected via Resource(T) / ResourceMut(T). Can implement init() / deinit(), or opt out with pub const auto_init = false (manual initialization required). POD resources are zero-initialized for compatibility.
Events: 1-frame delayed, double-buffered communication. Events written in frame N are read in frame N+1.
Docs: @docs/ARCHITECTURE.md, @docs/ENTITY_LIFECYCLE.md
System functions use injected parameters and must use commands: anytype for world mutation. Return void or !void.
fn mySystem(
allocator: std.mem.Allocator,
movement: Group(struct { Position, Velocity }),
health: SingleQuery(Health),
delta: Resource(DeltaTime),
score: ResourceMut(Score),
reader: EventReader(CollisionEvent),
writer: EventWriter(DamageEvent),
commands: anytype,
) !void {
// Implementation
}
Immediate (returns now):
commands.createEntity()try commands.createEntityWith(.{ Position{...}, Velocity{...} })commands.setResource(T, value) / commands.getResource(T) / commands.getResourcePtrMut(T)try commands.initResources(.{ ... })try commands.serializeToFile(path) / try commands.deserializeFromFile(path)Deferred (applied at world.endFrame()):
try commands.addComponent(e, T, value) / try commands.removeComponent(e, T)try commands.addTag(e, T) / try commands.removeTag(e, T)try commands.destroyEntity(e)Why deferred: avoids invalidating iterators or shifting dense arrays mid-iteration.
Docs: @docs/SYSTEM_PATTERNS.md
Decision guide:
fn healthSystem(query: SingleQuery(Health)) !void {
for (query.entities, query.components) |entity, *health| {
health.hp = @max(0, health.hp);
}
}
fn combatSystem(query: Query(struct { Position, Health, ?Shield })) !void {
for (query.entities) |entity| {
if (query.filter(entity)) {
const pos = query.getComponent(entity, Position);
const health = query.getComponentMut(entity, Health);
const shield = query.getOptional(entity, Shield);
_ = pos; _ = health; _ = shield;
}
}
}
const MovementGroup = struct { Position, Velocity };
const World = sparze.World(.{ Position, Velocity }, .{}, .{}, .{ MovementGroup });
fn movementSystem(group: Group(MovementGroup)) !void {
const positions = group.getMutArrayOf(Position);
const velocities = group.getArrayOf(Velocity);
for (positions, velocities) |*pos, vel| {
pos.x += vel.x;
pos.y += vel.y;
}
}
Free(Component): use in groups that do not own a component. Access via group.getComponent(entity, T) instead of array access.
fn enemySystem(query: TagQuery(struct { Enemy, ?Boss, Exclude(Dead) })) !void {
for (query.entities) |entity| {
if (query.filter(entity)) {
_ = entity;
}
}
}
Docs: @docs/QUERY_PATTERNS.md
Principles:
Frame lifecycle:
world.beginFrame();
try world.runSystem(inputSystem);
try world.runSystem(physicsSystem);
try world.runSystem(renderSystem);
try world.endFrame();
Critical: Always call endFrame() to flush deferred commands.
Initialization options:
init() / deinit() for auto-lifecyclepub const auto_init = false for manual setupSafety helpers:
isResourceInitialized(T)tryGetResource(T)initResources(.{ ... }) for bulk initFastest to slowest:
getMutArrayOf)getComponent)Best practices:
World.validateGroups()Storage notes:
getSparseSetPtrMut(T).reserve(capacity)Docs: @docs/PERFORMANCE.md, @docs/STORAGE_INTERNALS.md
| Task | API |
|---|---|
| Create entity | commands.createEntity() |
| Add component | try commands.addComponent(e, T, value) |
| Query single | SingleQuery(Health) |
| Query multi | Query(struct { Position, Velocity }) |
| Fastest iteration | Group(struct { Position, Velocity }) |
| Optional component | Query(struct { Position, ?Sprite }) |
| Exclude entities | Query(struct { Enemy, Exclude(Dead) }) |
| Read resource | Resource(DeltaTime) |
| Write resource | ResourceMut(Score) |
| Read events | EventReader(CollisionEvent) |
| Write events | EventWriter(DamageEvent) |
| Tag iteration | SingleTag(Enemy) |