API
Ark's public API.
World
The World is the central data storage for Entities, Components and Resources.
Ark.World — TypeWorld{CS<:Tuple,CT<:Tuple,N}The World is the central ECS storage.
Ark.World — MethodWorld(
comp_types::Type...;
initial_capacity::Int=128,
allow_mutable::Bool=false,
)Creates a new, empty World for the given component types.
Arguments
comp_types: The component types used by the world.initial_capacity: Initial capacity for entities in each archetype and in the entity index.allow_mutable: Allows mutable components. Use with care, as all mutable objects are heap-allocated in Julia.
Example
world = World(Position, Velocity)
;Ark.reset! — Functionreset!(world::World)Removes all entities and resources from the world, and un-registers all observers. Does NOT free reserved memory or remove archetypes.
Can be used to run systematic simulations without the need to re-allocate memory for each run. Accelerates re-populating the world by a factor of 2-3.
Ark.is_locked — Functionis_locked(world::World)::BoolReturns whether the world is currently locked for modifications.
Ark.StructArrayStorage — TypeStructArrayStorageMarks component types for using StructArray-like storage in world constructor.
In StructArray storages, mutable components are not allowed.
See also VectorStorage.
Example
world = World(
Position => StructArrayStorage,
Velocity => StructArrayStorage,
)Ark.VectorStorage — TypeVectorStorageMarks component types for using Vector storage in world constructor. As this is the default storage mode if the storage type is not specified.
See also StructArrayStorage.
Example
world = World(
Position => VectorStorage,
Velocity => VectorStorage,
)Entities
Entities are the "game objects" or "model entities". An entity if just an ID with a generation, but Components can be attached to an entity.
Ark.Entity — TypeEntityEntity identifier.
Ark.zero_entity — Constantconst zero_entity::EntityThe reserved zero Entity value.
Ark.new_entity! — Functionnew_entity!(world::World, values::Tuple)::EntityCreates a new Entity with the given component values. Types are inferred from the values.
Ark.new_entities! — Functionnew_entities!(world::World, n::Int, defaults::Tuple; iterate::Bool=false)::Union{Batch,Nothing}Creates the given number of Entity, initialized with default values. Component types are inferred from the provided default values.
If iterate is true, a Batch iterator over the newly created entities is returned that can be used for initialization.
Arguments
world::World: TheWorldinstance to use.n::Int: The number of entities to create.defaults::Tuple: A tuple of default values for initialization, like(Position(0, 0), Velocity(1, 1)).iterate::Bool: Whether to return a batch for individual entity initialization.
new_entities!(world::World, n::Int, comp_types::Tuple{Vararg{Val}})::BatchCreates the given number of Entity.
Returns a Batch iterator over the newly created entities that should be used to initialize components. Note that components are not initialized/undef unless set in the iterator!
For a more convenient tuple syntax, the macro @new_entities! is provided.
Arguments
world::World: TheWorldinstance to use.n::Int: The number of entities to create.comp_types::Tuple: Component types for the new entities, likeVal.((Position, Velocity)).
Ark.@new_entities! — Macro@new_entities!(world::World, n::Int, comp_types::Tuple{Vararg{Val}})::BatchCreates the given number of Entity.
Returns a Batch iterator over the newly created entities that should be used to initialize components. Note that components are not initialized/undef unless set in the iterator.
Macro version of new_entities! for ergonomic construction of component mappers.
Arguments
world::World: TheWorldinstance to use.n::Int: The number of entities to create.comp_types::Tuple: Component types for the new entities, like(Position, Velocity).
Ark.remove_entity! — FunctionArk.copy_entity! — Functioncopy_entity!(
world::World,
entity::Entity;
add::Tuple=(),
remove::Tuple=(),
mode=Val(:copy),
)Copies an Entity, optionally adding and/or removing components.
Mutable and non-isbits components are shallow copied by default. This can be changed with the mode argument.
For a more convenient tuple syntax, the macro @copy_entity! is provided.
Arguments
world: TheWorldinstance to query.entity::Entity: The entity to copy.add::Tuple: Components to add, likewith=(Health(0),).remove::Tuple: Component types to remove, likeVal.((Position,Velocity)).mode::Tuple: Copy mode for mutable and non-isbits components, likeVal(:copy). Modes are :ref, :copy, :deepcopy.
Example
entity1 = copy_entity!(world, entity)
entity2 = copy_entity!(world, entity;
add=(Health(100),),
remove=Val.((Position, Velocity)),
)Ark.@copy_entity! — Macro@copy_entity!(
world::World,
entity::Entity;
add::Tuple=(),
remove::Tuple=(),
mode=:copy,
)Copies an Entity, optionally adding and/or removing components.
Mutable and non-isbits components are shallow copied by default. This can be changed with the mode argument.
Macro version of copy_entity! for more ergonomic component type tuples.
Arguments
world: TheWorldinstance to query.entity::Entity: The entity to copy.add::Tuple: Components to add, likewith=(Health(0),).remove::Tuple: Component types to remove, like(Position,Velocity).mode::Tuple: Copy mode for mutable and non-isbits components, like:copy. Modes are :ref, :copy, :deepcopy.
Example
entity1 = @copy_entity!(world, entity)
entity2 = @copy_entity!(world, entity;
add=(Health(100),),
remove=(Position, Velocity),
)Ark.is_alive — Functionis_alive(world::World, entity::Entity)::BoolReturns whether an Entity is alive.
Ark.is_zero — Functionis_zero(entity::Entity)::BoolReturns whether an Entity is the zero entity.
Components
Components contain the data associated with Entities
Ark.get_components — Functionget_components(world::World, entity::Entity, comp_types::Tuple)Get the given components for an Entity. Components are returned in a tuple.
For a more convenient tuple syntax, the macro @get_components is provided.
Example
pos, vel = get_components(world, entity, Val.((Position, Velocity)))Ark.@get_components — Macro@get_components(world::World, entity::Entity, comp_types::Tuple)Get the given components for an Entity. Components are returned in a tuple.
Macro version of get_components for more ergonomic component type tuples.
Example
pos, vel = @get_components(world, entity, (Position, Velocity))Ark.has_components — Functionhas_components(world::World, entity::Entity, comp_types::Tuple)::BoolReturns whether an Entity has all given components.
For a more convenient tuple syntax, the macro @has_components is provided.
Example
has = has_components(world, entity, Val.((Position, Velocity)))Ark.@has_components — Macro@has_components(world::World, entity::Entity, comp_types::Tuple)::BoolReturns whether an Entity has all given components.
Macro version of has_components for more ergonomic component type tuples.
Example
has = @has_components(world, entity, (Position, Velocity))Ark.set_components! — Functionset_components!(world::World, entity::Entity, values::Tuple)Sets the given component values for an Entity. Types are inferred from the values. The entity must already have all these components.
Ark.add_components! — Functionadd_components!(world::World, entity::Entity, values::Tuple)Adds the given component values to an Entity. Types are inferred from the values.
Ark.remove_components! — Functionremove_components!(world::World, entity::Entity, comp_types::Tuple)Removes the given components from an Entity.
For a more convenient tuple syntax, the macro @remove_components! is provided.
Example
remove_components!(world, entity, Val.((Position, Velocity)))Ark.@remove_components! — Macro@remove_components!(world::World, entity::Entity, comp_types::Tuple)Removes the given components from an Entity.
Macro version of remove_components! for ergonomic construction of component mappers.
Example
@remove_components!(world, entity, (Position, Velocity))Ark.exchange_components! — Functionexchange_components!(world::World{CS,CT,N}, entity::Entity; add::Tuple, remove::Tuple)Adds and removes components on an Entity. Types are inferred from the add values.
For a more convenient tuple syntax, the macro @exchange_components! is provided.
Example
exchange_components!(world, entity;
add=(Health(100),),
remove=Val.((Position, Velocity)),
)Ark.@exchange_components! — Macro@exchange_components!(world::World, entity::Entity; add::Tuple, remove::Tuple)Removes the given components from an Entity.
Macro version of exchange_components! for more ergonomic component type tuples.
Example
@exchange_components!(world, entity;
add=(Health(100),),
remove=(Position, Velocity),
)Queries
Queries are used to filter and process Entities with a certain set of Components.
Ark.Query — TypeQueryA query for components.
Ark.Query — MethodQuery(
world::World,
comp_types::Tuple;
with::Tuple=(),
without::Tuple=(),
optional::Tuple=(),
exclusive::Val=Val(false)
)Creates a query.
For a more convenient tuple syntax, the macro @Query is provided.
Arguments
world: TheWorldinstance to query.comp_types::Tuple: Components the query filters for and provides access to. Must be aValtuple likeVal.((Position, Velocity)).with::Tuple: Additional components the entities must have. Passed aswith=Val.((Health,)).without::Tuple: Components the entities must not have. Passed aswithout=Val.((Altitude,)).optional::Tuple: Additional components that are optional in the query. Passed asoptional=Val.((Velocity,)).exclusive::Val{Bool}: Makes the query exclusive in base andwithcomponents, can't be combined withwithout.
Example
for (entities, positions, velocities) in Query(world, Val.((Position, Velocity)))
for i in eachindex(entities)
pos = positions[i]
vel = velocities[i]
positions[i] = Position(pos.x + vel.dx, pos.y + vel.dy)
end
endArk.@Query — Macro@Query(
world::World,
comp_types::Tuple;
with::Tuple=(),
without::Tuple=(),
optional::Tuple=(),
exclusive::Bool=false
)Creates a query.
Macro version of Query that allows ergonomic construction of queries using simulated keyword arguments.
Arguments
world: TheWorldinstance to query.comp_types::Tuple: Components the query filters for and provides access to. Must be a literal tuple like(Position, Velocity).with::Tuple: Additional components the entities must have. Passed aswith=(Health,).without::Tuple: Components the entities must not have. Passed aswithout=(Altitude,).optional::Tuple: Additional components that are optional in the query. Passed asoptional=(Velocity,).exclusive::Bool: Makes the query exclusive in base andwithcomponents, can't be combined withwithout.
Example
for (entities, positions, velocities) in @Query(world, (Position, Velocity))
for i in eachindex(entities)
pos = positions[i]
vel = velocities[i]
positions[i] = Position(pos.x + vel.dx, pos.y + vel.dy)
end
endArk.close! — Methodclose!(q::Query)Closes the query and unlocks the world.
Must be called if a query is not fully iterated.
Ark.Entities — TypeEntitiesArchetype column for entities. Can be iterated and indexed like a Vector.
Used in query iteration.
Ark.@unpack — Macro@unpack ...Unpacks the tuple returned from a Query during iteration into field vectors. Field vectors are particularly useful for StructArrayStorages, but can also be used with VectorStorages, although those are currently not equally efficient in broadcasted operations.
Example
for columns in Query(world, Val.((Position, Velocity)))
@unpack entities, (x, y), (dx, dy) = columns
@inbounds x .+= dx
@inbounds y .+= dy
endArk.unpack — Functionunpack(a::StructArrayView)Unpacks the components (i.e. field vectors) of a StructArrayStorage column returned from a Query. See also @unpack.
unpack(a::FieldsView)Unpacks the components (i.e. field vectors) of a VectorStorage column returned from a Query. See also @unpack.
Resources
Resources are singleton-like data structures that appear only once in a World and are not associated to an Entity.
Ark.get_resource — Functionget_resource(world::World, res_type::Type{T})::TGet the resource of type T from the world.
Ark.has_resource — Functionhas_resource(world::World, res_type::Type{T})::BoolCheck if a resource of type T is in the world.
Ark.add_resource! — Functionadd_resource!(world::World, res::T)::TAdd the given resource to the world. Returns the newly added resource.
Ark.set_resource! — Functionset_resource!(world::World, res::T)::TOverwrites an existing resource in the world. Returns the newly overwritten resource.
Ark.remove_resource! — Functionremove_resource!(world::World, res_type::Type{T})::TRemove the resource of type T from the world. Returns the removed resource.
Batch
An iterator over entities that were created or modified using batch operations. Behaves like a Query and can be used for component initialization.
Ark.Batch — TypeBatchA batch iterator. This is returned from batch operations and serves for initializing newly added components.
Ark.close! — Methodclose!(b::Batch)Closes the batch iterator and unlocks the world.
Must be called if a batch is not fully iterated.
Event system
The event system allows user code to react on structural changes like entity creation and removal and component addition and removal. Further, custom events can be defined and emitted.
Ark.EventType — TypeEventTypeType for built-in and custom events. See EventRegistry for creating custom event types.
Built-in event types
OnCreateEntity: Event emitted when a new entity is created.OnRemoveEntity: Event emitted when an entity is removed from the World.OnAddComponents: Event emitted when components are added to an entity.OnRemoveComponents: Event emitted when components are removed from an entity.
Ark.EventRegistry — TypeEventRegistryServes for creating custom event types.
Ark.EventRegistry — MethodEventRegistry()Creates a new EventRegistry.
Ark.new_event_type! — Functionnew_event_type!(reg::EventRegistry, symbol::Symbol)Creates a new custom EventType. Custom event types are best stored in global constants.
The symbol is only used for printing.
Ark.Observer — TypeObserverObserver for reacting on built-in and custom events.
See @observe! for details. See EventType for built-in, and EventRegistry for custom event types.
Ark.@observe! — Macro@observe!(
fn::Function,
world::World,
event::EventType,
components::Tuple=();
with::Tuple=(),
without::Tuple=(),
exclusive::Val=Val(false),
register::Bool=true,
)Creates an Observer and (optionally, default) registers it.
Macro version of observe! that allows ergonomic construction of observers using simulated keyword arguments.
See EventType for built-in, and EventRegistry for custom event types.
Arguments
fn::Function: A callback function to execute when a matching event is received. Can be used via adoblock.world::World: The World to observe.event::EventType: The EventType to observe.components::Tuple=(): The component types to observe. Must be empty forOnCreateEntityandOnRemoveEntity.with::Tuple=(): Components the entity must have.without::Tuple=(): Components the entity must not have.exclusive::Bool=false: Makes the observer exclusive for entities that have exactly the components given bewith.register::Bool=true: Whether the observer is registered immediately. Alternatively, register later with observe!
Example
@observe!(world, OnAddComponents, (Position, Velocity); with=(Altitude,)) do entity
println(entity)
endArk.observe! — Functionobserve!(
fn::Function,
world::World,
event::EventType,
components::Tuple=();
with::Tuple=(),
without::Tuple=(),
exclusive::Bool=false,
register::Bool=true,
)Creates an Observer and (optionally, default) registers it.
For a more convenient tuple syntax, the macro @observe! is provided.
See EventType for built-in, and EventRegistry for custom event types.
Arguments
fn::Function: A callback function to execute when a matching event is received. Can be used via adoblock.world::World: The World to observe.event::EventType: The EventType to observe.components::Tuple=(): The component types to observe. Must be empty forOnCreateEntityandOnRemoveEntity.with::Tuple=(): Components the entity must have.without::Tuple=(): Components the entity must not have.exclusive::Bool=false: Makes the observer exclusive for entities that have exactly the components given bewith.register::Bool=true: Whether the observer is registered immediately. Alternatively, register later with observe!
Example
observe!(world, OnAddComponents, Val.((Position, Velocity)); with=Val.((Altitude,))) do entity
println(entity)
endobserve!(world::World, observer::Observer; unregister::Bool=false)Registers or un-registers the given Observer. Note that observers created with @observe! are automatically registered by default.
Ark.@emit_event! — Macro@emit_event!(world::World, event::EventType, entity::Entity, components::Tuple=())Emits a custom event for the given EventType, Entity and optional components. The entity must have the given components. The entity can be the reserved zero_entity.
Macro version of emit_event! that allows more ergonomic event construction.
Ark.emit_event! — Functionemit_event!(world::World, event::EventType, entity::Entity, components::Tuple=())Emits a custom event for the given EventType, Entity and optional components. The entity must have the given components. The entity can be the reserved zero_entity.
For a more convenient tuple syntax, the macro @emit_event! is provided.
Index
Ark.zero_entityArk.BatchArk.EntitiesArk.EntityArk.EventRegistryArk.EventRegistryArk.EventTypeArk.ObserverArk.QueryArk.QueryArk.StructArrayStorageArk.VectorStorageArk.WorldArk.WorldArk.add_components!Ark.add_resource!Ark.close!Ark.close!Ark.copy_entity!Ark.emit_event!Ark.exchange_components!Ark.get_componentsArk.get_resourceArk.has_componentsArk.has_resourceArk.is_aliveArk.is_lockedArk.is_zeroArk.new_entities!Ark.new_entity!Ark.new_event_type!Ark.observe!Ark.remove_components!Ark.remove_entity!Ark.remove_resource!Ark.reset!Ark.set_components!Ark.set_resource!Ark.unpackArk.@QueryArk.@copy_entity!Ark.@emit_event!Ark.@exchange_components!Ark.@get_componentsArk.@has_componentsArk.@new_entities!Ark.@observe!Ark.@remove_components!Ark.@unpack