Ark
Batch operations

Batch operations

In an archetype-based ECS, creation and removal of entities or components are relatively costly operations. For these operations, Ark provides batched versions. This allows to create or manipulate a large number of entities much faster than one by one. Most batch methods come in two flavors. A “normal” one, and one that runs a callback function on each affected entity.

Creating entities

Entity creation is probably the most common use case for batching. When the number of similar entities that are to be created is known, creation can be batched with ecs.Map2.NewBatch et al.:

1// Create a component mapper.
2mapper := ecs.NewMap2[Position, Velocity](&world)
3// Create a batch of 100 entities.
4mapper.NewBatch(100, &Position{}, &Velocity{X: 1, Y: -1})

ecs.Map2.NewBatchFn can be used for more flexible initialization:

 1// Create a component mapper.
 2mapper := ecs.NewMap2[Position, Velocity](&world)
 3// Create a batch of 100 entities using a callback.
 4mapper.NewBatchFn(100, func(entity ecs.Entity, pos *Position, vel *Velocity) {
 5	pos.X = rand.Float64() * 100
 6	pos.Y = rand.Float64() * 100
 7
 8	vel.X = rand.NormFloat64()
 9	vel.Y = rand.NormFloat64()
10})

Components

Components can be added, removed or exchanged in batch operations. For these operations, ecs.Map2, ecs.Exchange2 etc. provide batch versions of the respective methods. Component batch operations take an ecs.Batch filter as an argument to determine the affected entities:

 1// Create a world
 2world := ecs.NewWorld()
 3
 4// Create a component mapper.
 5mapper := ecs.NewMap2[Position, Velocity](&world)
 6// Create some entities.
 7for range 100 {
 8	world.NewEntity()
 9}
10
11// Create a filter.
12filter := ecs.NewFilter0(&world)
13// Batch-add components.
14mapper.AddBatch(filter.Batch(), &Position{}, &Velocity{X: 1, Y: -1})
15
16// Batch-Remove components. The optional callback is not used here.
17mapper.RemoveBatch(filter.Batch(), nil)
18
19// Alternatively, add and initialize components with a callback.
20mapper.AddBatchFn(filter.Batch(), func(entity ecs.Entity, pos *Position, vel *Velocity) {
21	// ...
22})

Removing entities

Entities can be removed in batches using ecs.World.RemoveEntities:

 1// Create a component mapper.
 2mapper := ecs.NewMap2[Position, Velocity](&world)
 3// Create some entities.
 4mapper.NewBatch(10, &Position{}, &Velocity{X: 1, Y: -1})
 5
 6// Create a filter.
 7filter := ecs.NewFilter2[Position, Velocity](&world)
 8// Remove all matching entities. The callback can also be nil.
 9world.RemoveEntities(filter.Batch(), func(entity ecs.Entity) {
10	fmt.Println("Removing", entity)
11})