Simulation of a cosmos of eldritch beings trying to learn cooperation and social organization.
-
The
Cosmos
application is a work-in-progress implementation of an entity component system (ECS) which will power the simulation. -
The
Eldritch
library application is used to construct and interact with specific kinds of entities such asBeing
orNode
entity. -
The
Lofi
application is a simple cowboy and plug based server for interacting with the simulation.
- change the local persistance directory to use temporary one that will only exist during the life time of the Cosmos Application.
- User can create beings with a information incantation
- Entities push a message to user have the interval time has elapsed
The Cosmos
application can be started using
iex -S mix
This will start the various processes required to build entities, start systems, and begin a simulation.
To create a new being (a standard one with only default values for it's components)
curl -X POST http://localhost:5454/being
This will return something like
{"being_id": "2enp3IaLemeeiMDZYj3oJ0ukJ9U"}
which is the entity id for the being created. Now we can query for all existing beings with
curl -X GET http://localhost:5454/beings
and can get the full state of the being with
curl -X GET http://localhost:5454/being?id=2enp3IaLemeeiMDZYj3oJ0ukJ9U
Entities can be created using the a builder module.
For example, the Eldritch.Being.Builder
module can be used to create a
new being entity, with some of the standard attributes, use the build function
with argument {:new, :being, :standard}
. For example, after the Cosmos supervisor
has been started one can run
being_entity_id = Eldritch.Being.Builder.build({:new, :being, :standard}, %{"name" => "Gor'lop"})
to create and spawn an entity worker for a being entity named "Gor'lop". The being's
entity_id
is returned so that we can fetch it's worker process using
Cosmos.Entity.Cache.server_process(being_entity_id)
.
The build function called in this way adds the standard components for a being.
The second argument can overwrite the default values used to create the standard components of an entity.
Each entity is comprised of components each of which have a attribute system
whose
value is an atom corresponding to one of the implemented systems in the Cosmos ECS.
When adding or removing a component, the entity is subscribed or unsubscribed respectively
from the associated system. For example, in the previous section a being with standard
components whose name is "Gor'lop" was created. This being has the form:
%Cosmos.Entity{
id: "2NzPp7iRNFaaC10VMTpAgWvLxPK",
components: %{
1 => %Cosmos.Entity.Component{
name: "name",
system: :attribute,
value: "Gor'lop",
id: 1
},
2 => %Cosmos.Entity.Component{
name: "ichor",
system: :temporal_decay,
value: 100,
id: 2
},
3 => %Cosmos.Entity.Component{
name: "orichalcum",
system: :quantity,
value: 100,
id: 3
}
},
auto_component_id: 4
}
Since this being has a component with the :temporal_decay
system, it is subscribed
to that system and the value ichor
will decrease at a specified interval in time whenever
the :temporal_decay
system is turned on.
Systems are controlled by GenServers
(see Cosmos.System.TemporalDecay
for an example).
The GenServer that powers each system is started when the Cosmos application starts up,
but will not act on components of entities until being turned on.
Systems can be started or stopped using Cosmos.System.on/1
and Cosmos.System.off/1
where the argument is the system atom (e.g. :temporal_decay
).
- quantum is used for systems that need to be run at intervals of minutes or hours (such as full backups and health checks).
- cowboy
In the scripts
directory are some elixir scripts that we can use to run specific small scale situations.
These can be run by launching an iex
session then compiling the script file. For example, first
start the iex
session with
iex -S mix
then one can run the script with
iex> c "scripts/{path-to-script}.exs"
Launch the elixir REPL with
iex -S mix
Then run something like to make sure that database workers are behaving as expected.
iex(1)> Cosmos.Entity.Cache.start_link()
{:ok, #PID<0.215.0>}
iex(2)> server = Cosmos.Entity.Server.start_link("jorsa")
{:ok, #PID<0.221.0>}
iex(3)> {_, server} = server
{:ok, #PID<0.221.0>}
iex(4)> entity = Cosmos.Entity.Server.get(server)
%Cosmos.Entity{
id: "2MXHjNmnZAfLUZToIExXE5xrXiL",
components: %{},
auto_component_id: 1
}
iex(5)> comp = Cosmos.Entity.Component.new("name", :attribute, "johnson")
%Cosmos.Entity.Component{name: "name", system: :attribute, value: "johnson", id: nil}
iex(6)> Cosmos.Entity.Server.add_component(server, comp)
:ok
#PID<0.217.0> was chosen
Release names can be chosen from marquises from Ars Geotia