Hook, Atom, and Storage

3    22 Jun 2016 17:33 by u/psioniq

I've been toying around with [MFM](http://www.movablefeastmachine.org/) the last few days, because I find the concept really fascinating.

I normally do game programming in Unity3D, and figured I'd try to write a MFM that could hook into Unity.

Sounds simple enough, but there is a downside to using Unity for this. Unity works off of components and gameobjects. To access an instance of a component, you must create a gameobject that has the instance attached to it - also, these can only run on the main thread.

This of course is a problem for large datasets, and I would never use gameobjects/components for that anyway. But I need a hook.

Unity is awesome for a lot of things - one of them being that you can create 'prefabs' that look/act in certain ways when you spawn them. I want to use this prefab feature to create templates of my Atoms in the MFM.

But since the components cannot live in any other thread than the main thread, I have to load the instructions from the prefabs when the application loads.

Instructions are then loaded into the atom when it is created. An instruction can be as simple as "Move one tile in a random direction", and Atoms can have multiple instructions. The instructions are simply a class that inherits DCInstructions which has a Command action.

~~~ public class DCInstruction : MonoBehaviour { public List Properties; public DCEventHandler Command;

public virtual void Load() { } } ~~~ *You'll notice there is a "Properties" field too, but we'll get back to that.*

A full instruction might look something like this: ~~~ public class DCMover : DCInstruction { public override void Load() { base.Load();

Command = (s, a) => { DCCoord targetCoord = DCHelper.GetRandomDirection(a.Node.Coord);

if (DCCore.GetNode(targetCoord) == null) { DCCore.MoveNode(a.Node, targetCoord); } }; } } ~~~

This is all well and good. It works, and things do what they need to. But here's the thing.

If I were to use components only, I could simply access a property in an instruction by doing: ~~~ gameObject.GetComponent().myFloatProperty = 1.0f; ~~~ But as mentioned, that requires that the object actually exists in the Unity gameworld.

When doing it the way I'm doing, I can't access any properties on the component, because the actual component is not unique - so if I change the component property value on one Atom, it'll reflect onto all the others that are using the same instruction component.

I've tried using a Dictionary to create a form of internal propertylist for the Atoms, but it is incredibly slow when you get a couple thousand atoms going. It's obviously not the right way to do it, as you could end up overriding some property that another instruction uses.

An instruction that uses Properties: ~~~ public class DCImp : DCInstruction { public float consumeChance;

public override void Load() { base.Load();

Command = (s, a) => { DCNode node = a.Node; DCCoord targetCoord = DCHelper.GetRandomDirection(node.Coord); DCNode targetNode = DCCore.GetNode(targetCoord);

float energy = node.GetPropertyValue("energy");

if (energy <= 0) { DCCore.RemoveNode(node); } else if (targetNode == null) { if (energy >= 1) { DCCore.CreateNode(node.Template, targetCoord); node.AddPropertyValue("energy", -0.5f); } else { DCCore.MoveNode(node, targetCoord); node.AddPropertyValue("energy", -0.01f); } } else { if (targetNode.GetInstruction()) { DCCore.RemoveNode(targetNode); node.AddPropertyValue("energy", 1); } } } } } ~~~

Currently, Properties is a Dictionary, and I'm using TryGetValue when doing a lookup - but it's still slow.

So, how would you go about storing the properties of an instruction in an Atom, that'll give fast read/write access? Can the dictionary be optimized further, to shorten the lookup time (different key than string), and if so, how would you identify that key when needed?

Or do I need some sort of DB structure to better handle all this - or would that be just as slow as individual dictionary lookups?

Thanks in advance :)

0 comments

No comments archived.