Demiurge
Demiurge is an experimental game state and simulation library.
Installation
Add this line to your application's Gemfile:
gem 'demiurge'
And then execute:
$ bundle
Or install it yourself as:
$ gem install demiurge
Usage
See test mini-games in the test directory. For more information, see lib/demiurge/engine.rb.
For longer-term usage, Demiurge will normally be part of a larger program. Its intent is to manage behavior and state for a game or similar simulated world. In those cases, Demiurge will normally be required as a gem by its application, using normal "require 'demiurge'"-style declarations. You can see what that looks like by examining test/example mini-worlds in the relevant Demiurge directories.
If Demiurge is primarily managing a simulated world and you want to view the results, you'll need a display library to make its output visible. Currently that means Demiurge-CreateJS, which displays the results in your browser as a simulated world.
Please note that it is very, very difficult to separate the specifics of behavior from the specifics of output and display - entities simply behave differently in a text-only world with generalized "locations" than they do in a 2D grid or a 3D world with collisions. As a result, even if your preferred method of output isn't as specific as "Unreal Engine" or "browser game" or "MUD-style text game," your simulation is going to have a strong "flavor" of whatever underlying physics you select. There is no such thing as "just plain physics, with no strong bias that changes the behavior of agents within it."
This README doesn't tell you everything about creating and simulating a world with Demiurge. See CONCEPTS.md for an initial grounding in those ideas.
Demiurge DSL (World Files)
Demiurge contains an optional Domain-Specific Language (also called a "DSL") which can be used to specify your simulated world and its rules and behaviors. The "test" directory contains some examples of these files.
These DSLs may specify various sorts of locations and agents that roam them - the idea is that the world files should specify enough details to simulate the "world" fully, without containing too much additional detail on how to supply the results. Since many formats tend to pack this information together (e.g. TMX files contain layout and collision data required for simulation, but also links to image files for display) the Demiurge engine will often link to the display information without using it. This permits a display layer on top of Demiurge, such as Demiurge-CreateJS, to make use of the display information alongside the simulation data.
Specific Technologies: 2D Tile Maps
Remember that "no such thing as just plain physics" bit above? As a consequence, Demiurge contains support for specific, non-abstract physics bits like "2d grid of defined terrains," also called a tilemap or tiled terrain.
There are standards for tilemaps, such as TMX format and the Tiled map editor (http://mapeditor.org). TMX support also, not coincidentally, gives you a fairly rich source of existing media to use (e.g. The Mana Project and Source of Tales.) Please be careful to appropriately respect the licensing of this media, which requires an acknowledgement to the original authors for your graphics and map files.
2D tile-based media is rich enough to provide interesting simulation and AI behaviors without being so interesting that your agent code can't be in scripting languages and spends all its time doing pathfinding, as would be the case with most open 3D environments.
Specific Technologies: Serializability and Immutability
One of the hard challenges in game- and world-based AI is how to make it easy to create new content, primarily in the form of reactions and behavior. Those reactions and behavior are most frequently expressed as some form of code/scripts.
Reactions and behavior can take many forms. Two common ones are called Intentions and Actions by Demiurge. An Intention is generated by an artificial intelligence based on examining its current situation. For instance, "I am hungry and I remember food in the next room, so I intend to move in that direction." An Intention will examine the state of the world, but will not normally change it.
An Action is normally the result of an Intention, and it applies that intention to the simulated world. An Action will frequently change the state of the world, such as by moving an agent within the world, or by moving other non-agent items in the world (e.g. eating food, picking up a stick, etc.) An Action may also frequently be thwarted (e.g. an item is too heavy, food is not where it was suspected or remembered, somebody has pushed their way into the hall ahead of you and you may not pass.)
Immutable structures provide great verifiability and terrible performance. The code snippets can generate a second, modified version of each structure, but must copy nearly the entirety of it. You may be certain that no old state is being modified in a sloppy way, and memory usage and garbage collection time are both very high.
Mutable structures allow easy in-place modification for great performance, but they're hard to lock down when mutability isn't wanted (e.g. when verifying if an action is allowed to take place.)
Demiurge attempts to handle this by making the code immutable per run of the world, and to store state data in sometimes-mutable JSON-serializable structures.
It is assumed but only sometimes verified that when calculating Intentions the state of the world isn't altered. It is assumed that the behaviors are replicatable -- that random numbers generated from seeds are used in a way that is replicatable from run to run, for instance, or non-random behaviors reliably calculate the same intention from the same preconditions.
This provides a compromise between full immutability (slow performance, great verifiability) and full mutability (fast performance, terrible verifiability) by switching back and forth between them on demand.
Development
Demiurge is not yet ready for "pristine" production usage. It's not yet ready for you to just drop it in and use it unchanged. For that reason, assume you'll need to do some Demiurge development for yourself, whether or not you ever contribute it upstream.
For more information on Demiurge's architecture, see the HACKING.md document in this directory.
After checking out the repo, run bin/setup
to install
dependencies. Then, run rake test
to run the tests. You can also run
bin/console
for an interactive prompt that will allow you to
experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in
version.rb
, and then run bundle exec rake release
, which will
create a git tag for the version, push git commits and tags, and push
the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/noahgibbs/demiurge. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct. See CODE_OF_CONDUCT.md.
References, Influences and Sources of Media
- OpenGameArt and the Liberated Pixel Cup
- Source of Tales
- The Tiled Map Editor
- The Mana World - https://github.com/themanaworld
- The Mana Project
- Evol Online
License
The gem is available as open source under the terms of the MIT License.