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"}]
end

Documentation 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.

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
end

TODO

  1. Stop using the Ets store, rely on the generic one