DistributedEcs
DistributedEcs is an Entity-Component-Systems framework in Elixir. It is based on Ecstatic from https://github.com/Trevoke/ecstatic by Aldric Giacomoni.
Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed by adding `DistributedEcs` to your list of dependencies in `mix.exs`:
def deps do
[{:DistributedEcs, "~> 0.1.0"}]
endDocumentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) and published on [HexDocs](https://hexdocs.pm). Once published, the docs can be found at [https://hexdocs.pm/DistributedEcs](https://hexdocs.pm/DistributedEcs).
Vocabulary
Here's a list of DistributedEcs words; following will be an example sentence in English where we can connect each word to something meaningful for you.
Component: a collection of propertiesEntity: a collection of componentsAspect: a filter for entities, based on which components are and aren't on that entitySystem: business logic; receives an entity and will do some work on it if the entity matches a given aspect.Watcher: A hook that connects to a lifecycle event and will call a system if a particular predicate is matched.
So if Zaphod is a 33-year-old alien who doesn't have tendonitis and plays tennis, then his stamina will go down but he won't hurt after the game.
This could be written as (for example): There's an entity that has a "social component" with a name of "Zaphod", a "race component" with a name of "alien", and who does not have the "tendonitis component". When taken through the TennisGame "system", the entity's "physical component" will see its stamina reduced. A "watcher" will check for "physical components" with a stamina going down and pass those to a HealthSystem; if the entity matches the "aspect" of "has tendonitis component", it will add a "pain component" to the entity.
Code samples
defmodule Human do
use DistributedEcs.Entity
@default_components [Age, Mortal]
end
defmodule Age do
use DistributedEcs.Component
@default_value %{age: 1, life_expectancy: 80}
end
defmodule Mortal do
use DistributedEcs.Component
@default_value %{mortal: true}
end
defmodule AgeSystem do
use DistributedEcs.System
def aspect, do: %DistributedEcs.Aspect{with: [Age]}
def dispatch(entity) do
age_comp = Entity.find_component(entity, Age)
new_age_comp = %{age_comp | age: age_comp.age + 1}
%DistributedEcs.Changes{updated: [new_age_comp]}
end
end
defmodule DeathOfOldAgeSystem do
use DistributedEcs.System
def aspect, do: %DistributedEcs.Aspect{with: [Age, Mortal]}
def dispatch(entity) do
if Enum.rand(10_000) > 7000 do
%DistributedEcs.Changes{attached: [Dead]}
else
%DistributedEcs.Changes{}
end
end
end
defmodule Watchers do
use DistributedEcs.Watcher
watch_component Age, run: AgeSystem, every: 6_000
watch_component Age, run: DeathOfOldAgeSystem, when: fn(_pre, post) -> post.age > post.life_expectancy end
endTODO
-
Stop using the
Etsstore, rely on the generic one