ECS Resources

So far, we stored all data in components, associated to entities. However, sometimes this is not optimal. This particularly applies to non-ECS data structures, and “things” that appear only once in a model or game.

For these cases, Arche provides so-called ecs.Resources . A resource can be thought of as a component that only appears once, globally, in an ecs.World .

Resource types

Just like with components, any Go struct (or other Go type) can be a resource. An example:

1type Grid struct {
2    Data [][]ecs.Entity
3    Width int
4    Height int
5}

Resource IDs

Also analogous to components, resources are identified by a unique ID that can be obtained or registered using ecs.ResourceID :

1world := ecs.NewWorld()
2
3gridID := ecs.ResourceID[Grid](&world)
4_ = gridID

As with components, a resource is registered and assigned an ID on first use automatically.

Adding resources

The most simple way to add a resource to the world is the function ecs.AddResource :

1world := ecs.NewWorld()
2
3// Create the resource, and add a pointer to it to the world.
4grid := NewGrid(30, 20)
5ecs.AddResource(&world, &grid)

An ID is automatically assigned to type Grid here, if it was not registered before with ecs.ResourceID .

ecs.AddResource , however, is not particularly efficient. It a resource needs to be added (and removed) repeatedly, use ecs.World.Resources :

1world := ecs.NewWorld()
2gridID := ecs.ResourceID[Grid](&world)
3
4// Create the resource, and add a pointer to it to the world.
5grid := NewGrid(30, 20)
6world.Resources().Add(gridID, &grid)

Accessing resources

Access to resources is obtained via ecs.World.Resources in the ID-based API, and via generic.Resource in the generic API:

 1world := ecs.NewWorld()
 2
 3// Create the resource, and add a pointer to it to the world.
 4grid := NewGrid(30, 20)
 5ecs.AddResource(&world, &grid)
 6
 7// Then, somewhere else in the code...
 8gridRes := generic.NewResource[Grid](&world)
 9grid2 := gridRes.Get()
10
11_ = grid2.Data[1][2]
 1world := ecs.NewWorld()
 2
 3// Create the resource, and add a pointer to it to the world.
 4grid := NewGrid(30, 20)
 5ecs.AddResource(&world, &grid)
 6
 7// Then, somewhere else in the code...
 8gridID := ecs.ResourceID[Grid](&world)
 9grid2 := world.Resources().Get(gridID).(*Grid)
10
11_ = grid2.Data[1][2]

Note that in the ID-based example, we need to cast the pointer retrieved from ecs.Resources.Get to *Grid, similar to the cast in ID-based component access. However, the syntax is a bit different here as we cast an interface{}, rather than an unsafe.Pointer for components.

As with components, the generic API is the recommended way for normal usage.