Documentation ¶
Overview ¶
Package ecs contains Arche's core API.
See the top level module github.com/mlange-42/arche for an overview.
Index ¶
- Constants
- func GetResource[T any](w *World) *T
- type Batch
- func (b *Batch) NewEntities(count int, comps ...ID)
- func (b *Batch) NewEntitiesQuery(count int, comps ...ID) Query
- func (b *Batch) NewEntitiesWith(count int, comps ...Component)
- func (b *Batch) NewEntitiesWithQuery(count int, comps ...Component) Query
- func (b *Batch) RemoveEntities(filter Filter) int
- type Cache
- type CachedFilter
- type Component
- type Config
- type Entity
- type EntityEvent
- type Filter
- type ID
- type Mask
- func (b *Mask) Contains(other Mask) bool
- func (b *Mask) ContainsAny(other Mask) bool
- func (b Mask) Exclusive() MaskFilter
- func (b *Mask) Get(bit ID) bool
- func (b *Mask) IsZero() bool
- func (b Mask) Matches(bits Mask) bool
- func (b *Mask) Not() Mask
- func (b *Mask) Reset()
- func (b *Mask) Set(bit ID, value bool)
- func (b *Mask) TotalBitsSet() int
- func (b Mask) Without(comps ...ID) MaskFilter
- type MaskFilter
- type Query
- type ResID
- type Resources
- type World
- func (w *World) Add(entity Entity, comps ...ID)
- func (w *World) Alive(entity Entity) bool
- func (w *World) Assign(entity Entity, comps ...Component)
- func (w *World) Batch() *Batch
- func (w *World) Cache() *Cache
- func (w *World) Exchange(entity Entity, add []ID, rem []ID)
- func (w *World) Get(entity Entity, comp ID) unsafe.Pointer
- func (w *World) Has(entity Entity, comp ID) bool
- func (w *World) IsLocked() bool
- func (w *World) Mask(entity Entity) Mask
- func (w *World) NewEntity(comps ...ID) Entity
- func (w *World) NewEntityWith(comps ...Component) Entity
- func (w *World) Query(filter Filter) Query
- func (w *World) Remove(entity Entity, comps ...ID)
- func (w *World) RemoveEntity(entity Entity)
- func (w *World) Reset()
- func (w *World) Resources() *Resources
- func (w *World) Set(entity Entity, id ID, comp interface{}) unsafe.Pointer
- func (w *World) SetListener(listener func(e *EntityEvent))
- func (w *World) Stats() *stats.WorldStats
Examples ¶
- AddResource
- Batch
- Batch.NewEntities
- Batch.NewEntitiesQuery
- Batch.NewEntitiesWith
- Batch.NewEntitiesWithQuery
- Batch.RemoveEntities
- Cache
- CachedFilter
- ComponentID
- Config
- Entity
- Entity.IsZero
- EntityEvent
- GetResource
- Mask
- Mask.Exclusive
- Mask.Without
- MaskFilter
- Query
- Query.Close
- Query.Count
- ResourceID
- Resources
- TypeID
- World
- World.Add
- World.Assign
- World.Batch
- World.Cache
- World.Exchange
- World.Get
- World.Has
- World.NewEntity
- World.NewEntityWith
- World.Query
- World.Remove
- World.RemoveEntity
- World.Reset
- World.Resources
- World.Set
- World.SetListener
- World.Stats
Constants ¶
const MaskTotalBits = 128
MaskTotalBits is the size of Mask in bits.
It is the maximum number of component types that may exist in any World.
Variables ¶
This section is empty.
Functions ¶
func GetResource ¶ added in v0.5.0
GetResource returns a pointer to the given resource type in world.
Returns nil if there is no such resource.
Uses reflection. For more efficient access, see World.Resources, and github.com/mlange-42/arche/generic.Resource.Get for a generic variant. These methods are more than 20 times faster than the GetResource function.
Example ¶
world := NewWorld() myRes := Position{100, 100} AddResource(&world, &myRes) res := GetResource[Position](&world) fmt.Println(res)
Output: &{100 100}
Types ¶
type Batch ¶ added in v0.6.0
type Batch struct {
// contains filtered or unexported fields
}
Batch is a helper to perform batched operations on the world.
Create using World.Batch.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) world.Batch().NewEntities(10_000, posID, velID)
Output:
func (*Batch) NewEntities ¶ added in v0.6.0
NewEntities creates the given number of entities Entity. The given component types are added to all entities.
See also Batch.NewEntitiesQuery.
Panics when called on a locked world. Do not use during Query iteration!
See also the generic variants under github.com/mlange-42/arche/generic.Map1, etc.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) world.Batch().NewEntities(10_000, posID, velID)
Output:
func (*Batch) NewEntitiesQuery ¶ added in v0.6.0
NewEntitiesQuery creates the given number of entities Entity. The given component types are added to all entities.
Returns a Query for iterating the created entities. The Query must be closed if it is not used! Listener notification is delayed until the query is closed of fully iterated. See also Batch.NewEntities.
Panics when called on a locked world. Do not use during Query iteration!
See also the generic variants under github.com/mlange-42/arche/generic.Map1, etc.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) query := world.Batch().NewEntitiesQuery(10_000, posID, velID) for query.Next() { // initialize components of the newly created entities }
Output:
func (*Batch) NewEntitiesWith ¶ added in v0.6.0
NewEntitiesWith creates the given number of entities Entity. The given component values are assigned to all entity.
See also Batch.NewEntitiesWithQuery.
Panics when called on a locked world. Do not use during Query iteration!
See also the generic variants under github.com/mlange-42/arche/generic.Map1, etc.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) components := []Component{ {ID: posID, Comp: &Position{X: 0, Y: 0}}, {ID: velID, Comp: &Velocity{X: 10, Y: 2}}, } world.Batch().NewEntitiesWith(10_000, components...)
Output:
func (*Batch) NewEntitiesWithQuery ¶ added in v0.6.0
NewEntitiesWithQuery creates the given number of entities Entity. The given component values are assigned to all entity.
Returns a Query for iterating the created entities. The Query must be closed if it is not used! Listener notification is delayed until the query is closed of fully iterated. See also Batch.NewEntitiesWith.
Panics when called on a locked world. Do not use during Query iteration!
See also the generic variants under github.com/mlange-42/arche/generic.Map1, etc.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) components := []Component{ {ID: posID, Comp: &Position{X: 0, Y: 0}}, {ID: velID, Comp: &Velocity{X: 10, Y: 2}}, } query := world.Batch().NewEntitiesWithQuery(10_000, components...) for query.Next() { // initialize components of the newly created entities }
Output:
func (*Batch) RemoveEntities ¶ added in v0.6.0
RemoveEntities removes and recycles all entities matching a filter.
Returns the number of removed entities.
Panics when called on a locked world. Do not use during Query iteration!
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) world.Batch().NewEntities(10_000, posID, velID) filter := All(posID, velID).Exclusive() world.Batch().RemoveEntities(&filter)
Output:
type Cache ¶ added in v0.6.0
type Cache struct {
// contains filtered or unexported fields
}
Cache provides Filter caching to speed up queries.
Access it using World.Cache.
For registered filters, the relevant archetypes are tracked internally, so that there are no mask checks required during iteration. This is particularly helpful to avoid query iteration slowdown by a very high number of archetypes. If the number of archetypes exceeds approx. 50-100, uncached filters experience a slowdown. The relative slowdown increases with lower numbers of entities queried (below a few thousand). Cached filters avoid this slowdown.
Further, cached filters should be used for complex queries built with package github.com/mlange-42/arche/filter.
The overhead of tracking cached filters internally is very low, as updates are required only when new archetypes are created. The number of cached filters is limited to MaskTotalBits.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) filter := All(posID) cached := world.Cache().Register(filter) query := world.Query(&cached) for query.Next() { // ... }
Output:
func (*Cache) Register ¶ added in v0.6.0
func (c *Cache) Register(f Filter) CachedFilter
Register a Filter.
Use the returned CachedFilter to construct queries:
filter := All(posID, velID) cached := world.Cache().Register(&filter) query := world.Query(&cached)
func (*Cache) Unregister ¶ added in v0.6.0
func (c *Cache) Unregister(f *CachedFilter) Filter
Unregister a filter.
Returns the original filter.
type CachedFilter ¶ added in v0.6.0
type CachedFilter struct {
// contains filtered or unexported fields
}
CachedFilter is a filter that is cached by the world.
Create it using Cache.Register.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) filter := All(posID) cached := world.Cache().Register(filter) query := world.Query(&cached) for query.Next() { // ... }
Output:
func (*CachedFilter) Matches ¶ added in v0.6.0
func (f *CachedFilter) Matches(bits Mask) bool
Matches matches a filter against a mask.
type Component ¶ added in v0.2.0
type Component struct { ID ID // Component ID. Comp interface{} // The component, as a pointer to a struct. }
Component is a component ID/pointer pair.
It is a helper for World.Assign and World.NewEntityWith. It is not related to how components are implemented in Arche.
type Config ¶ added in v0.1.3
type Config struct { // Capacity increment for archetypes and the entity index. // The default value is 128. CapacityIncrement int }
Config provides configuration for an ECS World.
Example ¶
config := NewConfig().WithCapacityIncrement(1024) world := NewWorld(config) world.NewEntity()
Output:
func NewConfig ¶ added in v0.1.3
func NewConfig() Config
NewConfig creates a new default World configuration.
func (Config) WithCapacityIncrement ¶ added in v0.1.3
WithCapacityIncrement return a new Config with CapacityIncrement set. Use with method chaining.
type Entity ¶
type Entity struct {
// contains filtered or unexported fields
}
Entity identifier. Holds an entity ID and it's generation for recycling.
Entities are only created via the World, using World.NewEntity or World.NewEntityWith. Batch creation of entities is possible via World.Batch.
Entities are intended to be stored and passed around via copy, not via pointers.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) e1 := world.NewEntity() e2 := world.NewEntity(posID, velID) fmt.Println(e1.IsZero(), e2.IsZero())
Output: false false
type EntityEvent ¶ added in v0.4.0
type EntityEvent struct { Entity Entity // The entity that was changed. OldMask, NewMask Mask // The old and new component masks. Added, Removed, Current []ID // Components added, removed, and after the change. DO NOT MODIFY! AddedRemoved int // Whether the entity itself was added (> 0), removed (< 0), or only changed (= 0). }
EntityEvent contains information about component changes to an Entity.
To receive change events, register a function func(e *EntityEvent) with World.SetListener.
Events notified are entity creation, removal and changes to the component composition. Events are emitted immediately after the change is applied.
Except for removed entities, events are always fired when the World is in an unlocked state. Events for removed entities are fired right before removal of the entity, to allow for inspection of it's components. Therefore, the World is in a locked state during entity removal events.
Events for batch-creation of entities using World.Batch are fired after all entities are created. For batch methods that return a Query, events are fired after the Query is closed (or fully iterated). This allows the World to be in an unlocked state, and notifies after potential entity initialization.
Note that the event pointer received by the listener function should not be stored, as the instance behind the pointer might be reused for further notifications.
Example ¶
world := NewWorld() listener := func(evt *EntityEvent) { fmt.Println(evt) } world.SetListener(listener) world.NewEntity()
Output: &{{1 0} {0 0} {0 0} [] [] [] 1}
func (*EntityEvent) EntityAdded ¶ added in v0.4.0
func (e *EntityEvent) EntityAdded() bool
EntityAdded reports whether the entity was newly added.
func (*EntityEvent) EntityRemoved ¶ added in v0.4.0
func (e *EntityEvent) EntityRemoved() bool
EntityRemoved reports whether the entity was removed.
type Filter ¶ added in v0.4.0
type Filter interface { // Matches the filter against a bitmask, i.e. a component composition. Matches(bits Mask) bool }
Filter is the interface for logic filters. Filters are required to query entities using World.Query.
See Mask and MaskFilter for basic filters. For type-safe generics queries, see package github.com/mlange-42/arche/generic. For advanced filtering, see package github.com/mlange-42/arche/filter.
type ID ¶
type ID = uint8
ID is the component identifier type.
func ComponentID ¶
ComponentID returns the ID for a component type via generics. Registers the type if it is not already registered.
The number of unique component types per World is limited to MaskTotalBits.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) world.NewEntity(posID)
Output:
func TypeID ¶ added in v0.4.0
TypeID returns the ID for a component type. Registers the type if it is not already registered.
The number of unique component types per World is limited to MaskTotalBits.
Example ¶
world := NewWorld() posID := TypeID(&world, reflect.TypeOf(Position{})) world.NewEntity(posID)
Output:
type Mask ¶
Mask is a 128 bit bitmask. It is also a Filter for including certain components (see All and Mask.Without).
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) filter := All(posID, velID) query := world.Query(filter) for query.Next() { // ... }
Output:
func All ¶ added in v0.4.0
All creates a new Mask from a list of IDs. Matches al entities that have the respective components, and potentially further components.
See also Mask.Without and Mask.Exclusive
If any ID is bigger or equal MaskTotalBits, it'll not be added to the mask.
func (*Mask) ContainsAny ¶ added in v0.4.0
ContainsAny reports if any bit of other mask is in this mask.
func (Mask) Exclusive ¶ added in v0.6.0
func (b Mask) Exclusive() MaskFilter
Exclusive creates a MaskFilter which filters for exactly the mask's components. Matches only entities that have exactly the given components, and no other.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) filter := All(posID, velID).Exclusive() query := world.Query(&filter) for query.Next() { // ... }
Output:
func (*Mask) Get ¶
Get reports if bit index defined by ID is true or false.
The return will be always false for bit >= MaskTotalBits.
func (*Mask) Set ¶
Set sets the state of bit index to true or false.
This function has no effect for bit >= MaskTotalBits.
func (*Mask) TotalBitsSet ¶
TotalBitsSet returns how many bits are set in this mask.
func (Mask) Without ¶ added in v0.4.0
func (b Mask) Without(comps ...ID) MaskFilter
Without creates a MaskFilter which filters for including the mask's components, and excludes the components given as arguments.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) filter := All(posID).Without(velID) query := world.Query(&filter) for query.Next() { // ... }
Output:
type MaskFilter ¶ added in v0.4.0
type MaskFilter struct { Include Mask // Components to include. Exclude Mask // Components to exclude. }
MaskFilter is a Filter for including and excluding certain components. See All and Mask.Without.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) filter := All(posID).Without(velID) query := world.Query(&filter) for query.Next() { // ... }
Output:
func (*MaskFilter) Matches ¶ added in v0.4.0
func (f *MaskFilter) Matches(bits Mask) bool
Matches matches a filter against a mask.
type Query ¶
type Query struct {
// contains filtered or unexported fields
}
Query is an iterator to iterate entities, filtered by a Filter.
Create queries through the World using World.Query.
See also the generic alternatives github.com/mlange-42/arche/generic.Query1, github.com/mlange-42/arche/generic.Query2, etc. For advanced filtering, see package github.com/mlange-42/arche/filter.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) filter := All(posID, velID) query := world.Query(filter) for query.Next() { pos := (*Position)(query.Get(posID)) vel := (*Velocity)(query.Get(velID)) pos.X += vel.X pos.Y += vel.Y }
Output:
func (*Query) Close ¶ added in v0.1.2
func (q *Query) Close()
Close closes the Query and unlocks the world.
Automatically called when iteration finishes. Needs to be called only if breaking out of the query iteration.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) world.NewEntity(posID) query := world.Query(All(posID)) cnt := query.Count() fmt.Println(cnt) query.Close()
Output: 1
func (*Query) Count ¶ added in v0.1.3
Count counts the entities matching this query.
Involves a small overhead of iterating through archetypes when called the first time. However, this is still much faster than manual counting via iteration.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) world.NewEntity(posID) query := world.Query(All(posID)) cnt := query.Count() fmt.Println(cnt) query.Close()
Output: 1
func (*Query) Mask ¶ added in v0.4.0
Mask returns the archetype [BitMask] for the Entity at the iterator's current position.
Can be used for fast checks of the entity composition, e.g. using a Filter.
func (*Query) Step ¶ added in v0.4.4
Step advances the query iterator by the given number of entities.
Query.Step(1) is equivalent to Query.Next().
This method, used together with Query.Count, can be useful for the selection of random entities.
type ResID ¶ added in v0.5.0
type ResID = uint8
ResID is the resource identifier type.
func AddResource ¶ added in v0.5.0
AddResource adds a resource to the world. Returns the ID for the added resource.
Panics if there is already such a resource.
Uses reflection. For more efficient access, see [World.AddResource], and github.com/mlange-42/arche/generic.Resource.Add for a generic variant.
The number of resources per World is limited to MaskTotalBits.
Example ¶
world := NewWorld() myRes := Position{100, 100} AddResource(&world, &myRes) res := GetResource[Position](&world) fmt.Println(res)
Output: &{100 100}
func ResourceID ¶ added in v0.5.0
ResourceID returns the ResID for a resource type via generics. Registers the type if it is not already registered.
The number of resources per World is limited to MaskTotalBits.
Example ¶
world := NewWorld() resID := ResourceID[Position](&world) world.Resources().Add(resID, &Position{100, 100})
Output:
type Resources ¶ added in v0.6.0
type Resources struct {
// contains filtered or unexported fields
}
Resources manage a world's resources.
Access it using World.Resources.
Example ¶
world := NewWorld() resID := ResourceID[Position](&world) myRes := Position{100, 100} world.Resources().Add(resID, &myRes) res := (world.Resources().Get(resID)).(*Position) fmt.Println(res) if world.Resources().Has(resID) { world.Resources().Remove(resID) }
Output: &{100 100}
func (*Resources) Add ¶ added in v0.6.0
Add adds a resource to the world. The resource should always be a pointer.
Panics if there is already a resource of the given type.
See also github.com/mlange-42/arche/generic.Resource.Add for a generic variant.
func (*Resources) Get ¶ added in v0.6.0
Get returns a pointer to the resource of the given type.
Returns nil if there is no such resource.
See also github.com/mlange-42/arche/generic.Resource.Get for a generic variant.
func (*Resources) Has ¶ added in v0.6.0
Has returns whether the world has the given resource.
See also github.com/mlange-42/arche/generic.Resource.Has for a generic variant.
func (*Resources) Remove ¶ added in v0.6.0
Remove removes a resource from the world.
Panics if there is no resource of the given type.
See also github.com/mlange-42/arche/generic.Resource.Remove for a generic variant.
type World ¶
type World struct {
// contains filtered or unexported fields
}
World is the central type holding Entity and component data, as well as resources.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) _ = world.NewEntity(posID, velID)
Output:
func NewWorld ¶
NewWorld creates a new World from an optional Config.
Uses the default Config if called without an argument. Accepts zero or one arguments.
func (*World) Add ¶
Add adds components to an Entity.
Panics when called with component that can't be added because they are already present. Panics when called on a locked world or for an already removed entity. Do not use during Query iteration!
Note that calling a method with varargs in Go causes a slice allocation. For maximum performance, pre-allocate a slice of component IDs and pass it using ellipsis:
// fast world.Add(entity, idA, idB, idC) // even faster world.Add(entity, ids...)
See also the generic variants under github.com/mlange-42/arche/generic.Map1, etc.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) e := world.NewEntity() world.Add(e, posID, velID)
Output:
func (*World) Assign ¶ added in v0.2.0
Assign assigns multiple components to an Entity, using pointers for the content.
The components in the `Comp` field of Component must be pointers. The passed pointers are no valid references to the assigned memory!
Panics when called with components that can't be added because they are already present. Panics when called on a locked world or for an already removed entity. Do not use during Query iteration!
See also the generic variants under github.com/mlange-42/arche/generic.Map1, etc.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) e := world.NewEntity() world.Assign(e, Component{ID: posID, Comp: &Position{X: 0, Y: 0}}, Component{ID: velID, Comp: &Velocity{X: 10, Y: 2}}, )
Output:
func (*World) Batch ¶ added in v0.6.0
Batch creates a Batch processing helper.
It provides the functionality to create and remove large numbers of entities in batches, in a more efficient way.
Example ¶
world := NewWorld() world.Batch().NewEntities(10_000)
Output:
func (*World) Cache ¶ added in v0.6.0
Cache returns the Cache of the world, for registering filters.
See Cache for details on filter caching.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) filter := All(posID) cached := world.Cache().Register(filter) query := world.Query(&cached) for query.Next() { // handle entities... }
Output:
func (*World) Exchange ¶ added in v0.2.0
Exchange adds and removes components in one pass.
Panics when called with components that can't be added or removed because they are already present/not present, respectively. Panics when called on a locked world or for an already removed entity. Do not use during Query iteration!
See also the generic variants under github.com/mlange-42/arche/generic.Exchange.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) e := world.NewEntity(posID) world.Exchange(e, []ID{velID}, []ID{posID})
Output:
func (*World) Get ¶
Get returns a pointer th the given component of an Entity.
Returns `nil` if the entity has no such component. Panics when called for an already removed entity.
See also github.com/mlange-42/arche/generic.Map.Get for a generic variant.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) e := world.NewEntity(posID) pos := (*Position)(world.Get(e, posID)) pos.X, pos.Y = 10, 5
Output:
func (*World) Has ¶
Has returns whether an Entity has a given component.
Panics when called for an already removed entity.
See also github.com/mlange-42/arche/generic.Map.Has for a generic variant.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) e := world.NewEntity(posID) if world.Has(e, posID) { world.Remove(e, posID) }
Output:
func (*World) IsLocked ¶ added in v0.1.2
IsLocked returns whether the world is locked by any queries.
func (*World) Mask ¶ added in v0.4.0
Mask returns the archetype [BitMask] for the given Entity.
Can be used for fast checks of the entity composition, e.g. using a Filter.
func (*World) NewEntity ¶
NewEntity returns a new or recycled Entity. The given component types are added to the entity.
Panics when called on a locked world. Do not use during Query iteration!
Note that calling a method with varargs in Go causes a slice allocation. For maximum performance, pre-allocate a slice of component IDs and pass it using ellipsis:
// fast world.NewEntity(idA, idB, idC) // even faster world.NewEntity(ids...)
See also the generic variants under github.com/mlange-42/arche/generic.Map1, etc.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) _ = world.NewEntity(posID, velID)
Output:
func (*World) NewEntityWith ¶ added in v0.4.0
NewEntityWith returns a new or recycled Entity. The given component values are assigned to the entity.
The components in the `Comp` field of Component must be pointers. The passed pointers are no valid references to the assigned memory!
Panics when called on a locked world. Do not use during Query iteration!
See also the generic variants under github.com/mlange-42/arche/generic.Map1, etc.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) _ = world.NewEntityWith( Component{ID: posID, Comp: &Position{X: 0, Y: 0}}, Component{ID: velID, Comp: &Velocity{X: 10, Y: 2}}, )
Output:
func (*World) Query ¶
Query creates a Query iterator.
The ecs core package provides only the filter All for querying the given components. Further, it can be chained with Mask.Without (see the examples) to exclude components.
Locks the world to prevent changes to component compositions. The lock is released automatically when the query finishes iteration, or when Query.Close is called. The number of simultaneous locks (and thus open queries) at a given time is limited to MaskTotalBits.
For type-safe generics queries, see package github.com/mlange-42/arche/generic. For advanced filtering, see package github.com/mlange-42/arche/filter.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) filter := All(posID, velID) query := world.Query(filter) for query.Next() { pos := (*Position)(query.Get(posID)) vel := (*Velocity)(query.Get(velID)) pos.X += vel.X pos.Y += vel.Y }
Output:
func (*World) Remove ¶
Remove removes components from an entity.
Panics when called with components that can't be removed because they are not present. Panics when called on a locked world or for an already removed entity. Do not use during Query iteration!
See also the generic variants under github.com/mlange-42/arche/generic.Map1, etc.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) velID := ComponentID[Velocity](&world) e := world.NewEntity(posID, velID) world.Remove(e, posID, velID)
Output:
func (*World) RemoveEntity ¶ added in v0.4.0
RemoveEntity removes and recycles an Entity.
Panics when called on a locked world or for an already removed entity. Do not use during Query iteration!
Example ¶
world := NewWorld() e := world.NewEntity() world.RemoveEntity(e)
Output:
func (*World) Reset ¶ added in v0.6.0
func (w *World) Reset()
Reset removes all entities and resources from the world.
Does NOT free reserved memory, remove archetypes, clear the registry etc.
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.
Example ¶
world := NewWorld() _ = world.NewEntity() world.Reset()
Output:
func (*World) Resources ¶ added in v0.6.0
Resources of the world.
Resources are component-like data that is not associated to an entity, but unique to the world.
Example ¶
world := NewWorld() resID := ResourceID[Position](&world) myRes := Position{} world.Resources().Add(resID, &myRes) res := (world.Resources().Get(resID)).(*Position) res.X, res.Y = 10, 5
Output:
func (*World) Set ¶ added in v0.3.0
Set overwrites a component for an Entity, using a given pointer for the content.
The passed component must be a pointer. Returns a pointer to the assigned memory. The passed in pointer is not a valid reference to that memory!
Panics when called on a locked world or for an already removed entity. Do not use during Query iteration!
Panics if the entity does not have a component of that type.
See also github.com/mlange-42/arche/generic.Map.Set for a generic variant.
Example ¶
world := NewWorld() posID := ComponentID[Position](&world) e := world.NewEntity(posID) world.Set(e, posID, &Position{X: 0, Y: 0})
Output:
func (*World) SetListener ¶ added in v0.4.0
func (w *World) SetListener(listener func(e *EntityEvent))
SetListener sets a listener callback func(e EntityEvent) for the world. The listener is immediately called on every ecs.Entity change. Replaces the current listener. Call with `nil` to remove a listener.
For details, see EntityEvent.
Example ¶
world := NewWorld() listener := func(evt *EntityEvent) { fmt.Println(evt) } world.SetListener(listener) world.NewEntity()
Output: &{{1 0} {0 0} {0 0} [] [] [] 1}