demiurge 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 16771a3630ea74f9412194ba68ec9ebc5181380c
4
+ data.tar.gz: 7bd716fe644a7be1e32bd49ab0d39d4cc66a0e97
5
+ SHA512:
6
+ metadata.gz: b10caf567ea6f50864c594e22ac16708407e325ec72a543ec403a7439ede2c512c82f6bb383dc019ba343cd71dbd131fdc87b99a4a5108be7e3c7dc2fd6bac62
7
+ data.tar.gz: 4ec6595a79d26d53fb40c04725820239b434195b3979583f589a0615d07339cf104680b62cb5669bdb3851b2588f560a9d7b3f39a3fa6f97d152eac4a33c6226
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.14.6
data/.yardopts ADDED
@@ -0,0 +1,5 @@
1
+ --readme README.md
2
+ --title 'Demiurge API Documentation'
3
+ --charset utf-8
4
+ --markup markdown
5
+ 'lib/**/*.rb' - '*.md'
data/AUTHORS.txt ADDED
@@ -0,0 +1,6 @@
1
+ The core Demiurge engine tries to use only CC0-licensed content -- in
2
+ effect, public domain. But it's nice to credit people when they make
3
+ things for you. In that spirit:
4
+
5
+ Thanks to Jurkan, author of collision.png, a simple CC0-licensed collision-layer tileset.
6
+ Thanks to Hyptosis of lorestrome.com for CC0-licensed content including portraits and MageCity tilesets.
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at the.codefolio.guy@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/CONCEPTS.md ADDED
@@ -0,0 +1,271 @@
1
+ # Demiurge Simulated Worlds
2
+
3
+ Demiurge is a great way to prototype and develop an interesting
4
+ simulated world. It's intended to be flexible, powerful and easy to
5
+ tie into other systems.
6
+
7
+ Let's talk about the components of a Demiurge world and what they do.
8
+
9
+ ## Engines, State, Ticks
10
+
11
+ A single Demiurge simulation is called an Engine. It can be loaded
12
+ from World Files and state.
13
+
14
+ World Files determine the behavior of the world - what kinds of
15
+ entities does the world contain? How do they act? What are the rules
16
+ of physics that define that world?
17
+
18
+ State determines the current situation of that world. If your world
19
+ physics allows any number of rabbits in a particular field, how many
20
+ are there right now and where are they?
21
+
22
+ A single step of simulation is called a "tick", like the ticking of a
23
+ clock.
24
+
25
+ The world "entity" for a thing in the world is fairly vague. It may
26
+ refer to an "item", a "creature", an "area" (another vague word) or
27
+ something else. An entity is "a thing or things in the world" rather
28
+ than one specific abstraction that Demiurge defines. Entities
29
+ generally can act and be acted on, can pick things up and be picked
30
+ up, can take place in a location or be that location. In general, a
31
+ single individual entity will only do a few of those things, though.
32
+
33
+ ## Intentions, Actions and Events
34
+
35
+ A world may contain unchanging things, usually represented as
36
+ rules. It may contain changeable and movable items. And it may contain
37
+ items or creatures that act on their own. Demiurge can distinguish
38
+ between these categories, but it usually does so by distinguishing
39
+ between "rules" and "state" rather than between "intelligent" and
40
+ "unintelligent." Intelligence is mostly a matter of how complex the
41
+ rules are, and what objects they tend to affect.
42
+
43
+ A Demiurge Engine normally moves forward in discrete steps. The
44
+ current state is examined to create a list of Intentions, which do not
45
+ (yet) change state. The Intentions are then resolved into
46
+ notifications and state changes. One full state/intention/event cycle
47
+ is a tick.
48
+
49
+ Demiurge doesn't require that ticks occur at particular times
50
+ according to a real-world clock. You might choose to create entities
51
+ and rules that care about a real-world clock, but Demiurge doesn't
52
+ care. Ticks can be evenly spaced or not, as long as your entities'
53
+ rules reflect that.
54
+
55
+ ## State Items, and the Difference Between Rules and State
56
+
57
+ Rules exist entirely within World Files and the Demiurge framework
58
+ itself. The effects of rules can change according to current state,
59
+ but the rules themselves are in the World Files and do not depend on
60
+ state.
61
+
62
+ State in Demiurge must be serializable as JSON. That gives a
63
+ combination of numbers, strings, true/false/undefined special values,
64
+ lists and objects (dictionaries/hashes) as the set of all state
65
+ data. Each State Item gets a chunk of state and manages its own
66
+ rules. Each State Item's item name must be unique. There may be lots
67
+ of a particular *kind* of state item, but each one gets its own unique
68
+ name and its own chunk of state.
69
+
70
+ A "State Item" applies rules to state. As a programmatic object, it
71
+ can apply its rules (which are fixed) to its state (which can change
72
+ at any time).
73
+
74
+ This abstraction makes it easy to consider hypotheticals -- to ask,
75
+ "if the state were different in this way, how would that change the
76
+ world?"
77
+
78
+ ## Item Naming and Instances
79
+
80
+ A Demiurge entity (including Zones, Locations, Agents and many others)
81
+ must have a single, fully unique name within a given Engine. In World
82
+ Files, normally a human has to declare the name and that name needs to
83
+ be unique.
84
+
85
+ Names have a few restrictions. You can use alphanumeric characters
86
+ (letters and numbers, including Unicode letters and numbers) along
87
+ with spaces, dashes and underscores in the names. But other
88
+ punctuation including quotes, hash signs, dollar signs and so on
89
+ aren't permitted. These names are used internally as unique
90
+ identifiers and you don't need to worry about showing them to humans,
91
+ so don't worry about not being able to put punctuation you care about
92
+ in the names. The names are case-sensitive -- that is, "Bobo" and
93
+ "boBo" are completely different items because an upper-case and
94
+ lower-case letter count as different from each other.
95
+
96
+ Certain items, such as Zones in World Files may be reopened by
97
+ declaring another item (e.g. another Zone) with the same name. But if
98
+ so, they aren't two different Zones with the same name. Instead, the
99
+ files declare a single Zone across multiple files. That's perfectly
100
+ legal, just as you may declare a room in one World File while
101
+ declaring creatures and items inside it in another World File. But
102
+ it's all a single room, even if it's declared in multiple places for
103
+ human convenience. If you're used to programming with Ruby classes,
104
+ this idea of "reopening" the same zone in a new file will probably
105
+ seem very familiar.
106
+
107
+ Sometimes you want to declare an object and then have a lot of
108
+ them. Something like a wooden spoon, a low-level slime monster or a
109
+ player body object may get just one declaration in the World Files for
110
+ a lot of individual objects in the world. Differences in state or
111
+ appearance can add variation where you need it without requiring
112
+ giant, bloated World Files with fifteen identical slime monsters that
113
+ just have a "7" or a "12" after their name.
114
+
115
+ There are a few kinds of special punctuation in names and name-like
116
+ things that Demiurge may use for itself. For instance, a Position (see
117
+ later in this file) is a location's item name followed by a pound sign
118
+ and then some additional information, such as
119
+ "my\_room#25,71". Certain special objects and other things in Demiurge
120
+ can use other punctuation (e.g. colon or dollar-sign), but these
121
+ shouldn't occur in human-named objects in World Files.
122
+
123
+ ## Events and State Changes
124
+
125
+ Often an Intention turns into a change of state. For example, an item
126
+ is picked up, or a person moves from one location to another. When
127
+ that occurs, there may also be one or more notifications. The state
128
+ change is what it sounds like - if a person moves from one place to
129
+ another, their "location" is part of their state, and it's different
130
+ after the tick than it was before.
131
+
132
+ A Notification doesn't necessarily involve a change of state, though
133
+ the two will often happen together. The Notification doesn't cause the
134
+ state change, though it may be the result of one. A Notification is
135
+ simply a discrete that can be perceived in the world. A continuous,
136
+ ongoing event is state, not a Notification, though if it begins, ends
137
+ or changes significantly it may *cause* a Notification.
138
+
139
+ If a person moves from one room to another, their location changes and
140
+ so their state changes. There is also likely to be a Notification
141
+ associated with it - a detectable, trackable event which can be
142
+ watched for by other reactive entities in the world.
143
+
144
+ A Notification doesn't have to involve a state change, though. For
145
+ instance, if a character looks around shiftily or grins momentarily,
146
+ that doesn't necessarily change any recorded part of their state. But
147
+ another character may watch for the Notification and if they detect
148
+ it, they may react to it.
149
+
150
+ ## The Cycle of a Tick
151
+
152
+ Initially, the state is effectively frozen - nothing should change
153
+ it. It may be literally kept immutable in the program, depending on
154
+ required efficiency.
155
+
156
+ For each tick, code runs to generate Intentions on the part of any
157
+ entities that can act. Anything that will change state or create a
158
+ Notification requires an Intention.
159
+
160
+ Then, in some order of precedence, these Intentions are resolved one
161
+ at a time.
162
+
163
+ First an Intention is "validated" - can it happen at all? If not, it
164
+ is discarded as impossible, undesirable or otherwise "not going to
165
+ happen" with no effects of any kind.
166
+
167
+ At this point, the state becomes changeable again. This may involve
168
+ unfreezing or copying.
169
+
170
+ Then an Intention is offered - other entities may attempt to block,
171
+ modify or otherwise interfere with what occurs. This may result in the
172
+ Intention being blocked as in the validation stage (another entity
173
+ effectively makes its result impossible, resulting in nothing
174
+ happening) or its effects may be modified and/or other effects may
175
+ immediately occur as a result.
176
+
177
+ As that process resolves, the Intention may modify state. It may also
178
+ send Notifications. In general, a Notification reflects a completed
179
+ operation and the receiver can only react, not change or block the
180
+ action. While a Notification allows the receiver to modify state, that
181
+ receiver should only modify its own state or send additional
182
+ Notifications - it should not take "instant reactions", which should
183
+ be resolved in the offer/modify/veto stage.
184
+
185
+ After all these Notifications have resolved, including any
186
+ Notifications raised in response to other Notifications, the tick
187
+ begins again with the new state, which may be frozen during the early
188
+ Intention phases.
189
+
190
+ ## Zones, Location and Position
191
+
192
+ Location in Demiurge starts with the Zone. A Zone is a top-level
193
+ entity that manages state and flow of execution roughly independently
194
+ of other zones.
195
+
196
+ Different Zones may have very different "physics" between them - a
197
+ Zone might be entirely text descriptions, while a different Zone is
198
+ managed entirely in 2D tile graphics, for instance and a third Zone
199
+ could be an HTML UI. It's possible to do that within a single Zone in
200
+ some cases, if the Zone's "physics" permit it, but such changes are
201
+ expected between Zones.
202
+
203
+ A Location within a Zone may have some difference, but needs to
204
+ cooperate effectively with the Zone and with other Locations
205
+ inside. In a 2D tile-based Zone, it may be important that Zone
206
+ pathfinding works across multiple Locations, for instance. In a
207
+ text-based Zone of mostly-independent locations, there may be a
208
+ notification system that allows events in adjacent rooms to be visible
209
+ in certain other rooms as text notifications.
210
+
211
+ In general, a Zone defines the top-level "physics" and the nature of
212
+ space and location within itself, and Locations coordinate to make
213
+ that happen. Technically Locations are optional - it's possible for a
214
+ Zone to skip Locations entirely. But ordinarily there is some form of
215
+ subdivision.
216
+
217
+ Locations are also allowed to contain other Locations, and may do so
218
+ or not depending on the nature of their Zone.
219
+
220
+ When one asks for an entity's "location", one may mean "what entity
221
+ inside a Zone is it contained in?" However, there is not always a
222
+ well-defined answer to that question. For instance, an "infinite
223
+ space" Zone with no sub-locations that handles all object interactions
224
+ directly may not have "Location" sub-objects within itself at
225
+ all. What "location" is somebody at within the Zone? The Demiurge
226
+ entity in question is just the Zone, since there are no smaller
227
+ Location entities within it.
228
+
229
+ And within a Location, an entity may occupy different positions. In a
230
+ box of 3D space or a 2D tile map or a MUD-style room with objects
231
+ inside, a given entity may be at "x: 27.4, y:-1547.2, z: 297.0" or "x:
232
+ 27, y: 5" or "next to the gray lamp."
233
+
234
+ The Demiurge class "Demiurge::Location" is basically advisory -
235
+ locations within a Zone aren't required to belong to that class, may
236
+ be part of a tree of different location objects or may not exist at
237
+ all.
238
+
239
+ As a result, a "location" in Demiurge is about author intention, not
240
+ really about what Demiurge does with the object in question. The Zone
241
+ defines what being a location means, and it may vary widely from Zone
242
+ to Zone.
243
+
244
+ But then, how does one specify? With a Position.
245
+
246
+ A Position is given relative to a Zone or an object inside the Zone,
247
+ such as a Location (if one exists.) It is of the form
248
+ "item\_name#coordinates" where "item\_name" is a canonical
249
+ Demiurge item name, instanced or non-instanced. The coordinates may be
250
+ in a form appropriate to their zone such as "7,25" or
251
+ "29.45/81.6/Kappa" or "left\_of/gray\_greasy\_lamp". The coordinates
252
+ should not contain a pound-sign, a dollar sign or other characters
253
+ that aren't legal in a Demiurge item name.
254
+
255
+ ## The Admin Zone and Positionless Actions
256
+
257
+ Sometimes, a thing happens that doesn't belong in any specific game
258
+ zone. A player might fail to create a new account - what zone would
259
+ that belong in? An admin might reload the whole world, which isn't
260
+ specific to any one zone. An error might occur that can't be traced to
261
+ any specific zone.
262
+
263
+ When that happens, a special zone name, "admin", is used. There cannot
264
+ be an "admin" zone in a world file. Instead, "admin" is the name of an
265
+ automatic InertStateItem which holds system information like how many
266
+ total ticks have passed in the world, and the current notification_id
267
+ and intention_id for queueing.
268
+
269
+ Positionless occurrences like the examples above (e.g. account
270
+ creation failures) will appear to occur in this nonexistent "admin"
271
+ zone.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in demiurge.gemspec
4
+ gemspec
data/HACKING.md ADDED
@@ -0,0 +1,34 @@
1
+ # Hacking Demiurge
2
+
3
+ When in doubt: read the source, tests and examples of course, just
4
+ like any other code.
5
+
6
+ ## State and JSON
7
+
8
+ Demiurge is architected in such a way that StateItems contain logic
9
+ about how to manipulate state. StateItems contain current state and
10
+ can calculate new Intentions and apply Actions.
11
+
12
+ State can be serialized and swapped out at any time, so StateItems
13
+ must be able to be disposable and replaceable. Since it's hard to
14
+ serialize a procedure as JSON, generally StateItems define actions in
15
+ their World Files or Ruby code, and the StateItem contains the names
16
+ of the actions. The actual Ruby procedures are either part of the
17
+ StateItem subclass Ruby code or they're stored as a proc in the engine
18
+ itself.
19
+
20
+ Similarly, serialized state data often contains item names rather than
21
+ actual items. Names are easily serialized and easily handled with a
22
+ minimum of fuss, while structures and code are both messy.
23
+
24
+ ## Zones and Top-Level State
25
+
26
+ If every StateItem was guaranteed a call every tick, simulation would
27
+ slow to a crawl very rapidly as the world expanded. Instead, certain
28
+ top-level StateItems called "zones" are guaranteed to be called every
29
+ tick and they decide how to manage the flow of execution to their
30
+ contents.
31
+
32
+ In general, a Zone manages whether to call various sub-items or
33
+ agents, or whether to only call them sometimes, or whether to quiesce
34
+ them completely.
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Noah Gibbs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,181 @@
1
+ # Demiurge
2
+
3
+ Demiurge is an experimental game state and simulation library.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'demiurge'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install demiurge
20
+
21
+ ## Usage
22
+
23
+ See test mini-games in the test directory. For more information, see
24
+ lib/demiurge/engine.rb.
25
+
26
+ For longer-term usage, Demiurge will normally be part of a larger
27
+ program. Its intent is to manage behavior and state for a game or
28
+ similar simulated world. In those cases, Demiurge will normally be
29
+ required as a gem by its application, using normal "require
30
+ 'demiurge'"-style declarations. You can see what that looks like by
31
+ examining test/example mini-worlds in the relevant Demiurge
32
+ directories.
33
+
34
+ If Demiurge is primarily managing a simulated world and you want to
35
+ view the results, you'll need a display library to make its output
36
+ visible. Currently that means Demiurge-CreateJS, which displays the
37
+ results in your browser as a simulated world.
38
+
39
+ Please note that it is very, very difficult to separate the specifics
40
+ of behavior from the specifics of output and display - entities simply
41
+ *behave* differently in a text-only world with generalized "locations"
42
+ than they do in a 2D grid or a 3D world with collisions. As a result,
43
+ even if your preferred method of output isn't as specific as "Unreal
44
+ Engine" or "browser game" or "MUD-style text game," your simulation is
45
+ going to have a strong "flavor" of whatever underlying physics you
46
+ select. There is no such thing as "just plain physics, with no strong
47
+ bias that changes the behavior of agents within it."
48
+
49
+ This README doesn't tell you everything about creating and simulating
50
+ a world with Demiurge. See CONCEPTS.md for an initial grounding in
51
+ those ideas.
52
+
53
+ ## Demiurge DSL (World Files)
54
+
55
+ Demiurge contains an optional Domain-Specific Language (also called a
56
+ "DSL") which can be used to specify your simulated world and its rules
57
+ and behaviors. The "test" directory contains some examples of these
58
+ files.
59
+
60
+ These DSLs may specify various sorts of locations and agents that roam
61
+ them - the idea is that the world files should specify enough details
62
+ to simulate the "world" fully, without containing too much additional
63
+ detail on how to supply the results. Since many formats tend to pack
64
+ this information together (e.g. TMX files contain layout and collision
65
+ data required for simulation, but also links to image files for
66
+ display) the Demiurge engine will often link to the display
67
+ information without using it. This permits a display layer on top of
68
+ Demiurge, such as Demiurge-CreateJS, to make use of the display
69
+ information alongside the simulation data.
70
+
71
+ ## Specific Technologies: 2D Tile Maps
72
+
73
+ Remember that "no such thing as just plain physics" bit above? As a
74
+ consequence, Demiurge contains support for specific, non-abstract
75
+ physics bits like "2d grid of defined terrains," also called a tilemap
76
+ or tiled terrain.
77
+
78
+ There are standards for tilemaps, such as TMX format and the Tiled map
79
+ editor (http://mapeditor.org). TMX support also, not coincidentally,
80
+ gives you a fairly rich source of existing media to use (e.g. The Mana
81
+ Project and Source of Tales.) Please be careful to appropriately
82
+ respect the licensing of this media, which requires an acknowledgement
83
+ to the original authors for your graphics and map files.
84
+
85
+ 2D tile-based media is rich enough to provide interesting simulation
86
+ and AI behaviors without being *so* interesting that your agent code
87
+ can't be in scripting languages and spends all its time doing
88
+ pathfinding, as would be the case with most open 3D environments.
89
+
90
+ ## Specific Technologies: Serializability and Immutability
91
+
92
+ One of the hard challenges in game- and world-based AI is how to make
93
+ it easy to create new content, primarily in the form of reactions and
94
+ behavior. Those reactions and behavior are most frequently expressed
95
+ as some form of code/scripts.
96
+
97
+ Reactions and behavior can take many forms. Two common ones are called
98
+ Intentions and Actions by Demiurge. An Intention is generated by an
99
+ artificial intelligence based on examining its current situation. For
100
+ instance, "I am hungry and I remember food in the next room, so I
101
+ intend to move in that direction." An Intention will examine the state
102
+ of the world, but will not normally change it.
103
+
104
+ An Action is normally the result of an Intention, and it applies that
105
+ intention to the simulated world. An Action will frequently change the
106
+ state of the world, such as by moving an agent within the world, or by
107
+ moving other non-agent items in the world (e.g. eating food, picking up a
108
+ stick, etc.) An Action may also frequently be thwarted (e.g. an item
109
+ is too heavy, food is not where it was suspected or remembered,
110
+ somebody has pushed their way into the hall ahead of you and you may
111
+ not pass.)
112
+
113
+ Immutable structures provide great verifiability and terrible
114
+ performance. The code snippets can generate a second, modified version
115
+ of each structure, but must copy nearly the entirety of it. You may be
116
+ certain that no old state is being modified in a sloppy way, and
117
+ memory usage and garbage collection time are both very high.
118
+
119
+ Mutable structures allow easy in-place modification for great
120
+ performance, but they're hard to lock down when mutability isn't
121
+ wanted (e.g. when verifying if an action is allowed to take place.)
122
+
123
+ Demiurge attempts to handle this by making the code immutable per run
124
+ of the world, and to store state data in sometimes-mutable
125
+ JSON-serializable structures.
126
+
127
+ It is assumed but only sometimes verified that when calculating
128
+ Intentions the state of the world isn't altered. It is assumed that
129
+ the behaviors are replicatable -- that random numbers generated from
130
+ seeds are used in a way that is replicatable from run to run, for
131
+ instance, or non-random behaviors reliably calculate the same
132
+ intention from the same preconditions.
133
+
134
+ This provides a compromise between full immutability (slow
135
+ performance, great verifiability) and full mutability (fast
136
+ performance, terrible verifiability) by switching back and forth
137
+ between them on demand.
138
+
139
+ ## Development
140
+
141
+ Demiurge is not yet ready for "pristine" production usage. It's not
142
+ yet ready for you to just drop it in and use it unchanged. For that
143
+ reason, assume you'll need to do some Demiurge development for
144
+ yourself, whether or not you ever contribute it upstream.
145
+
146
+ For more information on Demiurge's architecture, see the HACKING.md
147
+ document in this directory.
148
+
149
+ After checking out the repo, run `bin/setup` to install
150
+ dependencies. Then, run `rake test` to run the tests. You can also run
151
+ `bin/console` for an interactive prompt that will allow you to
152
+ experiment.
153
+
154
+ To install this gem onto your local machine, run `bundle exec rake
155
+ install`. To release a new version, update the version number in
156
+ `version.rb`, and then run `bundle exec rake release`, which will
157
+ create a git tag for the version, push git commits and tags, and push
158
+ the `.gem` file to [rubygems.org](https://rubygems.org).
159
+
160
+ ## Contributing
161
+
162
+ Bug reports and pull requests are welcome on GitHub at
163
+ https://github.com/noahgibbs/demiurge. This project is intended to be
164
+ a safe, welcoming space for collaboration, and contributors are
165
+ expected to adhere to the
166
+ [Contributor Covenant](http://contributor-covenant.org) code of
167
+ conduct. See CODE\_OF\_CONDUCT.md.
168
+
169
+ ## References, Influences and Sources of Media
170
+
171
+ * OpenGameArt and the Liberated Pixel Cup
172
+ * Source of Tales
173
+ * The Tiled Map Editor
174
+ * The Mana World - https://github.com/themanaworld
175
+ * The Mana Project
176
+ * Evol Online
177
+
178
+ ## License
179
+
180
+ The gem is available as open source under the terms of the
181
+ [MIT License](http://opensource.org/licenses/MIT).