So I’ve done another one of those short weekend projects, this time about mixing and passing on genomes. More of an afternoon project to be honest.
It’s basically a simulation based on a chapter I read in the book What If by Randal Munroe where he describes a way to present and combine simplified DNA in a intriguing way. I’ve adapted it for my case as following…
The debug text works this way for example: Sight: [initial average] | [current average]
Each of these cubes and blobs you see on the screenshot has 5 stats (or chromosomes if you will):
- sight (radius of stuff detection)
- health (for combat)
- lifespan (number of cycles that a cube can live)
- strength (combat works by health-strength)
- color (to more easily keep track of lineages)
And they’re calculated by joining together two sets of direct ancestor chromosomes. Herein lies the interesting part. The ancestor stats can either be values or multipliers and when combining them together you either get:
- two values, pick the better one
- value and multiplier, multiply together
- two multipliers, value is 1 (inbreeding causes lots of these due to high probability of multipliers on the same stat)
Then when passing on genetic data to children (the one sentence when this doesn’t refer to subnodes in gamedev lmao) the passed on set of stats is randomly picked from the two contained sets (one or the other for each stat).
Then I’ve put these cubes on a grid where they can move in 4 directions, gave them basic steering behaviors (wander, seek) and set them to follow these rules:
- a) if hungry, wander until you see food, eat food, repeat
- b) if really hungry do a) but also kill any other same sex cubes for food
- c) if hunger is below a threshold seek out an opposite sex cube within 0-1 generational difference
If a cube dies from any cause, it drops food.
Then I spawned different amounts of food (small green cubes) and cubes (with random initial stats) and dropped them into different sized maps.
I ran it in the rendering thread with vsync off so I could get about 500-2000 steps a second, leaving some time for the cubes to live and procreate, then check the results.
While it’s not quite perfect, we can actually see natural selection at work. Here in the following screenshot we have a gigantic map and we can see the cubes were selected for huge sight values and long lifespans - which makes sense if you want to find food and a mate on a huge plane. The cubes with the best genes passed them on, the rest perished.
So basically, a genetic algorithm with extra steps
Oh btw, the starved, killed and aged numbers list the amount of cubes that died in each way.
I’ve tried some further tests with added mutations and stuff, trying to get the selection to bring average values up to some crazy levels but it just wouldn’t work for some reason. I’m not sure if there were any massive outliers but it didn’t seem that way. ¯\_(ツ)_/¯
I suppose there could be some more interesting things we could do with this setup but I sort of deleted the whole genetics thing when trying to make it into a 2D quad noise terrain renderer…
Shouldn’t be too hard to reimplement if anyone has any clue where to go from this anyway. I sure had no further ideas at the time.
And finally, not jme related and not exactly a weekend project either: an underwater ROV I’m building.
Those are 1100 gallon per hour submersible bilge pumps for ships, with one of them converted to a prop so it can reverse thrust for depth control. I’d convert the remaining two as well, but I can’t get my hands on any more prop adapters. Local hobby shops are all out of this size and amazon doesn’t have it.
This is just a preview test fit btw, as I still don’t quite know where to put the large buoyancy tanks so they’re above the depth prop and I think I’ll need twice as many in the end as well. The base console (see: pvc box with switches, monitor and a UPS battery) with switches is nearly done as well.