mirror of
https://github.com/Ukendio/jecs.git
synced 2025-04-24 17:10:03 +00:00
5.8 KiB
5.8 KiB
Migrating from Matter to jecs
This guide is intended to help developers migrate from the Matter ECS library to jecs.
Key Differences
Architectural Differences
- Storage Implementation: jecs uses an archetype-based storage system (SoA - Structure of Arrays). Matter uses a simpler component-based storage approach.
- Performance: jecs is designed with a focus on performance, particularly for large-scale systems with hundreds of thousands of entities.
- Relationship Model: jecs treats entity relationships as first-class citizens. Matter doesn't have built-in relationship features.
- Memory Usage: jecs typically uses less memory for the same number of entities and components due to its optimized storage structure.
API Differences
World Creation and Management
Matter:
local Matter = require("Matter")
local world = Matter.World.new()
jecs:
local jecs = require("jecs")
local world = jecs.World.new()
Component Definition
Matter:
local Position = Matter.component("Position")
local Velocity = Matter.component("Velocity")
jecs:
local Position = world:component()
local Velocity = world:component()
Entity Creation
Matter:
local entity = world:spawn(
Position({x = 0, y = 0}),
Velocity({x = 10, y = 5})
)
jecs:
local entity = world:entity()
world:set(entity, Position, {x = 0, y = 0})
world:set(entity, Velocity, {x = 10, y = 5})
Queries
Matter:
for id, position, velocity in world:query(Position, Velocity) do
-- Update position based on velocity
position.x = position.x + velocity.x * dt
position.y = position.y + velocity.y * dt
end
jecs:
for entity, position, velocity in world:query(Position, Velocity) do
-- Update position based on velocity
position.x = position.x + velocity.x * dt
position.y = position.y + velocity.y * dt
end
System Definition
Matter:
local function movementSystem(world)
for id, position, velocity in world:query(Position, Velocity) do
position.x = position.x + velocity.x * dt
position.y = position.y + velocity.y * dt
end
end
jecs:
local function movementSystem(world, dt)
for entity, position, velocity in world:query(Position, Velocity) do
position.x = position.x + velocity.x * dt
position.y = position.y + velocity.y * dt
end
end
Entity Removal
Matter:
world:despawn(entity)
jecs:
world:delete(entity)
Component Removal
Matter:
world:remove(entity, Position)
jecs:
world:remove(entity, Position)
jecs-Specific Features
Relationships
jecs has built-in support for entity relationships:
local ChildOf = world:component()
local Name = world:component()
local parent = world:entity()
world:set(parent, Name, "Parent")
local child = world:entity()
world:add(child, jecs.pair(ChildOf, parent))
world:set(child, Name, "Child")
-- Query for all children of parent
for e in world:query(jecs.pair(ChildOf, parent)) do
local name = world:get(e, Name)
print(name, "is a child of Parent")
end
Wildcards
jecs supports wildcard queries for relationships:
-- Query for all parent-child relationships
for entity, target in world:query(jecs.pair(ChildOf, jecs.Wildcard)) do
print(world:get(entity, Name), "is a child of", world:get(target, Name))
end
-- Alternative using the shorter 'w' alias
for entity, target in world:query(jecs.pair(ChildOf, jecs.w)) do
print(world:get(entity, Name), "is a child of", world:get(target, Name))
end
Observer Hooks
jecs provides component lifecycle hooks:
world:set(Position, jecs.OnAdd, function(entity)
print("Position added to entity", entity)
end)
world:set(Position, jecs.OnRemove, function(entity)
print("Position removed from entity", entity)
end)
world:set(Position, jecs.OnSet, function(entity, value)
print("Position set on entity", entity, "with value", value)
end)
Automatic Cleanup with OnDelete and OnDeleteTarget
jecs offers automated cleanup of related entities:
-- When a parent is deleted, all its children will be deleted too
world:add(ChildOf, jecs.pair(jecs.OnDeleteTarget, jecs.Delete))
-- When Health component is deleted, remove the entity's Shield component
world:add(Health, jecs.pair(jecs.OnDelete, jecs.Remove))
world:add(Shield, jecs.pair(jecs.OnDelete, jecs.Remove))
Performance Considerations
When migrating from Matter to jecs, consider these performance tips:
- Batch Entity Operations: Group entity operations when possible to minimize archetype transitions.
- Use Cached Queries: For frequently used queries, create cached versions.
- Consider Component Layout: Components frequently queried together should be defined together.
- Use Tags When Appropriate: For components with no data, use tags instead of empty tables.
- Be Aware of Archetype Transitions: Adding/removing components causes archetype transitions, which have performance implications for large-scale operations.
Migration Strategy
- Start with World Creation: Replace Matter's world creation with jecs.
- Migrate Component Definitions: Update component definitions to use jecs's approach.
- Update Entity Creation: Modify entity spawning code to use jecs's entity and set methods.
- Adapt Queries: Update queries, noting that iteration patterns are similar.
- Implement Relationships: Take advantage of jecs's relationship features where applicable.
- Add Observer Hooks: Implement lifecycle hooks to replace custom event handling in Matter.
- Optimize: Refine your implementation using jecs-specific features for better performance.
By following this guide, you should be able to migrate your Matter ECS application to jecs while taking advantage of jecs's enhanced performance and features.