Skip to content

Commit 506816e

Browse files
committed
doc: Restructure the game engine embedding infos.
1 parent 1b32a41 commit 506816e

File tree

3 files changed

+59
-70
lines changed

3 files changed

+59
-70
lines changed

doc/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,3 @@ A full specification is provided [here](nyan_specification.md).
8888
* Data does not contain any executable code but can specify function names
8989
and parameters. The game engine is responsible for calling those
9090
functions or redirecting to custom scripts
91-

doc/embedding.md

Lines changed: 59 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# Embedding nyan into a Game Engine
12

23
## nyan interpreter
34

@@ -11,70 +12,7 @@
1112
* All data history is stored over time
1213

1314

14-
### Database views
15-
16-
Problem: Different players and teams have different states of the same nyan tree.
17-
18-
Solution: Hierarchy of state views.
19-
20-
A `nyan::View` has a parent which is either the root database or another `nyan::View`.
21-
22-
The view then stores the state for e.g. a player.
23-
24-
What does that mean?
25-
26-
* You can create a view of the main database
27-
* You can create a view of a view
28-
* Querying values respects the view the query is executed in
29-
* If a patch is applied in a view, the data changes are applied in this view
30-
and all children of it. Parent view remain unaffected.
31-
32-
Querying data works like this:
33-
* `nyan::Object obj = view.get(object_name)`
34-
* The `nyan::Object` is just a handle which is then used for real queries
35-
* `obj.get(member_name, time)` will evaluates the member of the object at a give time
36-
* This returns the `nyan::Value` stored in the member at the given time.
37-
38-
Patching data works as follows:
39-
* Obtain a patch object from some view
40-
* `nyan::Object patch = view.get(patch_name);`
41-
* If it is known in the view, return it
42-
* Else return it from the parent view
43-
* Create a transaction with this Patch to change the view state at the desired time
44-
* `nyan::Transaction tx = view.new_transaction(time);`
45-
* Add one or more patch objects to the transaction
46-
* `tx.add(patch); tx.add(...);`
47-
* `tx.add(another_patch, view.get(target_object_name))` is used to patch a child of
48-
the patch target.
49-
* Commit the transaction
50-
* `bool success = tx.commit();`
51-
* This triggers, for each patch in the transaction:
52-
* Determine the patch target object name
53-
* If a custom patch target was requested,
54-
check if it was a child of the default patch target at loadtime.
55-
* Copy the patch target object in a (new) state at `time`
56-
* Query the view of the transaction at `time` for the target object, this may recursively query parent views
57-
* If there is no state at `time` in the view of the transaction, create a new state
58-
* Copy the target object into the state at `time` in the view of the transaction
59-
* Linearize the inheritance hierary to a list of patch objects
60-
* e.g. if we have a `SomePatch<TargetObj>()` and `AnotherPatch(SomePatch)` and we would like to apply `AnotherPatch`, this will result in `[SomePatch, AnotherPatch]`
61-
* Apply the list left to right and modify the copied target object
62-
* Notify child views that this patch was applied, perform the patch there as well
63-
64-
This approach allows different views of the database state and integrates with the
65-
patch idea so e.g. team boni and player specific updates can be handled in an "easy"
66-
way.
67-
68-
69-
### Embedding nyan
70-
71-
A mod API could be implemented as follows: Create a `nyan::Object` named `Mod`
72-
that has a member with a set of patches to apply. To add new data to the engine,
73-
inherit from this `Mod`-object and add patches to the set. This `Mod`-object is
74-
registered to the engine with a mod description file.
75-
76-
77-
#### Embedding in the engine
15+
## Embedding in the Engine Code
7816

7917
The mod API definitions in `engine.nyan` have to be designed exacly the way the
8018
C++ engine code is then using it. It sets up the type system so that the nyan
@@ -179,9 +117,65 @@ if (not research.commit()) { error("failed transaction"); }
179117
```
180118
181119
120+
### Database views
121+
122+
Problem: Different players and teams have different states of the same nyan tree.
123+
124+
Solution: Hierarchy of state views.
125+
126+
A `nyan::View` has a parent which is either the root database or another `nyan::View`.
127+
128+
The view then stores the state for e.g. a player.
129+
130+
What does that mean?
131+
132+
* You can create a view of the main database
133+
* You can create a view of a view
134+
* Querying values respects the view the query is executed in
135+
* If a patch is applied in a view, the data changes are applied in this view
136+
and all children of it. Parent view remain unaffected.
137+
138+
Querying data works like this:
139+
* `nyan::Object obj = view.get(object_name)`
140+
* The `nyan::Object` is just a handle which is then used for real queries
141+
* `obj.get(member_name, time)` will evaluates the member of the object at a give time
142+
* This returns the `nyan::Value` stored in the member at the given time.
143+
144+
Patching data works as follows:
145+
* Obtain a patch object from some view
146+
* `nyan::Object patch = view.get(patch_name);`
147+
* If it is known in the view, return it
148+
* Else return it from the parent view
149+
* Create a transaction with this Patch to change the view state at the desired time
150+
* `nyan::Transaction tx = view.new_transaction(time);`
151+
* Add one or more patch objects to the transaction
152+
* `tx.add(patch); tx.add(...);`
153+
* `tx.add(another_patch, view.get(target_object_name))` is used to patch a child of
154+
the patch target.
155+
* Commit the transaction
156+
* `bool success = tx.commit();`
157+
* This triggers, for each patch in the transaction:
158+
* Determine the patch target object name
159+
* If a custom patch target was requested,
160+
check if it was a child of the default patch target at loadtime.
161+
* Copy the patch target object in a (new) state at `time`
162+
* Query the view of the transaction at `time` for the target object, this may recursively query parent views
163+
* If there is no state at `time` in the view of the transaction, create a new state
164+
* Copy the target object into the state at `time` in the view of the transaction
165+
* Linearize the inheritance hierary to a list of patch objects
166+
* e.g. if we have a `SomePatch<TargetObj>()` and `AnotherPatch(SomePatch)` and we would like to apply `AnotherPatch`, this will result in `[SomePatch, AnotherPatch]`
167+
* Apply the list left to right and modify the copied target object
168+
* Notify child views that this patch was applied, perform the patch there as well
169+
170+
This approach allows different views of the database state and integrates with the
171+
patch idea so e.g. team boni and player specific updates can be handled in an "easy"
172+
way.
173+
174+
182175
#### API definition example
183176
184-
See openage
177+
openage uses an [ECS-style nyan API](https://github.com/SFTtech/openage/tree/master/doc/nyan/api_reference) for storing game data.
178+
185179
186180
### Creating a scripting API
187181
@@ -211,6 +205,3 @@ should be the annotated ones.
211205
212206
Nevertheless, `nyanc` is just an optimization, and has therefore no
213207
priority until we need it.
214-
215-
216-

doc/nyan_specification.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,4 +581,3 @@ the calculation is done like this:
581581
* `A` adds `5`, so `entry` is `12`
582582
* `LOLWhat` adds `1`, `entry` is `13`
583583
* `OHNoes` adds `1` as well, and `entry` is returned to be `14`
584-

0 commit comments

Comments
 (0)