Answer to Question No. 3 over here: https://itch.io/post/411539
Recent community posts
I explained what the latest state of that bug is over here: https://itch.io/t/150983/somthing-seems-off-in-the-pick-best-creature-algorithm-...
Effectively, the bug isn't that the best creature isn't being selected correctly, but that the best creature sometimes decides to just not repeat what it did really well in the previous generation, even though it has the exact same brain as before. Makes the whole thing much much more complicated to try to fix.
Hmm, the only info I could have given you on that is that all of those unzipped files (Evolution.exe, Evolution_Data and UnityPlayer.dll) need to be in the same folder, but you said that they already are. There's also nothing else I can find that might be causing this issue. The last time I tested the Windows build everything worked fine. I downloaded the .zip, unzipped it and then ran the .exe
Maybe someone else who uses Windows as their main OS and has had this problem before can help you out.
You can use the middle mouse button to pan the camera when building a creature (Or use two fingers if you are on mobile).
I don't know why I haven't added scroll to zoom yet, especially since it's just one line of code. It's going to be part of the next update, thanks!
Yeah, the distances in the simulation aren't really comparable to real life distances. They are only useful if you want to compare different creatures to each other.
As far as Unity and the physics system is concerned, the creatures are actually massive and the muscles are extremely powerful. Gravity is set to -50m/s² (in Unity meter units). I had to play around with these values a lot to get both natural looking behaviour and to get rid of as many unexpected physics bugs as possible.
So the fact that in the creature stats I write meters, doesn't mean actual meters. It's just because if I wrote "Average speed: 5 units/s" everybody would be asking what this arbitrary unit is, whereas its only purpose is to give you a comparison between creatures.
I really like this one! Do you maybe have the option to rerecord this at a higher framerate? If it's a performance issue you could try to set it to simulate in batches of 1 while you record, to make it a little easier for the CPU. Or you could send me the savefile to firstname.lastname@example.org if possible and I could try to record a gif on my machine.
If none of that is possible, I'll just use this gif, but I feel like the motion is too good to be displayed at only ~8fps.
1. https://stackoverflow.com/a/44421935/6214222 Company name in this case is "Keiwan Donyagard", product name is "Evolution"
2. You can take a look at the code, if you want. You need to scroll down to the UpdateInputs function in each Brain implementation. Here's the running brain for example. https://github.com/keiwando/evolution/blob/master/Assets/Scripts/Brains/RunningB..
3. The mutation variable determines the percentage of creatures that get mutated per generation. So if you have 10 creatures about 5 will be mutated during the recombination step. I say "about 5" because the actual number of mutated creatures is still random, based on a uniform distribution.
4. No, since the mutation rate works on a per-creature basis.
5. By group you mean have them expand and contract at the same time? Currently no, but maybe in the future (It's not very likely though)
6. I'm not too sure what exactly you mean by that? Something like this? https://arxiv.org/pdf/1706.03702.pdf
7. Since the last update there is now an option to visualize the amount of muscle contraction / expansion per muscle, which is effectively nothing other than the network output for that muscle.
8. No, the network gets randomly initialized every time you start a new simulation.
9. If you click on the little screen in the top right that says "Best of Gen..." you can view the best creature from any previously simulated generation.
10. On that same "Best of Gen" screen, you'll find some stats about the best creature of the previous generations, including the distance travelled. I might add little markers to the simulation screen to indicate the current distance sometime in the future.
Thanks a lot for the kind words!
I can see the the problem, but it's unfortunately not very straightforward to fix, without at least compromising in some other areas and possibly even breaking existing designs.
If I add an absolute limit to the minimal and maximal length of the muscles, that wouldn't really fix your problem, since the "global" max limit (that applies to all muscles) would have to be much bigger than you want, in case that you do need to use a longer muscle somewhere in your design.
If I use relative limits (e.g I say the muscle can only stretch to 200% of its original length within the design) then that will limit behaviour of your creatures in a lot of designs where you wouldn't expect it. For example, if you had to place two bones together at a small angle, but then wanted a muscle between the two to expand far enough to create a very large angle, the muscle wouldn't be able to do that, which would make it seem like it's not strong enough.
The best way I can currently think of to incorporate this would be to add general options to each individual muscle, where you could adjust stuff like this (relative expansion/contraction limits, force...) on a per-muscle basis. That way I could keep the current muscle settings as a default but also allow you to do some adjustments if you like.
However, that's going to take quite a bit more time to implement as compared to just slapping a fixed, non-adjustable limit on every muscle, and since I currently barely have any time to spend on this project I can't say how long it's going to take me (probably a few months) or if it's going to work out at all - I might come across some unexpected issues and would have to scrap this idea.
Yeah, that's definitely one of the first things I want to try in the future when I find the time. I'm interested to see how much I can increase the performance by offloading all of the network calculations from the CPU to the GPU, since those calculations are all naturally parallelizable anyway.
Currently the only option you have if you want the benefits of a larger population size and you're okay with trading in the time it takes to simulate a single generation, is to simulate your generation in batches that your CPU can handle at once.
I just released a linux version with the latest update.
However, I won't be offering any linux specific support or extensive testing of this linux build because I don't have the resources for that. Also as a heads up, there is a bug in the current version of Unity that causes every keystroke into an input field to be registered twice in linux builds [see here], which is quite annoying. I'm probably going to rebuild the linux version once they fix it.
Most of the tasks require a slightly different set of inputs, so the creature brains are not interchangeable between different tasks. (The same design needs a different type of brain for almost every different tasks)
Also, the even if the inputs were all the same, the creature still wouldn't be able to learn multiple skills and then "choose" based on the task it has to fulfill. It would have to unlearn the first skill and then learn the new task, which effectively ends up being the same as how it currently works anyway.
The stats are available for the best creatures of previous generations. You can switch to that view by clicking the little screen in the top right corner (during simulation) that says "Best of Gen..."
I already tried the Time.timescale approach but unfortunately it messes up the physics system causing the creatures to behave and move differently when everything is sped up, which ruins the whole simulation.
If anybody knows a different way I could implement a speedup that doesn't break the physics in Unity I would definitely give it a shot.
You can change the time per generation/batch during the simulation from the pause screen. The pause button is at the bottom of the screen.
However, please note that lowering the simulation time per generation doesn't make the creatures evolve faster. It's not equivalent to a speedup slider or anything similar. It's just the amount of time you give the creatures to show their behaviour before the algorithm goes in and has to decide which ones are better than others. If that time is too short, the algorithm has no proper way of being able to tell which creatures perform better and at that point selection becomes pretty much random. So setting that number too low (in this case 1 sec) will definitely ruin the simulation and you shouldn't expect any progress at all.
I would strongly recommend not setting the value to anything significantly less than 10 sec.
Thank you so much for all of your ideas, suggestions and general feedback! And for that great video! It's going to take me at least a month before I have some time again to get to all of this, but I'm definitely looking forward to it.
I originally started out with a higher overall muscle force but that caused the creatures to just randomly explode all the time. It happened most often when there were multiple muscles attached to the same bone and apparently the physics system couldn't handle all of those forces. I don't know if there is another way to fix that issue, but the only solution I found was to settle at the current combination of body part weights, muscle strengths, gravity and physics solver settings. I am also very hesitant to change something like the muscle strength, since that could easily break already existing and saved creature designs and simulations (the creature movement would change because of the different forces).
I definitely agree that the muscles should be stronger than they currently are, but I currently don't see an easy way to implement that without potentially breaking a lot of other stuff.
Thanks again for all your input! I'll definitely come back to this once the current semester is over.
Since I barely ever use Windows myself I can't really help any more than point to the Unity documentation for where you can find the PlayerPrefs file. I'm not familiar with the Windows registry at all, so I don't know why it wouldn't be there. Did you follow the exact path given by the documentation?
"On Windows, PlayerPrefs are stored in the registry under HKCU\Software\[company name]\[product name] key, where company and product names are the names set up in Project Settings."
I will definitely fix this issue once I get time to work on this project again (probably the end of next month)
Thanks! Yeah, I wrote the network myself. It's a really basic feed-forward network so it's nothing special or overly complex, just a nice little exercise for myself to play around with and learn more about machine learning.
It would be nice if you could send me the error.log to email@example.com. I'll try to take a look and see if I can figure out the problem once I have time to work on this project again (probably some time around the end of February).
Oh, I didn't take it as an insult at all. I apologize if it seemed like I did :)
There are certainly a lot of flaws with my implementation, and I definitely believe you when you say that the VR movement is not very accurate. When I run it on my phone and do a 360° turn (in real life) I end up with an offset of about 20° between the library and the real world. The offset also seems to be related to how fast I move my phone around and generally how accurate the gyroscope of my device is (I get a slightly more accurate experience on my iPad). So it wouldn't surprise me if you experienced an even larger offset on a different phone.
I dealt with the mirror by simply not including it :) Since there is no actual character for the player but only a camera floating in space it would have either ruined the illusion of you really being in the library, or I would have had to find a nice-looking model and added that in, which just seemed like too much work for a small detail (and it probably wouldn't even have looked very nice).
The reason why I didn't include the toilet and sleeping cupboard was purely because of a lack of space. There really isn't a lot of space left between the staircase and the hexagon walls and I didn't want to resize everything to make it fit.
Oh and there are 32 books per shelf.
The staircases do have a rotation of 60 degrees and not 90. It's exactly because of the reason you just explained, namely to ensure that every hexagon is reachable, especially the ones on the same floor that you are currently on. Right now you can go to a neighbouring hexagon that is not directly connected to the one you're in via a hallway by walking up a staircase, walking to the next hallway and then walking back down a staircase.
Here's a sketch of the library structure I made back when I was trying to figure out how I needed to design everything for it to work:
You found it!
"Others, going about it in the opposite way, thought the first thing to do was eliminate all worthless books. They would invade the hexagons, show credentials that were not always false, leaf disgustedly through a volume and condemn entire walls of books. It is to their hygienic, ascetic rage that we lay the senseless loss of millions of volumes. Their name is execrated today, but those who grieve over the "treasures" destroyed in that frenzy overlook two widely acknowledged facts: One, that the Library is so huge that any reduction by human hands must be infinitesimal. And two, that each book is unique and irreplaceable, but (since the Library is total) there are always several hundred thousand imperfect facsimiles - books that differ by no more than a single letter, or a comma. "
The music is "Comfortable Mystery (1-4)" by Kevin MacLeod. You can download it over at incompetech.com. It's weird, in my mind I had credited the music in the settings but I just went back and checked and it seems like I forgot to do that. I'm going to add that in a future update.
"Isn't the program supposed to preserve the best creature and so the drop in fitness shouldn't happen because of that?“
Yes, the best creature’s brain will be included without any modifications in the next generation if you have the setting enabled (I’ve also tested and verified this). You’re right, this should theoretically prevent a drastic fitness drop. Maybe this is also related to the behaviour change bug.
"Isn't the simulation deterministic so the same creature with the same brain should always behave exactly the same way?“
The neural network is fully deterministic so yes, the idea is that the same brain should always result in the same behaviour. Apparently though, this doesn’t always happen, for which I have no explanation. The only part of the full code that isn’t deterministic is the mutation and mating logic (the creatures that get picked are based on weighted randomization), but this has nothing to do with the brain during the simulation.
The part that is not under my control is Unity’s physics system, which could have something to do with the issue.
"Maybe the best creature is picked but for some reason some other creature is being displayed?“
The way that the best creatures logic works is the following: At the end of every generation I store the encoded brain (as a string) of the best creature in a list. When a „Best creature“ needs to be displayed (either manually or automatically), I pick the respective encoded brain, instantiate a new copy of the body, decode the brain string (chromosome) into an actual neural network and apply that to the body. (I also verified that the creatures always get the same brain that the best one of the generation had - even when the „Best creature“ doesn’t move, it has the exact same brain as when it used to be moving)
"Also shouldn't the worst creatures be erased from the population and so there shouldn't be such a big gap between the best and worst creature?“
The worst ones don’t get completely erased but they have a very small chance of passing on their genes to the next generation. It can also always happen that you mate two good creatures and then mutate a section of their brain that then renders the whole brain useless and results in a really bad creature.
"You said that the bug doesn't happen often but for me it happens all the time. As you can see in the video the "best of" screen never shows anything other than a creature falling on it's face.“
I mean it doesn’t happen that often in different simulations. Once it happens in a certain simulation then it seems to persist for the rest of that simulation without going back to normal.
"Are you the one who wrote the code behind the neural network or are you using some libraries for that?“
Yes, I wrote the network (and everything else) myself without using any libraries. The whole point of this project to me was to learn the basics of neural networks and evolutionary algorithms and have something to apply that knowledge to and playing around with.
"And one last thing. Is there any chance of you releasing the source code to public?“
I get asked that quite often and I’m actually surprised that nobody just tries to search for it, because you could easily find it in about 20 seconds. The source code is and has always been on my GitHub. https://github.com/keiwando/evolution
The project does not have an open source license, so the regular copyright stuff applies. You can obviously read through the code or play around with it for personal use though.
"Hmm, may it be that the reason for the bug is that, you are reseting physical structure of creature but not it's brain at the start of "the best" simulation? Same reason could be the cause for that fitness drop.“
The brains / neural networks have no state associated with them that would need to be reset. The networks always get encoded into strings (which is just an encoding of the weight matrices), then these strings are used for mutation and reproduction and then the new strings are decoded into networks to be applied to the new set of copies of the body.
(I commented this underneath the video already but I'm reposting it here so other people can read it as well. The comment might have also landed in your YouTube spam filter.)
Thanks a lot for the video! There is certainly a bug in here, but it's not really what seems to be the 'obvious' reason. In fact, I tried to solve this bug alone for a couple of days when I had time to work on the 2.0 update but I didn't manage to figure out what's going on.
That being said, I did a ton of testing and know certain things that are definitely not causing the bug. In short the problem is this: Sometimes the creatures in the "Best of" scene don't behave the same way they did during the actual simulation, even though they have the exact same brain as the best creature of that previous simulated generation.
I understand that when you (or anybody else) looks at the behaviour the first thing to think is: „The simulation clearly doesn’t pick the best one / It picks one of the bad ones.“ A lot of people say that. The real problem is that this is not the case (It would be really nice if it was because that would have been easy to fix).
This is definitely not the case though. The simulation consistently picks the creature with the highest fitness score of the generation as the best creature and stores that brain (in chromosome form, so as an encoded string). The fitness scores are also assigned properly. This is why 1) the creatures evolve at all and 2) the reason why you were seeing relatively high fitness scores (~17%) being displayed in the best creatures scene, while the „best creature“ was just falling over. It’s because the same creature (with the same brain) performed well and actually got 17% fitness during the simulation. It just for some reason doesn’t want to move when you put it in the „best creatures scene“. <- This is the really annoying bug that I’ve already tried to fix for days, but the problem is that I have no idea why this might be happening at all, so I can’t even consistently reproduce it.
As you have probably also noticed this doesn’t happen all the time. Most of the time the best creatures perform exactly the same as they did during the simulation and everything is fine. But that just makes it harder for me to find out the reason behind the bug. So if anybody can find out how to consistently reproduce this issue (instead of just randomly witnessing it) that would be of great help!
Another way to tell that the best creature is actually behaving differently (compared to when it was simulating) is that sometimes when this bug happens (not in this video) you can see that all of the creatures during the simulation actually walk - some better, some worse, but all of them walk - whereas the bugged out best creature just wiggles or falls over. This shows that this isn’t a matter of the wrong creature being picked but it’s actually a change in behaviour of the best creature (without any apparent reason).
That’s as much as I can say about this bug. The thing to take away from this is: While this bug is highly annoying and definitely something I’d love to be able to finally fix one day, it doesn’t affect the outcome of the simulation at all. It’s something that purely happens on the „best of“ scene.
Now you might ask yourself, well then why did the fitness score randomly drop from 17 to 5%?
This could have a lot of different reasons so I can’t say for sure why that is, but I’m pretty sure it’s unrelated to the above bug. Not only does the fitness drop „randomly“, it also goes back up as you can even see in this video. Additionally, the fitness neither drops exactly when the best creature bug happens for the first time, nor does it drop only when the bug occurs. Sometimes you can see these fitness fluctuations between generations without the bug even happening at all.
My current guess is that the creature brains have reached a point where you have (sort of) two groups of creatures. The ones that are doing pretty well at walking and the ones that can barely walk at all. Now when the next generation is created you can end up mating good and bad creatures which could cause the new creatures to receive one part of the bad creature’s brain and another part of the good creature’s brain. This could result in a bunch of creature that can’t walk at all (just like we’re seeing it in the video). However, the brain information of the previously good creatures is not fully gone; it’s still in the brains of the current generation. Therefore, during the next mating process you can still end up with creatures that receive both good brain parts and then „know“ how to walk again.
This is just my guess as to what might be happening here - especially since it seems to be happening in cycles and the good behaviour always keeps coming back after a certain number of generation after the fitness drops. The important thing is that this is unrelated to the bug described above and most likely not a bug itself.
That being said this bipedal creature is pretty amazing when it walks. Would you be okay with it if I record a little gif of one of them and add it to the collection at keiwando.com/evolution-gifs ? I would link back to this video of yours or another video/gif you might want to make yourself with this creature design.
That sounds really interesting and would probably improve the behaviour of a lot of creatures but I'm going to be honest: Implementing this would be quite a lot of work so it's probably not going to happen.
To be a little more specific, parts of the code that would be affected by this would be:
- The creature building logic. I'd need to have a way to figure out which muscles are a symmetric pair. (There are a bunch of edge cases and problems that come with that)
- The creature saving logic. I'd need to add this additional information about symmetry into the save files, which would then cause me to have a new save file version which needs to be distinguished from the old ones.
- The runtime logic of how the brain connects to the muscles.
- If I implement synchronized symmetric muscles, why not just allow the user to pick arbitrary groups of muscles that will then receive the same brain outputs, instead of restricting it to symmetric designs.
This last point is actually quite interesting and could lead to some really cool results. I'm now a little bit more tempted to do it. It's still going to be a large amount of work and is most likely not going to happen in the next year or so because I just don't have any time, but maybe with the next big update (if there will ever be one).
I've been really enjoying seeing all the different creature designs you've come up with, so I decided to make a small collection of gifs of user created creatures over on my website: http://keiwando.com/evolution-gifs.html
If you've created a cool creature and would like it to be featured in that collection you can send me a gif and I might add it to the list. Just link them here on itch.io or send me an e-mail at firstname.lastname@example.org
Important: Here are some things to consider if you want to submit a gif. I will assume that you have read these points and are okay with them if you decide to send something in! If you do not agree with any of these points, don't send anything in.
- I will download the gif, compress and potentially resize or crop it in order to lower the file size as much as I can. The optimized gif will then be hosted from my website and not where the original was hosted.
- I will add a link to every gif that takes you either to the original or to a different link you've sent me (together with the gif link) where the gif is taken from.
- Example 1: You have made a YouTube video and want to submit a short gif extracted from that video. Send me a direct link to the .gif and a link to your YouTube video. If a user clicks on the optimized gif in the gif collection, it will take them to your YouTube video.
- Example 2: You only send me a direct link to the .gif. If a user clicks on the compressed gif in the gif collection, it will take them to the location of the original.
- I can't promise that all of the submissions will end up on the website. This can have several reasons:
- I didn't get your e-mail (maybe because it ended up in my spam folder). If you don't want to run into this risk just link the gif right here.
- The gif was too big and I wasn't able to compress it to an acceptable file size.
- Nothing even remotely interesting happens in the gif. If your creature just sits there and does nothing, chances are high it will not end up in the collection.
- I didn't have time to update the website yet. I will add multiple of them at a time whenever I have some free time and nothing else to do (which doesn't happen too often at the moment) so please don't expect your submission to show up any time soon in the collection.
- If the custom link you submitted together with the gif doesn't actually lead to a place where the gif is taken from, is shortened in a way that doesn't immediately show where it's going to take me to if I click on it or is in any other way inappropriate, then I will either directly link to the gif itself or not include it at all.
- Any other arbitrary reason that I can't think of right now but I'm sure exists.
The change in lighting is the only practical way to find it but you also have to get lucky. The easter egg is something (relatively big) that spawns inside a certain radius from your spawn point in one of the rooms. It's most likely not going to spawn close enough for you to see it immediately (but it might) so you'll have to get lucky and start walking into the right direction (without knowing it at first) until you see a change of lighting. If this wasn't a just a simulation you'd also feel a change of temperature...
This is the current fitness function for the running task:
fitness = Mathf.Clamp(creature.GetXPosition() / (MAX_DISTANCE * SimulationTime), 0f, 1f);
The fitness is directly proportional to the horizontal distance that the creature has travelled, the top speed has no effect.
I'm going to look into this to see if I can reproduce this the next time I have time to work on this project again.
There is no builtin restriction that would prevent the creatures from being able to walk by crossing their legs over. However, walking that way is much more complex and requires a very fine tuned brain that is able to perfectly balance the whole creature during the transition between legs.
Therefore it's much more unlikely that a creature will learn how to do that in a short period of time. Instead, they will optimize their behaviour towards a local maximum where their strategy of walking still gets them moving forward at a certain speed (most likely not as fast as the 'obvious' way they should be doing things) without the need to worry a whole lot about balancing all the time.
You can always get lucky with a creature that is really good at walking using a highly complex movement pattern, it's just fairly unlikely to happen.