evox-a: a first implementation

Erwin Driessens
5 min readSep 23, 2022

--

In the beginning, space is empty. A grid of voxels, all with value 0, meaning ‘nothing here’. Something has to happen and the minimal action is to plant a ‘seed’ in this space. The simplest seed is a single ‘solid’ voxel: a position somewhere in the grid with value 1, meaning ‘cell of type 1 here’. There is just one such seed with size 1x1x1, which is ok in some cases, and problematic in others. Often a seed serves to create an initial condition for a generative process. Some generative processes are deterministic and then variation in the seeds is the only way to have variation in the final outcome. For processes that are not deterministic, using different seeds can give insight into possible pathways that development can take. Seeds are thus valuable experimental constructs and should be handled with care.

(read the previous article to understand the context of the following better: https://notnot.medium.com/how-to-evolve-processes-of-growth-ce2a089c1fc3)

To honour the ‘body is fully connected’ requirement at all times, the seed must be fully connected too, because everything starts from there. The seed is in fact the initial body, the body in its earliest embryonic state. A seed can’t just be a random bunch of voxels. There would probably be loose parts then.

See here some outputs of a seeding function that generates fully connected seeds, given a bounding box size and a fill factor. The algorithm works by first setting a random voxel in the bounding box, and then adding random adjacent voxels until the fill factor has been reached.

A few examples of valid seeds in a 2x2x2 bounding box, various fill factors.
A few examples of valid seeds in a 3x3x3 bounding box, various fill factors.
A few examples of valid seeds in a 4x4x4 bounding box, various fill factors.

Smaller seeds are simpler, which is an attractive feature of a seed. But there is obviously more variation in larger seeds. At this point it is impossible to make a choice: the seed size should thus be a hyperparameter in the model. The 3x3x3 seeds seem to be a good default.

Once a seed is set, the body-bots have to be positioned on the surface of the body. For now, only ‘adder’ bots will be used. These are bots that add cells to the existing body, and this type of bot will always be positioned in empty cells that are adjacent to the body. Testing will be done with 4 such bots. For the sake of simplicity, for now, multiple bots are allowed to be present in the same grid position. The initial number of body-bots will be a hyperparameter in the model. It makes sense to let the number of bots be dynamic, depending on the development of the body. It could also be interesting to implement ‘birth’ and ‘death’ of body bots, depending on the state of the system.

Screen grabs of seeds with initial body-bot positions (yellow dots).

Note that the random placement of the body-bots adds another layer to the initial conditions of the growth process, besides the seed configuration. Since both the seed and the bot positions are created using numbers from the random number generator, which is itself seeded before use, we can generally consider this random number generator seed to be the ‘base seed’ for all subsequent processing. Later on, when our application is more refined, there will be even more layers or dimensions in the initial configuration. Think of the body-bots each having different control programs, variations in the medium that surround and permeate the body, and possibly other factors.

Everything is now ready for the execution of the first timesteps! In each timestep of the model, all the body-bots will take turns, each taking their step and possibly modifying the body. Conceptually, all of the action is sequential so that the validity of the body (full connectivity at all times) can be guaranteed. Simultaneous action of two bots in the same grid location must be avoided. Such complications will be dealt with later.

5 stages of development in a tiny 16x16x16 grid. 4 similar body-bots make random movements along the body, adding a cell at each step.

At this point we are only concerned about a proof of concept, trying out the workings of the system using a very simple setup. There are 4 body-bots with identical programs, together growing a body in a small 16x16x16 grid. Their program is one of the simplest imaginable. The following is done on each step:

- List candidate positions to move to. These are all the grid positions in the direct bot neighborhood that are adjacent to the body.- Move to a randomly selected candidate position from the list, or stand still when the list is empty.- Add a cell at the new position.

Running this toy system is already quite revealing. We see that the bots build a single, fully connected body with a complex shape, while they properly respect the given 3D grid boundaries.

Surprisingly, bots often arrive at a ‘dead end’, a spot where there are no longer any valid candidate positions to move to. What to do then? There are several ways to deal with this situation and it makes sense to treat the ‘dead end’ behavior of a bot as yet another stage of its program pipeline, and develop a number of building blocks for it. For example: 1) bot dies, 2) bot stands still, 3) bot hops to the nearest free position, 4) bot hops to a random free position, 5) bot switches from being a cell adder to being a cell remover, etcetera.

In a larger grid the growth is less constrained and the characteristics of the processes at work are more evident. This first bot program effectively makes a random walk, without ever visiting the same grid position twice. Very little structure arises, which is to be expected given all the random choices the bot makes.

A test run in a 256x256x256 grid. 4 similar body-bots make random movements along the body, adding a cell at each step.

With a minimal evox-a application in good working order, the focus can shift to designing the body-bot processing pipelines in more detail and introducing interactions between bots and cells, but also between bots and other bots. That will be the subject of the next article.

(next: https://medium.com/@notnot/evox-a-types-of-interaction-b61dade96b01)

This is a work in progress… to be continued…

--

--