diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 05ffcd9a..6e48dcfb 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -30,6 +30,9 @@ jobs:
- name: Run benchmark tables
run: |
go run ./benchmark/table | tee docs/content/background/_benchmarks.md
+ - name: Copy changelog
+ run: |
+ cp ./CHANGELOG.md ./docs/content/background/_changelog.md
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
deleted file mode 100644
index 425552d2..00000000
--- a/ARCHITECTURE.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# Architecture
-
-## Archetype-based architecture
-
-*Arche* uses an archetype-based architecture.
-
-The ASCII graph below illustrates the approach.
-Components for entities are stored in so-called archetypes, which represent unique combinations of components.
-In the illustration, the first archetype holds all components for all entities with (only/exactly) the components A, B and C.
-
-```text
- Entities Archetypes Bitmasks Queries
-
- E E Comps
- |0| |2|A|B|C| 111...<-.<--match-.
- |1|---. |8|A|B|C| | |
- |2| '-->|1|A|B|C| | |
- |3| |3|A|B|C| |--(A, C) |
- |4| | 101... |
- |6| .-->|7|A|C| 101...<-' |--(B)
- |7|---' |6|A|C| | 010...
- |8| |4|A|C| |
- |9|---. |
- |.| | |5|B|C| 011... <--------'
- |.| '-->|9|B|C|
- |.|
- |.| <===> [Entity pool]
-```
-
-The exact composition of each archetype is encoded in a bitmask for fast comparison.
-Thus, queries can easily identify their relevant archetypes, and then simply iterate entities linearly, which is very fast. Components can be accessed through the query in a very efficient way (≈1ns).
-
-For getting components by entity ID, e.g. for hierarchies, the world contains a list that is indexed by the entity ID. For each entity, it references it's current archetype and the index in the archetype. This way, getting components for entity IDs (i.e. random access) is fast, although not as fast as in queries (≈1.5ns vs. 1ns).
-
-Obviously, archetypes are an optimization for iteration speed.
-But they also come with a downside. Adding or removing components to/from an entity requires moving all the components of the entity to another archetype.
-This takes around 20ns per involved component.
-It is therefore recommended to add/remove/exchange multiple components at the same time rather than one after the other.
-
-## Entity relations
-
-*Arche* supports entity relations as first class feature.
-Relations are used to represent graphs of entities, e.g. hierarchies.
-Relations are added to and removed from entities just like components.
-
-In Arche, queries can specify a target entity for a relation.
-These relation queries are as fast as usual queries for component compositions.
-This is achieved by subdividing archetypes with a relation component by their relation target. I.e. entities that reference a different target entity are stored in separate archetypes.
-
-The feature is inspired by [Flecs](https://github.com/SanderMertens/flecs).
-However, the implementation in *Arche* is currently limited in that it only supports a single relation per entity, and no nested relation queries.
-
-### Benchmarks
-
-The figure below compares the iteration time per entity for different ways of representing entity relations.
-The task is to sum up a value over the children of each parent.
-
-The following ways to represent entity relations are shown in the figure:
-
-* **ParentList** (purple): Children form an implicit linked list. The parent references the first child.
- * Query over parents, inner loop implicit linked list of children, using world access for next child and value component.
-* **ParentSlice** (red): The parent holds a slice of all it's children.
- * Query over parents, inner loop over slice of children using world access for value component.
-* **Child** (green): Each child references it's parent.
- * Query over all child entities and retrieval of the parent sum component using world access.
-* **Default** (blue): Using Arche's relations feature without filter caching.
- * Outer query over parents, inner loop over children using relation queries.
-* **Cached** (black): Using Arche's relations feature with filter caching.
- * Same as above, using an additional component per parent to store cached filters.
-
-The first three representations are possible in any ECS, while the last two use Arche's relations feature.
-
-
-
-![Benchmarks Entity relations](https://user-images.githubusercontent.com/44003176/238461931-7824bfeb-4a03-49e8-9de8-0650032259c0.svg)
-*Iteration time per entity for different ways of representing entity relations. Color: ways to represent entity relations; Line style: total number of child entities; Markers: number of children per parent entity*
-
-
-The benchmarks show that Arche's relations feature outperforms the other representations, except when there are very few children per parent.
-Only when there is a huge number of parents and significantly fewer than 100 children per parent,
-the *Child* representation should perform better.
diff --git a/BENCHMARKS.md b/BENCHMARKS.md
deleted file mode 100644
index 1226cbf4..00000000
--- a/BENCHMARKS.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# Benchmarks
-
-This document gives an overview of the runtime cost of typical Arche operations.
-All time information is per entity.
-Batch operations are performed in batches of 1000 entities.
-
-Absolute numbers are not really meaningful, as they heavily depend on the hardware.
-However, all benchmarks run in the CI in the same job and hence on the same machine, and can be compared.
-
-Benchmark code: [`benchmark/table`](https://github.com/mlange-42/arche/tree/main/benchmark/table).
-
-## Query
-
-| Operation | Time | Remark |
-|----------------------------------|-------------:|------------------------------|
-| Query.Next | 1.0 ns | |
-| Query.Next + 1x Query.Get | 1.6 ns | |
-| Query.Next + 2x Query.Get | 2.2 ns | |
-| Query.Next + 5x Query.Get | 4.4 ns | |
-| Query.Next + Query.Relation | 2.3 ns | |
-| Query.EntityAt, 1 arch | 12.0 ns | |
-| Query.EntityAt, 1 arch | 2.8 ns | registered filter |
-| Query.EntityAt, 5 arch | 31.6 ns | |
-| Query.EntityAt, 5 arch | 4.9 ns | registered filter |
-| World.Query | 45.1 ns | |
-| World.Query | 33.4 ns | registered filter |
-
-## World access
-
-| Operation | Time | Remark |
-|----------------------------------|-------------:|------------------------------|
-| World.Get | 2.0 ns | random, 1000 entities |
-| World.Has | 1.2 ns | random, 1000 entities |
-| World.Alive | 0.6 ns | random, 1000 entities |
-| World.Relations.Get | 3.5 ns | random, 1000 entities |
-| World.Relations.GetUnchecked | 0.8 ns | random, 1000 entities |
-
-## Entities
-
-| Operation | Time | Remark |
-|----------------------------------|-------------:|------------------------------|
-| World.NewEntity | 16.2 ns | memory already allocated |
-| World.NewEntity w/ 1 Comp | 34.0 ns | memory already allocated |
-| World.NewEntity w/ 5 Comps | 45.1 ns | memory already allocated |
-| World.RemoveEntity | 14.7 ns | |
-| World.RemoveEntity w/ 1 Comp | 27.0 ns | |
-| World.RemoveEntity w/ 5 Comps | 53.5 ns | |
-
-## Entities, batched
-
-| Operation | Time | Remark |
-|----------------------------------|-------------:|------------------------------|
-| Builder.NewBatch | 9.7 ns | 1000, memory already allocated |
-| Builder.NewBatch w/ 1 Comp | 10.1 ns | 1000, memory already allocated |
-| Builder.NewBatch w/ 5 Comps | 10.2 ns | 1000, memory already allocated |
-| Batch.RemoveEntities | 7.0 ns | 1000 |
-| Batch.RemoveEntities w/ 1 Comp | 7.2 ns | 1000 |
-| Batch.RemoveEntities w/ 5 Comps | 7.6 ns | 1000 |
-
-## Components
-
-| Operation | Time | Remark |
-|----------------------------------|-------------:|------------------------------|
-| World.Add 1 Comp | 48.2 ns | memory already allocated |
-| World.Add 5 Comps | 66.9 ns | memory already allocated |
-| World.Remove 1 Comp | 58.1 ns | |
-| World.Remove 5 Comps | 103.6 ns | |
-| World.Exchange 1 Comp | 55.5 ns | memory already allocated |
-
-## Components, batched
-
-| Operation | Time | Remark |
-|----------------------------------|-------------:|------------------------------|
-| Batch.Add 1 Comp | 8.4 ns | 1000, memory already allocated |
-| Batch.Add 5 Comps | 8.9 ns | 1000, memory already allocated |
-| Batch.Remove 1 Comp | 10.3 ns | 1000 |
-| Batch.Remove 5 Comps | 15.3 ns | 1000 |
-| Batch.Exchange 1 Comp | 10.0 ns | 1000, memory already allocated |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dbc20aab..710c18a4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,3 @@
-# Changelog
-
## [[unpublished]](https://github.com/mlange-42/arche/compare/v0.10.1...main)
### Features
@@ -10,7 +8,7 @@
### Documentation
-* Adds a dedicated Arche [User Guide](https://mlange-42.github.io/arche/) web site (#380, #382, #383, #384)
+* Adds a dedicated Arche [User Guide](https://mlange-42.github.io/arche/) web site (#380, #382, #383, #384, #385)
* Adds [BENCHMARKS.md](https://github.com/mlange-42/arche/blob/main/BENCHMARKS.md) for a tabular overview of the runtime cost of typical *Arche* ECS operations (#367, #372)
* Link benchmarking code in `README.md` and benchmarking tables (#375)
* Documents build tags `tiny` and `debug` in package docs of `ecs` (#377)
diff --git a/README.md b/README.md
index 7b4c49a8..c96fa29d 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,14 @@
[![Arche (logo)](https://user-images.githubusercontent.com/44003176/236701164-28178d13-7e52-4449-baa4-41b764183cbd.png)](https://github.com/mlange-42/arche)
[![Test status](https://img.shields.io/github/actions/workflow/status/mlange-42/arche/tests.yml?branch=main&label=Tests&logo=github)](https://github.com/mlange-42/arche/actions/workflows/tests.yml)
-[![Coverage Status](https://badge.coveralls.io/repos/github/mlange-42/arche/badge.svg?branch=main)](https://badge.coveralls.io/github/mlange-42/arche?branch=main)
+[![Coverage Status](https://img.shields.io/coverallsCoverage/github/mlange-42/arche?logo=coveralls)](https://badge.coveralls.io/github/mlange-42/arche?branch=main)
[![Go Report Card](https://goreportcard.com/badge/github.com/mlange-42/arche)](https://goreportcard.com/report/github.com/mlange-42/arche)
-[![Go Reference](https://pkg.go.dev/badge/github.com/mlange-42/arche.svg)](https://pkg.go.dev/github.com/mlange-42/arche)
+[![User Guide](https://img.shields.io/badge/user_guide-%23007D9C?logo=go&logoColor=white&labelColor=gray)](https://mlange-42.github.io/arche/)
+[![Go Reference](https://img.shields.io/badge/reference-%23007D9C?logo=go&logoColor=white&labelColor=gray)](https://pkg.go.dev/github.com/mlange-42/arche)
[![GitHub](https://img.shields.io/badge/github-repo-blue?logo=github)](https://github.com/mlange-42/arche)
-[![DOI:10.5281/zenodo.7656484](https://zenodo.org/badge/DOI/10.5281/zenodo.7656484.svg)](https://doi.org/10.5281/zenodo.7656484)
-[![MIT license](https://img.shields.io/github/license/mlange-42/arche)](https://github.com/mlange-42/arche/blob/main/LICENSE)
+[![DOI:10.5281/zenodo.7656484](https://img.shields.io/badge/10.5281%2Fzenodo.7656484-blue?label=doi)](https://doi.org/10.5281/zenodo.7656484)
+[![MIT license](https://img.shields.io/badge/MIT-brightgreen?label=license)](https://github.com/mlange-42/arche/blob/main/LICENSE)
-*Arche* is an [archetype](https://github.com/mlange-42/arche/blob/main/ARCHITECTURE.md)-based [Entity Component System](https://en.wikipedia.org/wiki/Entity_component_system) for [Go](https://go.dev/).
+*Arche* is an [archetype](https://mlange-42.github.io/arche/background/architecture/)-based [Entity Component System](https://en.wikipedia.org/wiki/Entity_component_system) for [Go](https://go.dev/).
*Arche* is designed for the use in simulation models of the
[Department of Ecological Modelling](https://www.ufz.de/index.php?en=34213) at the
@@ -24,7 +25,7 @@
* Simple [core API](https://pkg.go.dev/github.com/mlange-42/arche/ecs). See the [API docs](https://pkg.go.dev/github.com/mlange-42/arche).
* Optional logic [filter](https://pkg.go.dev/github.com/mlange-42/arche/filter) and type-safe [generic](https://pkg.go.dev/github.com/mlange-42/arche/generic) API.
-* Entity relations as first-class feature. See [Architecture](https://github.com/mlange-42/arche/blob/main/ARCHITECTURE.md#entity-relations).
+* Entity relations as first-class feature. See the [User Guide](https://mlange-42.github.io/arche/user-guide/relations/).
* World serialization and deserialization with [arche-serde](https://github.com/mlange-42/arche-serde).
* No systems. Just queries. Use your own structure (or the [Tools](#tools)).
* No dependencies. Except for unit tests ([100% coverage](https://coveralls.io/github/mlange-42/arche)).
@@ -42,9 +43,8 @@ go get github.com/mlange-42/arche
Here is the classical Position/Velocity example that every ECS shows in the docs.
It uses the type-safe [generic](https://pkg.go.dev/github.com/mlange-42/arche/generic) API.
-For a full-featured wrapper with systems, scheduling and more, see [arche-model](https://github.com/mlange-42/arche-model).
-See the [API docs](https://pkg.go.dev/github.com/mlange-42/arche) and
+See the [User Guide](https://mlange-42.github.io/arche/), [API docs](https://pkg.go.dev/github.com/mlange-42/arche) and
[examples](https://github.com/mlange-42/arche/tree/main/_examples) for details.
For more complex examples, see [arche-demo](https://github.com/mlange-42/arche-demo).
@@ -156,14 +156,14 @@ This may not seem idiomatic for Go.
However, explicit error handling in performance hotspots is not an option.
Neither is silent failure, given the scientific background.
-### Other limitations
+### Limitations
* The number of component types per `World` is limited to 256. This is mainly a performance decision.
* The number of entities alive at any one time is limited to just under 5 billion (`uint32` ID).
## Benchmarks
-A tabular overview of the runtime cost of typical *Arche* ECS operations is provided in [BENCHMARKS.md](https://github.com/mlange-42/arche/blob/main/BENCHMARKS.md).
+A tabular overview of the runtime cost of typical *Arche* ECS operations is provided under [benchmarks](https://mlange-42.github.io/arche/background/benchmarks/) in the Arche's [User Guide](https://mlange-42.github.io/arche/).
See also the latest [Benchmarks CI run](https://github.com/mlange-42/arche/actions/workflows/benchmarks.yml).
diff --git a/_examples/doc.go b/_examples/doc.go
index f612f96b..46fe12ef 100644
--- a/_examples/doc.go
+++ b/_examples/doc.go
@@ -1,4 +1,8 @@
// Package examples contains examples for Arche.
//
// See the top level module [github.com/mlange-42/arche] for an overview.
+//
+// 🕮 Also read the Arche's [User Guide]!
+//
+// [User Guide]: https://mlange-42.github.io/arche/
package examples
diff --git a/doc.go b/doc.go
index c27945db..04c555cf 100644
--- a/doc.go
+++ b/doc.go
@@ -7,4 +7,8 @@
// - Advanced filters -- [github.com/mlange-42/arche/filter]
// - Event listeners -- [github.com/mlange-42/arche/listener]
// - Usage examples -- [github.com/mlange-42/arche/_examples]
+//
+// 🕮 Also read the Arche's [User Guide]!
+//
+// [User Guide]: https://mlange-42.github.io/arche/
package arche
diff --git a/docs/content/_index.md b/docs/content/_index.md
index 492b78b5..ded106f3 100644
--- a/docs/content/_index.md
+++ b/docs/content/_index.md
@@ -11,26 +11,29 @@ no_heading = true
-
+
+
+
+
-
+
-
+
-
+
{{< /html >}}
-*Arche* is an [archetype](https://github.com/mlange-42/arche/blob/main/ARCHITECTURE.md)-based [Entity Component System](https://en.wikipedia.org/wiki/Entity_component_system) for [Go](https://go.dev/).
+*Arche* is an [archetype](/background/architecture)-based [Entity Component System](https://en.wikipedia.org/wiki/Entity_component_system) for [Go](https://go.dev/).
*Arche* is designed for the use in simulation models of the
[Department of Ecological Modelling](https://www.ufz.de/index.php?en=34213) at the
@@ -40,13 +43,13 @@ no_heading = true
- Simple core API. See the [API docs](https://pkg.go.dev/github.com/mlange-42/arche).
- Optional logic [filter](https://pkg.go.dev/github.com/mlange-42/arche/filter) and type-safe [generic](https://pkg.go.dev/github.com/mlange-42/arche/generic) API.
-- Entity relations as first-class feature. See [Architecture](https://github.com/mlange-42/arche/blob/main/ARCHITECTURE.md).
+- Entity relations as first-class feature. See the [User Guide](https://mlange-42.github.io/arche/user-guide/relations/).
- World serialization and deserialization with [arche-serde](https://github.com/mlange-42/arche-serde).
- No systems. Just queries. Use your own structure (or the [Tools](https://github.com/mlange-42/arche#tools)).
- No dependencies. Except for unit tests ([100% coverage](https://coveralls.io/github/mlange-42/arche)).
- Probably the fastest Go ECS out there. See the [Benchmarks](https://github.com/mlange-42/arche#benchmarks).
-For more information, see the GitHub [repository](https://github.com/mlange-42/arche) and [API docs](https://pkg.go.dev/github.com/mlange-42/arche).
+For more information, see the [GitHub repository](https://github.com/mlange-42/arche) and [API docs](https://pkg.go.dev/github.com/mlange-42/arche).
## Cite as
diff --git a/docs/content/background/.gitignore b/docs/content/background/.gitignore
index b25ee02d..dcd22944 100644
--- a/docs/content/background/.gitignore
+++ b/docs/content/background/.gitignore
@@ -1 +1,2 @@
/_benchmarks.md
+/_changelog.md
diff --git a/docs/content/background/_index.md b/docs/content/background/_index.md
index 1ae1238a..96e21bbb 100644
--- a/docs/content/background/_index.md
+++ b/docs/content/background/_index.md
@@ -6,4 +6,8 @@ part = 2
description = "Background information on Arche's design, architecture, performance and history."
+++
-Background information on Arche's design, architecture, performance and history.
+Background information on Arche's
+[design](./design),
+[architecture](./architecture),
+[performance](./benchmarks) and
+[history](./changelog).
diff --git a/docs/content/background/benchmarks.md b/docs/content/background/benchmarks.md
index edce076a..afc72ce4 100644
--- a/docs/content/background/benchmarks.md
+++ b/docs/content/background/benchmarks.md
@@ -15,5 +15,6 @@ Benchmark code: {{< repo "/tree/main/benchmark/table" "benchmark/table" >}} in t
Benchmarks are run automatically in the GitHub CI, and are updated on this page on every merge into the `main` branch.
They always reflect the latest development state of Arche, but may change depending on the hardware the CI runs on.
+For a benchmark comparison with other ECS implementations, see the benchmarks on the {{< repo "#benchmarks" "repo README" >}}.
-{{% include file="background/_benchmarks.md" %}}
+{{% include file="/background/_benchmarks.md" %}}
diff --git a/docs/content/background/changelog.md b/docs/content/background/changelog.md
index dc768780..2a2f5f5b 100644
--- a/docs/content/background/changelog.md
+++ b/docs/content/background/changelog.md
@@ -3,463 +3,4 @@ title = 'Changelog'
weight = 90
description = 'Arche changelog.'
+++
-
-## [[v0.10.1]](https://github.com/mlange-42/arche/compare/v0.10.0...v0.10.1)
-
-### Bugfixes
-
-* Fix IsRelation check to allow for non-struct components, like type aliases (#354)
-
-### Other
-
-* Repository [arche-demo](https://github.com/mlange-42/arche-demo) provides a [live demo](https://mlange-42.github.io/arche-demo/)
-of several models built with Arche.
-
-## [[v0.10.0]](https://github.com/mlange-42/arche/compare/v0.9.0...v0.10.0)
-
-### Highlights
-
-* Arche supports full world serialization and deserialization, in conjunction with [arche-serde](https://github.com/mlange-42/arche-serde) (#319)
-* Supports 256 instead of 128 component types as well as resource types and engine locks (#313)
-* Generic API supports up to 12 instead of 8 component types (#324)
-* Reworked event system with granular subscription to different event types and components (#333, #334, #335, #337, #340)
-
-### Breaking changes
-
-* `MaskTotalBits` changed from 128 to 256 (#313)
-* Removes `Mask.Lo` and `Mask.Hi`, internal mask representation is now private (#313)
-* `Filter.Matches(Mask)` became `Filter.Matches(*Mask)`; same for all `Filter` implementations (#313)
-This change was necessary to get the same performance as before, despite the more heavyweight implementation of the now 256 bits `Mask`.
-* Component and resource IDs are now opaque types instead of type aliases for `uint8` (#330)
-* Restructures `EntityEvent` to remove redundant information and better handle relation changes (#333)
-* World event listener changed from a simple function to a `Listener` interface (#334)
-* Removes `World.ComponentType(ID)`, use function `ComponentInfo(ID)` instead (#341)
-
-### Features
-
-* Adds functions `ComponentInfo(*World, ID)` and `ResourceType(*World, ResID)` (#315, #318)
-* Adds methods `World.Ids(Entity)` and `Query.Ids()` to get component IDs for an entity (#315, #325)
-* Entities support JSON marshalling and unmarshalling (#319)
-* The world's entity state can be extracted and re-established via `World.DumpEntities()` and `World.LoadEntities()` (#319, #326)
-* Adds functions `ComponentIDs(*World)` and `ResourceIDs(*World)` to get all registered IDs (#330)
-* Adds methods `Mask.And`, `Mask.Or` and `Mask.Xor` (#335)
-* Adds build tag `tiny` to restrict to 64 components for an extra bit of performance (#338)
-* Adds methods `Relations.Exchange()`, `Relations.ExchangeBatch()`, `Relations.ExchangeBatchQ()` for exchange with relation target (#342)
-* Generic API adds `Exchange.WithRelation()` and optional target argument for operations with relation target (#342)
-* Generic API adds `MapX.AddBatch()`, `MapX.AddBatchQ()`, `MapX.RemoveBatch()`and `MapX.RemoveBatchQ()` (#342)
-* Generic API adds optional relation target argument to most `MapX` methods (#342)
-* Generic API adds `FilterX.Filter()` to get an `ecs.Filter` from a generic one (#342)
-* Generic API adds `Map.SetRelationBatch()` and `Map.SetRelationBatchQ()` (#344)
-* All batch operations (except entity creation) return the number of affected entities (#348)
-
-### Performance
-
-* Reduces archetype memory footprint by using a dynamically sized slice for storage lookup (#327)
-* Reduces event listener overhead through granular subscriptions and elimination of a heap allocation (#333, #334, #335, #337, #340)
-
-### Documentation
-
-* Adds an overview to packages `ecs` and `generic` on how to achieve ECS manipulation operations (#345)
-
-### Other
-
-* Entity generation data type changed from `uint16` to `uint32` (#317)
-* Adds [unitoftime/ecs](https://github.com/unitoftime/ecs) to competition benchmarks (#311)
-* Adds competition benchmarks for accessing 10 components (#328)
-
-## [[v0.9.0]](https://github.com/mlange-42/arche/compare/v0.8.1...v0.9.0)
-
-### Infrastructure
-
-* Upgraded to Go 1.21 toolchain (#308)
-
-## [[v0.8.1]](https://github.com/mlange-42/arche/compare/v0.8.0...v0.8.1)
-
-### Documentation
-
-* Emphasize in `Entity` and `World` docs that entities are intended to be stored and passed by copy, not by pointer (#306)
-
-## [[v0.8.0]](https://github.com/mlange-42/arche/compare/v0.7.1...v0.8.0)
-
-### Highlights
-
-Entity relations were added as a first-class feature (#231, #271)
-
-Relations are used to represent graphs of entities, e.g. hierarchies.
-They can be added, removed and queried just like normal components.
-The new feature offers ergonomic handling of entity relations,
-and provides relation queries with native performance.
-
-### Breaking changes
-
-* Removed `World.Batch` for entity batch creation, use `Builder` instead (#239)
-* Rework of generic entity creation API, use `MapX.New`, `MapX.NewWith`, `MapX.NewBatch` and `MapX.NewQuery` (#239, #252)
-* Stats object `WorldStats` etc. adapted for new structure of archetypes nested in nodes (#258)
-* Removed generic filter method `FilterX.Filter` (#271)
-* Method `Batch.NewQuery` renamed to `Batch.NewBatchQ` (#298)
-
-### Features
-
-* Relation archetypes are removed when they are empty *and* the target entity is dead (#238, #242)
-* Support an unlimited number of cached filters, instead of 128 (#245)
-* `WorldStats` contains the number of cached filters (#247)
-* Archetypes with entity relations are removed on `World.Reset` (#247)
-* Capacity increment can be configured separately for relation archetypes (#257)
-* Adds methods for faster, unchecked entity relation access (#259)
-* Re-introduce `World.Batch` for batch-processing of entities (add/remove/exchange) (#264)
-* New method `Builder.Add` for adding components with a target to entities (#264)
-* New method `Batch.SetRelation` for batch-setting entity relations (#265)
-* New methods `Builder.AddQ`, `Builder.RemoveQ` etc. to get a query over batch-processed entities (#297)
-* Sends an `EntityEvent` to the world listener on relation target changes (#265)
-
-### Performance
-
-* Reduce memory footprint of archetypes by moving properties to nodes (#237)
-* Queries iterate archetype graph nodes in an outer loop, potentially skipping nested relation archetypes (#248)
-* Relation archetypes are recycled in archetype graph nodes (#248)
-* Already empty archetypes are not zeroed on reset (#248)
-* Optimize `RelationFilter`: get archetype directly instead of iterating complete node (#251)
-* Cached filters use swap-remove when removing an archetype (#253)
-* Speed up generic query re-compilation after changing the relation target (#255)
-* Speed up archetype and node iteration to be as fast as before the new nested structure (#270, #288)
-* ~~Filter cache stores archetype graph nodes instead of archetypes (#276)~~ (#288)
-* Use `uint32` instead of `uintptr` for indices and query iteration counter (#283)
-* Cached filters use a map for faster removal of archetypes (#289)
-* Speed up iterating through many archetypes by approx. 10% (#301)
-
-### Documentation
-
-* Adds an example for creating and querying entity relations (#256)
-* Adds a section on entity relations to the `ARCHITECTURE.md` document (#256)
-* Replace Aos benchmarks plot in README for pointer iteration fix #284 (#285)
-* Adds a plot for entity relation benchmarks to ARCHITECTURE.md (#290)
-* Adds an outline of the most important types and functions to each sub-package (#295)
-
-### Other
-
-* Remove go-gameengine-ecs from Arche benchmarks (but not from competition!) (#228)
-* Reduce memory size of `Query` and internal archetype list by 8 bytes (#230)
-* Generic filters are locked when registered for caching (#241)
-* Adds benchmarks for getting and setting entity relations (#259)
-* Arche now has an official logo (#273)
-* Use for loop with counter in AoS competition benchmarks, to allow for pointers (#284)
-
-## [[v0.7.1]](https://github.com/mlange-42/arche/compare/v0.7.0...v0.7.1)
-
-### Documentation
-
-* Tweak/improve example `batch_ops` (#222)
-* Adds an example for running simulations in parallel (#223)
-
-### Other
-
-* Adds benchmarks for world component access with shuffled entities (#224)
-
-## [[v0.7.0]](https://github.com/mlange-42/arche/compare/v0.6.3...v0.7.0)
-
-### Features
-
-* Adds method `World.ComponentType(ID)` to get the `reflect.Type` for component IDs (#215)
-* Adds methods `World.GetUnchecked` and `World.HasUnchecked` as optimized variants for known static entities (#217, #219)
-* Adds method `MapX.GetUnchecked` to all generic mappers, as equivalent to previous point (#217, #219)
-* Adds methods `Map.GetUnchecked` and `Map.HasUnchecked` to generic `Map`, as equivalent to previous points (#217, #219)
-
-### Performance
-
-* Optimize `World.Alive(Entity)` by only checking the entity generation, but not `id == 0` (#220)
-
-### Bugfixes
-
-* All world methods with an entity as argument panic on a dead/recycled entity; causes 0.5ns slower `World.Get(Entity)` (#216)
-
-## [[v0.6.3]](https://github.com/mlange-42/arche/compare/v0.6.2...v0.6.3)
-
-### Documentation
-
-* Minor README and docstring tweaks (#211, #213)
-
-### Other
-
-* Use [coveralls.io](https://badge.coveralls.io/github/mlange-42/arche?branch=main) for test coverage, add respective badge (#212)
-
-## [[v0.6.2]](https://github.com/mlange-42/arche/compare/v0.6.1...v0.6.2)
-
-### Performance
-
-* Speed up generating world stats by factor 10, by re-using stats object (#210)
-
-## [[v0.6.1]](https://github.com/mlange-42/arche/compare/v0.6.0...v0.6.1)
-
-### Documentation
-
-* Extend documentation and benchmarks for `Entity` (#201)
-* Add a section with links to the Arche tools [arche-model](https://github.com/mlange-42/arche-model) and [arche-pixel](https://github.com/mlange-42/arche-pixel) (#202)
-
-## [[v0.6.0]](https://github.com/mlange-42/arche/compare/v0.5.1...v0.6.0)
-
-Arche v0.6.0 features fast batch entity creation and deletion, cached filters, and many internal optimizations.
-
-### Highlights
-
-* Batch creation and deletion of entities, with up to 4x and 10x speedup, respectively. Even more when combined with `World.Reset()`.
-* Cached filters for handling many archetypes and complex queries without slowdown.
-* A lot of internal performance optimizations.
-
-### Breaking changes
-
-* Generic mappers do no longer return all components when creating entities or components (#145)
-* Resources API moved out of the world, to a helper to get by `World.Resources()` (#150)
-* `World.Reset()` does no longer remove the component change listener (#157)
-* Removes methods `filter.ALL.Not()` and `filter.ANY.Not()`, use `NoneOf()` and `AnyNot()` instead (#160)
-* World listener function takes a pointer to the `EntityEvent` instead of a copy as argument (#162)
-
-### Features
-
-* Adds method `World.Reset()`, to allow for more efficient systematic simulations (#138)
-* Adds `World.Batch()` helper for performing optimized batch-creation and batch-removal of entities (#149)
-* Adds method `Mask.Exclusive()` to create a filter matching an exact component composition (#149, #188)
-* Generic mappers (`Map1`, ...) have methods `NewEntities`, `NewEntitiesWith` and `RemoveEntities` for batch operations (#151)
-* Batch-creation methods (ID-based and generic) have variants like `NewEntitiesQuery` that return a query over the created entities (#152)
-* Notification during batch-creation is delayed until the resp. query is closed (#157)
-* Batch-remove methods (`RemoveEntities()`) return the number of removed entities (#173)
-* Filters can be cached and tracked by the `World` to speed up queries when there are many archetypes (#178)
-* Function `AddResource[T](*World)` returns the ID of the resource (#183)
-
-### Performance
-
-* Speedup of archetype mask checks by 10% by checking mask before empty archetype (#139)
-* Speedup of generic queries and mappers to come closer to ID-based access (#144)
-* Speedup of archetype mask checks by casting filter interface to concrete type when possible (#148)
-* Optimized batch creation of entities (#159)
-* More efficiently clear the memory of removed components, with 2-3x speedup (#165)
-* Do not clear memory when adding entities to archetypes, not required anymore as of #147 (#165)
-* Speed up copying entity to archetype by getting entity pointer without reflection (#166)
-* Avoid slice allocations in generic mapper methods (#170)
-* Avoid type checks in query when iterating archetypes (#179)
-* Speed up counting entities in queries with a cached filter (#182)
-* Implements a fast and memory-efficient lookup data structure for components ID keys, to reduce the memory footprint of archetypes and the archetype graph (#192)
-* Speedup of archetype creation by 40% by using a `const` for archetype storage page sizes (#197)
-
-### Bugfixes
-
-* Archetype storage buffers are "zeroed" when removing entities, to allow GC on pointers and slices in components (#147)
-* Use slices instead of arrays inside paged archetype list to ensure pointer persistence (#184)
-
-### Documentation
-
-* Adds an example for batch-creation and batch-removal of entities (#173)
-* Adds code examples to most public types, methods and functions (#183, #189)
-
-### Other
-
-* Restructure and extend benchmarks (#146, #153, #155, #156)
-* Add an ECS competition benchmark for adding and removing components (#170)
-* Add benchmarks for different ways to implement parent-child relations between entities (#194, #195)
-
-## [[v0.5.1]](https://github.com/mlange-42/arche/compare/v0.5.0...v0.5.1)
-
-### Performance
-
-* Speedup of archetype access by 5-10% by merging storages into archetypes (#137)
-
-### Documentation
-
-* Document all private functions, types and methods (#136)
-* Adds a section and plot on benchmarks against other Go ECS implementations to the README (#138)
-
-### Other
-
-* Internal code refactoring (#136)
- * Move method `nextArchetype` from `World` to `Query`.
- * Remove internal type `queryIter`.
- * Move repetitive pointer copying code in `storage` into a private method.
- * Move repetitive entity creation code in `World` into a private method.
-
-## [[v0.5.0]](https://github.com/mlange-42/arche/compare/v0.4.6...v0.5.0)
-
-Feature release. Does not break v0.4.x projects.
-
-### Features
-
-* The World handles ECS resources, i.e. component-like global data (#132)
-* Generic access to world resources (#132)
-
-### Documentation
-
-* Adds an example for the use of resources (#132)
-
-## [[v0.4.6]](https://github.com/mlange-42/arche/compare/v0.4.5...v0.4.6)
-
-### Performance
-
-* Speedup archetype access by 10%, by elimination of bounds checks (#126)
-* Speedup entity access from queries by 50% by using a component storage for them (#131)
-* Minor optimizations of component storage (#128)
-
-### Documentation
-
-* Adds an example to demonstrate how to implement classical ECS systems (#129)
-
-## [[v0.4.5]](https://github.com/mlange-42/arche/compare/v0.4.4...v0.4.5)
-
-### Features
-
-* Adds memory per entity to archetype stats (#124)
-
-### Other
-
-* Adds benchmarks of Arche vs. Array of Structs (AoS) and Array of Pointers (AoP), for different memory per entity and number of entities (#123)
-
-## [[v0.4.4]](https://github.com/mlange-42/arche/compare/v0.4.3...v0.4.4)
-
-### Features
-
-* `Query` has methods `Count()` and `Step(int)`, primarily for effective random sampling (#119)
-
-### Documentation
-
-* Adds example `random_sampling` to demonstrate usage of `Query.Count()` and `Query.Step(int)` (#119)
-
-### Bugfixes
-
-* `Query.Next`, `Query.Get`, etc. now always panic when called on a closed query (#117)
-
-### Other
-
-* Update to [go-gameengine-ecs](https://github.com/marioolofo/go-gameengine-ecs) v0.9.0 in benchmarks (#116)
-* Remove internal wrapper structs in generic queries and maps (#120)
-
-## [[v0.4.3]](https://github.com/mlange-42/arche/compare/v0.4.2...v0.4.3)
-
-### Bugfixes
-
-* `EntityEvent` has more consistent values when an entity is removed (#115)
- * `EntityEvent.NewMask` is zero
- * `EntityEvent.Removed` is contains all former components
- * `EntityEvent.Current` is `nil`
-
-## [[v0.4.2]](https://github.com/mlange-42/arche/compare/v0.4.1...v0.4.2)
-
-### Performance
-
-* Avoid creation of unused archetypes by splitting the archetype graph out of the actual archetypes (#113)
-* Use slice instead of fixed-size array for type lookup in component registry (#113)
-* Avoid copying `entityIndex` structs by using pointers (#114)
-
-## [[v0.4.1]](https://github.com/mlange-42/arche/compare/v0.4.0...v0.4.1)
-
-### Bugfixes
-
-* Fix units symbol for bytes from `b` to `B` in string formatting of world statistics (#111)
-
-### Other
-
-* Adds [github.com/wfranczyk/ento](https://github.com/wfranczyk/ento) to benchmarks (#110)
-
-## [[v0.4.0]](https://github.com/mlange-42/arche/compare/v0.3.1...v0.4.0)
-
-API revision, split out generics and filters into separate packages.
-
-### Features
-
-* Generic queries support optional, additional and excluded components (#53, #56, #58, #59, #60, #63)
-* Logic filters for complex queries (#54, #58, #61)
-* `Query` and `World` have a method `Mask(Entity)` to access archetype masks (#65)
-* Generic query `Get` method returns all queried components (#83)
-* Added method `World.Stats()` for inspecting otherwise inaccessible world statistics (#67)
-* Entities can be initialized with components, via ID as well as using generics (#76)
-* A listener function can be registered to the world, for notification on entity changes (#77)
-* Support for up to 128 distinct component types per world (was limited to 64 before) (#78)
-* Generic entity manipulation through types `Map1`, `Map2`, ... and `Exchange` (#79, #84, #87)
-
-### Performance
-
-* Generic queries are compiled to masks and cached on first build (#62)
-* Optimization of adding/removing components, with 2-3x speedup and vast reduction of (number of) allocations (#93)
-* Speed up component world access by use of nil pointer check instead of bitmask (#96)
-
-### Other
-
-* Overhaul of the module structure, with generics and filters in separate packages (#55, #57, #61, #64)
-* Boilerplate code for generic filters and queries is auto-generated with `go generate` (#64)
-* Ensure 100% test coverage by adding a CI check for it (#68)
-* `World.RemEntity(Entity)` is now `World.RemoveEntity(Entity)` (#87)
-* More examples as user documentation (#83, #95)
-* General API cleanup with renaming of several types and methods (#100)
-
-## [[v0.3.1]](https://github.com/mlange-42/arche/compare/v0.3.0...v0.3.1)
-
-### Other
-
-* Fix failing https://pkg.go.dev to fetch Arche version v0.3.0
-
-## [[v0.3.0]](https://github.com/mlange-42/arche/compare/v0.2.0...v0.3.0)
-
-### Features
-
-* Added a layer of generic access as alternative for using component IDs, for type safety and ergonomics (#47, #48)
- * Generic queries like `Query1[T]`, `Query2[T, U]`, ... (#47)
- * Generic add, assign and remove (`Add[T]()`, `Add2[T, U](), ...`) (#47)
- * Generic get, has, and set through component mapper `Map[T]` (#47)
-
-### Performance
-
-* Use of an archetype graph to speed up finding the target archetype for component addition/removal (#42)
-* Minor optimization of component access by queries (#50)
-
-### Other
-
-* Reduced dependencies by moving profiling and benchmarking to sub-modules (#46)
-* Smaller integer type for component identifiers (#47)
-
-## [[v0.2.0]](https://github.com/mlange-42/arche/compare/v0.1.4...v0.2.0)
-
-### Features
-
-* `World` has method `Exchange` to add and remove components in one go (#38)
-* `World` has method `Assign` add and assign components in one go (#38)
-* `World` has method `AssignN` add and assign multiple components in one go (#38)
-
-### Performance
-
-* Optimization of `Query` iteration, avoids allocations and makes it approx. 30% faster (#35)
-* Much smaller archetype data structure at the cost of one more index lookup (#37)
-
-### Other
-
-* Removed method `Query.Count()`, as it was a by-product of the allocations in the above point (#35)
-* Archetypes are stored in a paged collection to use more efficient access by pointers (#36)
-
-## [[v0.1.4]](https://github.com/mlange-42/arche/compare/v0.1.3...v0.1.4)
-
-### Documentation
-
-* Extended and improved documentation (#34)
-
-## [[v0.1.3]](https://github.com/mlange-42/arche/compare/v0.1.2...v0.1.3)
-
-### Features
-
-* Add `Config` to allow for configuration of the world (currently only storage capacity increment) (#28)
-* `Query` has a method `Count()`, reporting the total number of matching entities (#30)
-
-## [[v0.1.2]](https://github.com/mlange-42/arche/compare/v0.1.1...v0.1.2)
-
-### Other
-
-* Use aligned item size in component storage for faster query iteration (#25)
-* Queries lock the World, and automatically unlock it after iteration (#26)
-
-## [[v0.1.1]](https://github.com/mlange-42/arche/compare/v0.1.0...v0.1.1)
-
-### Other
-
-* Avoid allocation in `World.Has(entity, compID)` (#16)
-* `World.RemEntity(entity)` panics on dead entity, like all other `World` methods (#18)
-* Reserve zero value `Entity` to serve as nil/undefined value (#23)
-
-## [[v0.1.0]](https://github.com/mlange-42/arche/tree/v0.1.0)
-
-Initial release.
-
-Basic ECS implementation.
+{{% include file="/background/_changelog.md" %}}
diff --git a/docs/content/background/design.md b/docs/content/background/design.md
index 396dd820..148299b1 100644
--- a/docs/content/background/design.md
+++ b/docs/content/background/design.md
@@ -37,7 +37,7 @@ This may not seem idiomatic for Go.
However, explicit error handling in performance hotspots is not an option.
Neither is silent failure, given the scientific background.
-### Other limitations
+### Limitations
* The number of component types per `World` is limited to 256. This is mainly a performance decision.
* The number of entities alive at any one time is limited to just under 5 billion (`uint32` ID).
diff --git a/docs/content/user-guide/_index.md b/docs/content/user-guide/_index.md
index 0dde3a18..dd831f8b 100644
--- a/docs/content/user-guide/_index.md
+++ b/docs/content/user-guide/_index.md
@@ -8,7 +8,13 @@ description = 'Comprehensive Arche user guide.'
Arche's user guide.
+## Usage
+The following chapters are designed to be read sequentially in the presented order.
+If you are familiar with ECS and know what you are looking for,
+you may also just look it up or use the search.
+If you are not familiar with the Entity Component System (ECS) concept,
+take a look at the great [**ECS FAQ**](https://github.com/SanderMertens/ecs-faq) by Sander Mertens, the author of the [Flecs](http://flecs.dev) ECS.
{{< notice style="blue" icon="lightbulb" title="Tip" >}}
Inline code referencing parts of Arche's API is linked to the API reference, like here: {{< api ecs World >}}.
diff --git a/docs/content/user-guide/filters/filters_test.go b/docs/content/user-guide/filters/filters_test.go
index 52b137f4..0b7e37b6 100644
--- a/docs/content/user-guide/filters/filters_test.go
+++ b/docs/content/user-guide/filters/filters_test.go
@@ -115,14 +115,20 @@ func TestLogicFilters(t *testing.T) {
velID := ecs.ComponentID[Velocity](&world)
headID := ecs.ComponentID[Heading](&world)
- // Either Position and Velocity, or Position and Heading
+ // Either Position and Velocity, or Position and Heading.
_ = filter.OR{
L: ecs.All(posID, velID),
R: ecs.All(posID, headID),
}
- // Missing any of Position or Velocity
- _ = filter.AnyNOT(ecs.All(posID, velID))
+ // Same as above, expressed with a different logic.
+ _ = filter.AND{
+ L: ecs.All(posID),
+ R: filter.Any(velID, headID),
+ }
+
+ // Missing any of Position or Velocity.
+ _ = filter.AnyNot(posID, velID)
}
func TestRegister(t *testing.T) {
diff --git a/docs/hugo.toml b/docs/hugo.toml
index c3a4e2f0..a1d07ee6 100644
--- a/docs/hugo.toml
+++ b/docs/hugo.toml
@@ -36,7 +36,7 @@ disableInlineCopyToClipBoard = true
[[menu.shortcuts]]
name = " GitHub repo"
-identifier = "ds"
+identifier = "repo"
url = "https://github.com/mlange-42/arche"
weight = 10
@@ -46,6 +46,12 @@ identifier = "hugodoc"
url = "https://pkg.go.dev/github.com/mlange-42/arche"
weight = 20
+[[menu.shortcuts]]
+name = " Web demo"
+identifier = "demo"
+url = "https://mlange-42.github.io/arche-demo/"
+weight = 30
+
[markup]
[markup.highlight]
lineNumbersInTable = false
diff --git a/ecs/doc.go b/ecs/doc.go
index 600c66f2..b4eac1d1 100644
--- a/ecs/doc.go
+++ b/ecs/doc.go
@@ -2,6 +2,8 @@
//
// See the top-level module [github.com/mlange-42/arche] for an overview.
//
+// 🕮 Also read the Arche's [User Guide]!
+//
// # Outline
//
// - [World] provides most of the basic functionality,
@@ -64,4 +66,6 @@
// Usage:
//
// go build -tags tiny .
+//
+// [User Guide]: https://mlange-42.github.io/arche/
package ecs
diff --git a/filter/doc.go b/filter/doc.go
index f5539967..7aefbaa5 100644
--- a/filter/doc.go
+++ b/filter/doc.go
@@ -2,6 +2,8 @@
//
// See the top level module [github.com/mlange-42/arche] for an overview.
//
+// 🕮 Also read the Arche's [User Guide]!
+//
// # Outline
//
// - [All] creates a basic filter for components.
@@ -13,4 +15,6 @@
//
// All filters that wrap other filters ([AND], [OR], [XOR], [NOT]) ignore potential relation targets
// of any wrapped ecs.RelationFilter (see [github.com/mlange-42/arche/ecs.RelationFilter]).
+//
+// [User Guide]: https://mlange-42.github.io/arche/
package filter
diff --git a/generic/doc.go b/generic/doc.go
index 3b9fb8f4..3735429d 100644
--- a/generic/doc.go
+++ b/generic/doc.go
@@ -2,6 +2,8 @@
//
// See the top level module [github.com/mlange-42/arche] for an overview.
//
+// 🕮 Also read the Arche's [User Guide]!
+//
// # Outline
//
// - [Filter0], [Filter1], etc. provide generic filters and query generation using [Filter0.Query] and friends.
@@ -33,4 +35,6 @@
// - Remove components: [Map2.RemoveBatch], [Map2.RemoveBatchQ]
// - Exchange components: [Exchange.ExchangeBatch]
// - Change entity relation target: [Map.SetRelationBatch], [Map.SetRelationBatchQ]
+//
+// [User Guide]: https://mlange-42.github.io/arche/
package generic
diff --git a/listener/doc.go b/listener/doc.go
index eda5b368..577115ea 100644
--- a/listener/doc.go
+++ b/listener/doc.go
@@ -1,4 +1,8 @@
// Package listener provides ecs.Listener implementations (see [github.com/mlange-42/arche/ecs.Listener]).
//
// See the top level module [github.com/mlange-42/arche] for an overview.
+//
+// 🕮 Also read the Arche's [User Guide]!
+//
+// [User Guide]: https://mlange-42.github.io/arche/
package listener