@slick_kilmister/quest-classbased-objstructure-poc
v1.0.8
Published
small PoC creating the entire object-structure using ES6 classes and mapping parent-child relation with a costumised instace of the NodeJS path-module to create IPv6-like addresses and scopes.
Downloads
9
Readme
Proof of Concept for Rebasing the Core Object Structure on Prototype Inheritance
| Links | | |-------------------------------------------------------------|--------------------------| | Link toGitHub-RepoLink to GitHub-Pages | |
Main Features
- ES6-Class based Inheritance
- Two Basic Scripts Showcasing the PoC
- High Degree of Isolation on every Object making Code-Execution Predictable
- Use of JavaScript-native Proxys Implemented deep in the Core Code
- Fully Dynamic Object Generation Allowing Runtime Creation of Complete Games
- Fully Functional Address-Module able to Resolve both Absolute and Relative Addresses
- Simple UUID-Creation-Module and Global Index
- Basic Caching of Child-Objects allowing Fast Retrieval of Children
ES6-Class based Inheritance
A strict inheritance model to optimise runtime-execution and makes the program act
more predictable. Currently it consists of two branches inheriting from a single
Node. They are currently mostly representational but can easily be expanded
upon.
The two branches are: (names are subject to change)
World-Objects
Forming the Super-Structure of the world and grouping programmatic environments.
Game-Objects
Forming the manipulatable world
Two Basic Scripts Showcasing the PoC
They can be used by running bin/ex.js
and selecting the respective options when
prompted.
Unstructured
Soft benchmarking creating up to 20'000 objects representing a massive world. Number of objects is dictated by random number generation within an easily adjustable min-max. Depending on available resources i'm able to generate a world populated with 20k objects in between 0.5 and 2 seconds. both acceptable for production and 20k is massive and could easily be generated as needed or at first time setup.
Structured
Simple showcase of the addNewChild()
-method present on (as-of-now) every
object. Generates 32 objects in a few milliseconds
Both Tasks write the resulting Root-Object to a JSON
file (heavily shortened to
a depth of about 5).
The API is (albeit messy) fully exposed and ready to be experimented upon. This
PoC is also available as an NPM package that can can be downloaded and used as
a dependency.
npm install @slick_kilmister/quest-classbased-objstructure-poc
High Degree of Isolation on every Object helping against unpredictable Code-Execution
High degrees of isolation were a design focus. Objects know only basic
properties of the world around them. Every property escaping the objects scope
is handled by a super or the proxy
. This naturally cuts down on glitches and
while source code
gets more complex, it makes scripting simpler.
- eg. no complex scoping is necessary as objects visible from a game-logic standpoint (and only those) are also programmatically visible by default.
- this can be easily fine-tuned by selectively exposing/hiding objects from the local scope.
Use of JavaScript-native Proxys Implemented deep in the Core Code
The base-object-constructor
(and thus everything that inherits from it)
returns a Proxy
with a specialized handler object enveloping it.
The Proxy
serves three main purposes:
- The
Proxy
enables permission checking and pre/post-processing of data before it reaches the target object. - It can store information at an easy-to-access place while still isolating the actual object from it. eg. it can store the absolute address of an Object while still keeping it out of reach of the object itself and of those who can read the object.
- Being Native-
Code
, they are incredibly efficient and with some simpleboolean
-pre-triggers they cause close to zero additional processing time and (when correctly configured) are basically impossible to circumvent.
Case-and-Point: ALL objects in the example scripts are wrapped by aproxy
. And the design of the logging-to-console has more effect on execution speed than all theproxies
combined.
They are making source code
less intuitive, tho. but i think they are well worth
it.
Fully Dynamic Object Generation Allowing Runtime Creation of Complete Games
Using proper prototype
inheritance entire sections can be generated and
discarded on the fly with few lines of code
, making scripting much easier and
runtime smoother.
Fully Functional Address Module able to Resolve both Absolute and Relative Addresses
this PoC comes with a fully functional Address-module based on the NodeJS
path
-module. It currently features construction of the Absolute Address of an
Object and resolving of relative addresses by only giving it start- and
target-Object.
It is designed after IPv6, every parent acting as a DNS for its direct children.
Each parent assigns a in-scope-unique HEX-based ID to each of it's children at their
creation (or relocation). These are then joined by a :
giving an easy to read
and use address. eg: :0:4:1:2:50
(leading :
indicates the absolute root)
Relative addresses are prefixed with a letter representing the scope of the last
common ancestor. eg: A:1:207
(the capital A
indicating that both objects are
within the same area) this adds a layer of isolation as a local control-node
(like a room or container) does not need access or knowledge of its own
position to guide scoping within itself.
Addresses can be accessed by the .address
-getter/trap or
the .getRelativeAddress(target)
-method
Examples Pulled from the Showcase-Script
| represented by | ROOT | Realm | World | Area | room |
|----------------|----------------:|-----------------:|----------------:|---------------:|---------------:|
| leading- | :
| R
| W
| A
| r
|
| -----x------ | -------x------- | -------x-------- | -------x------- | -------x------ | -------x------ |
| from | :0:2:3:3:a8
| :0:2:2:1:22c
| :0:2:2:2:32e
| :0:2:2:4:52
| :0:2:7:1:1d0
|
| to | :0:2:7:2:198
| :0:2:3:3:16e:0
| :0:2:2:4:1ff
| :0:2:9:1:362
| :0:2:a:2:335
|
| relative | W:7:2:198
| W:3:3:16e:0
| A:4:1ff
| W:9:1:362
| W:a:2:335
|
| -----x------ | -------x------- | -------x-------- | -------x------ | -------x------ | -------x------ |
| from | :0:2:2:1:372
| :0:2:2:4:24c
| :0:2:2:4:2c4
| :0:2:2:3:114
| :0:2:2:3:1bb
|
| to | :0:2:8:2:2a2
| :0:2:9:2:341
| :0:2:8:2:9f
| :0:2:a:1:36f
| :0:2:8:2:fb
|
| relative | W:8:2:2a2
| W:9:2:341
| W:8:2:9f
| W:a:1:36f
| W:8:2:fb
|
NOTE: smaller subdivisions currently all are lead by lower-case c
for container
Simple UUID-Creation-Module and Global Index
Every object is assigned a unique UUID at creation and is indexed with it.
contrary to the ID used in the Address-module, the object keeps this one
regardless of location and the UUID won't be given free at object destruction.
This is a simple way to guarantee persistance of object-connections. eg: lock
and key relation.
The UUID-Creator is simple and can be tweaked if necessary. Currently it
guarantees uniqueness and generates a HEX-base ID of 8+4+4
-digits.
eg: 4e71fff5-1757-1dc0
Basic Caching of Child-Objects allowing Fast Retrieval of Children
The ChildCache-Object allows for some basic caching. It's based on an
independent class outside the inheritance tree as a refracturing measure.
It works as a mixin of sort and is created when first needed. So objects without
any children don't try to start caching
It's not really supposed to be directly accessed but works as an extension of
the base-class. Its methods being mainly used by the parent object. and serving
as a Node to quickly easily connect (grand-)children to their respective
container.
It currently features some ultra basic caching working as a data-base for the
getters of the main Object. The caching is bare-bones and needs optimization,
but as-is it could already serve specific data to their matching getters.
It could keep the matching data ready to serve for various containers of an
object. eg: a table with a hidden compartment (separating on-top, and
compartment) or an (N-)PC inventory (separating held-, worn-, stored- etc. items).
This makes it easy for programmatic-logic to follow game-logic as it could
easily handle visibility, accessability or unlock-requirements within the parent object directly.