Evolving processes of growth: some sketchy ideas.
2022–09–20 23:12:42 : embarked on a new project: design and implement a software substrate for the growth of a rich variety of 3-dimensional forms. Blogging about it might help to clear up my mind. In contrast to a work log with its almost random assortment of entries, I imagine a blog to have more structure. Let’s see!
As a preparation, a few months were spent to study, implement and play with some well-known existing growth related algorithms, such as Cellular Automata, L-systems and Reaction-Diffusion. To explore new territories a hybrid approach was used where several processes can be combined. For example, the above image shows a form that came about by an L-system based ‘skeleton’ onto which voxel accretion took place.
Although the expressiveness of this hybrid system is more than that of its constituent parts, it lacks the capacity for sheer surprise and novelty. One would want a system that operates on a much lower level, interconnecting atomic growth related operations (tiny pieces of generative code) into working assemblies and dump these in a primordial soup where who knows what will emerge!
Note that growth is here considered as a computational process running in a model of simulated time-space, following its artificial rules. We need not be limited by the workings of processes known from nature, we are free to use any hypothetical mechanisms that can possibly arise. Of course nature, with its wealth of forms is immensely inspiring but we do not strive to replicate it.
Let’s be more concrete now. There are some requirements:
- The forms that grow should consist of one piece, i.e. fully connected, no loose parts. Forms are allowed to have enclosed cavities.
- The forms have a limited maximal size and complexity, dictated by the computer hardware that is used to run the model. Growth must be stoppable before these limits are reached.
Voxels, a.k.a Volume Elements, are well suited as a format to describe the growing forms because they make it relatively easy to check connectivity, while they impose no restrictions to the complexity of the encoded forms, except that they will be quantized onto a regular 3D grid. The higher the grid resolution, the less of an issue this quantization becomes. Voxels are simple to imagine and reason about and lead to relatively intuitive and straightforward algorithms. Compared to biological cells, the cubic voxels with their fixed position and size are quite rigid, but nonetheless a metaphor of an abstract cell can stimulate thought experiments of possible processes where cells act as agents in a growing body.
Voxel grids could also be useful to store spatialized information about the ‘medium’ that surrounds the growing form. One can imagine that certain qualities of this medium influence the growth processes locally. One can also imagine it the other way around: that the growing form, or ‘body’, influences the medium around it. We then have a potentially fertile feedback setup for complexity to arise.
3D vectors may also have their place in the system to describe for instance positions and directions of sources, targets, forces, velocities and what not. Vectors can be ‘drawn’ into the voxel grid, if need be. The advantage of vectors is that they are not subjected to the grid positions but can have any intermediate positions and angles.
How to ensure that the growing body consists of one piece? All the voxels that make up that body must then be connected to each other, either directly, or via intermediate voxels. If we start with a single voxel, then add voxels only in places where they have direct contact with already existing voxels, then full connectivity is guaranteed throughout the growth. Trivial to implement. If we have code to check local connectivity, it is even possible to find and remove voxels without breaking up the body into several pieces. Slightly harder to implement. Such a basic ‘step by step’ approach is attractive because it could be a way to iteratively develop complexity starting from simplicity.
Many interesting phenomena involve dynamics between several, possibly conflicting processes. The interplay between cell addition (‘birth’) and removal (‘death’) is an example. A promising model of growth will make a large variety of dynamics possible, with many types of outcomes, without actually predefining (let alone hardcoding!) all scenarios. Ideally the software should generate specific growth systems automatically, which can then be executed and monitored. The growth model is then a meta description of low level operations and they way these can be combined to form valid instances of actual processes.
When developing software, it is wise to keep things simple. On the other hand, we seek complex outcomes. Since we are eager to witness surprise and novelty, we cannot on forehand write a specification of the system. All we can do is start with a concept -still rather vague- and make it concrete by coding it, being confronted with what it does, understanding it better, trying to increase expressivity without making a mess. Repeat until done. In my case it helps if the system I work on, no matter how virtual it is, can still be thought of as some almost tangible machinery that manipulates particles of matter instead of numbers flowing through CPU registers.
Talking about machinery, suppose the growth of a body is described by modeling a set of miniscule interacting robots that move on the surface of that body, perhaps even inside it, adding or removing cells? Suppose these robots can detect the local conditions at their current positions and let those influence their behavior. Suppose these robots are aware of the other robots, via some distant sensing. Some might want to join, others might want to stay apart, yet others won’t even care. What if there were a variety of robot species, each with their own behaviors? What if there could be large numbers of various robots active in and on a body? What if some robots can have fluctuating energy levels, possibly dependent on interactions with the body and/or other robots? What if there were multiple cell types, each with their own characteristics and opportunities for differentiation? Using an agent-based approach like this there is plenty of room for the emergence of the unspecified features!
The challenge now is to figure out a way to dissect the actions of the imaginary ‘body-bots’ in such a way that we end up with a sequence of stages that is common to all of them, but still allows a lot of variation. Each stage handles a part of the processing pipeline that a bot needs to perform in order to complete one timestep of the simulation. As an example, a very rudimental 2-stage sequence could be:
1: move to grid position
2: act on grid position
Obviously there are many ways to implement these two stages. Suppose there are 7 types of ‘move’ stages, and 13 types of ‘act’ stages. It is then possible to create 7 * 13 = 91 unique processing pipelines, by making different combinations of the available building blocks for each stage. When dissecting these two basic actions further, we could for instance end up with the following stages of processing:
1: sense current local environment
2: move (depending on local environment)
3: sense new local environment
4: act (depending on local environment)
The more fine-grained the processing stages will get, the simpler they will be because there is less work to do per stage. The more stages, and the more variants per stage, the higher the number of permutations becomes! Let’s say 4 * 6 * 5 * 11 = 1320.
Once a scheme is found that defines how to assemble a body-bot processing pipeline by chaining compatible building blocks, creating a large variety of bots from scratch is easy. Once the processing stages have become so fine-grained and varied that the number of possible unique bots runs in the millions or even billions, there is a huge space of possibilities to explore. Note that we are not necessarily dealing with just a single bot, but with a group of them, each of which can be different. A combinatorial explosion!
In nature, evolution is bringing about an amazing and continuously changing variety and differentiation of lifeforms. In software, artificial evolution has proven to be capable of searching huge spaces of possibilities and finding striking ‘solutions’. Because the process of evolution is open ended, it is a suitable underlying mechanism for building a meta-model of growth, and exploring it without any roadmap to specific destinations.
With all this in mind, time has come to implement a minimal application that can generate a variety of body-bots that can grow and manipulate voxel based bodies. In this initial implementation the focus will be on developing the foundations of a ‘software substrate’ : the datatypes and functions that are necessary to host virtual growth processes in a computer and evolve them, as outlined above. Ideas and concepts that are now lazily vague will have to become fully detailed and specific before they can be captured in a programming language. It is then, when confronted with all the nitty-gritty that concepts develop and refine. Still, keep things as simple as possible for now, no fancy stuff! A two stage bot processing pipeline suffices to test all the low-level functions needed to grow fully connected voxel bodies. Just being able to move along a body and adding voxels of a single cell type will do.
Working title: ‘evox-a’ (evolved voxels version a)
(next: https://notnot.medium.com/evox-a-a-first-implementation-f52b0e27875e)
This is a work in progress… to be continued…