Saturday, November 4, 2017

Zay-es and "Blueprints"

One of my favorite libraries for jmonkey is Zay-es entity system. Zay-es is a powerful entity-component system that really forces you to consider an entity-component system from a very "pure" perspective. This is really great for rapid prototyping as I have built up a collection of components that are very easy to drag and drop from project to project. The only thing I really need to change are the underlying systems.

That said, entity-component systems to have their shortcomings. One problem I have been trying to find a good solution to is saving and loading entities. Zay-es has a way to do this, though from what I've read it's focused more on saving/loading the entire system as opposed to a single entity. I am interested in saving/loading a "blueprint" of an entity, much like Unity's prefabs. In the past I have used factory type builders to get an entity when I needed to spawn many similar objects, such as bullets or enemies.

Today I figured out a way to achieve this using json files! I came up with a simple way to use Gson to read and write easy to read files with all the components you would like attached to an entity. These files are simple text files so modifying them outside an ide is simple. Here's an example file for you :


com.mru.lib.scene.TransformComponent
{"position":{"x":0.0,"y":1.0,"z":0.0},"scale":{"x":1.0,"y":1.0,"z":1.0},"rotation":{"x":0.0,"y":0.0,"z":0.0,"w":1.0}}
com.mru.lib.scene.ChildComponent
{"parent":{"id":1},"offset":{"x":0.0,"y":1.0,"z":0.0},"scale":{"x":1.0,"y":1.0,"z":1.0},"rot":{"x":0.0,"y":0.0,"z":0.0,"w":1.0}}
com.mru.lib.scene.ModelAssetComponent
{"key":{"name":"models/MG.j3o"}}


My simple Gson parser assumes that every component is preceded by the class path. This is read using a buffered reader and the class is located. After a class is located the reader will read the next line using Gson which will instantiate the component.

The read/write commands are held within an "Entity Blueprint" class, which is basically just a set of components and the read/write commands to parse the files. During run time the blueprints can be used to quickly set components of entities as they are created.

In the example above you will notice a "child component". This is an example of the pitfalls to my system. Any component that references another entity (id:1) will not work after loading. There is no way I can guarantee entity's id's at runtime. For now I can design around this by not making blueprints of entities that rely on such components, but in the future this is a problem I will need to address.


No comments:

Post a Comment