After my initial experiments with 2D Virtual Creatures the next step I wanted to try was 3D creatures.
Types of starting creature setups
The virtual creatures are based on 3D boxes joined together by motor driven joints. Nothing more complex is required. No neural nets, no sensors, just a series of connected body parts with joints rotating at various angles and speeds. Even with these few simple parts some interesting behaviour can occur.
For my experiments I used the following base creature types.
Snake – A series of 2 or more body segments lying in a row connected by joints. Segment sizes and joint directions and strengths are all random.
Cross – A body with 4 arms linked out in the X and Z directions.
Jack – A body with arms linked out in all 6 XYZ directions. Named because the initial layout shape is like the pieces in the old jacks game.
Building an initial gene pool
To evolve creatures you need a set of existing creatures to mutate and evolve. To create a gene pool I repeatedly create random creatures (random body segments, segment sizes, joint speeds etc).
The creatures are then dropped onto a virtual ground and monitored over a set amount of time. If the creature stops moving or explodes (happens if the physcis engine math goes crazy) it is ignored. If it survives for the amount of testing time it is added to a temporary list. The search can be left to run for hours or overnight. When the search is stopped the best 10 are found and saved. Best creatures are selected based on how far they travel from their starting point across the virtual ground.
Evolving the gene pool
Once you have a set of reasonable performing creatures in the gene pool evolution can tweak and improve them further.
Each creature has its attributes slightly changed and the new mutated creature is tested. If it goes further then it replaces the old creature.
For these mutations I only mutate the joint speeds, torque and rotation axiis using the following code
mutationpercentage:=; mutationfactor2:=mutationpercentage/100; mutationfactor1:=1-mutationfactor2/2; JointSpeed:=JointSpeed*(mutationfactor1+random*mutationfactor2);
If the initial mutationpercentage is specified to be 20% then the joint speed is randomly changed + or – 10% of its current amount. Same for the torque and rotation axis vector xyz components.
Nothing too spectacular at this time. Maybe if I let the mutations churn for weeks it may fluke a really interesting setup. The following movie shows some of the creatures that the current methods discovered.