🤑 Indie game store🙌 Free games😂 Fun games😨 Horror games
👷 Game development🎨 Assets📚 Comics
🎉 Sales🎁 Bundles

A short video and some ideas

A topic by adamwilko created Jan 09, 2018 Views: 226 Replies: 3
Viewing posts 1 to 4
(+1)

I saw in another thread Keiwan mentioned he may do "linked" muscles in a future version, which would help a lot with the sort of designs I'm messing with. Just wanted to mention that if you do this, inverse links would help as well - it would reduce the outputs on this guy in the video from 24 to 6 real outputs with 6 linked and 12 inverse linked muscles.

Also, an idea I wanted t mention: genetic algorithms are fun and all, but the standard set up of running and breeding generations is terribly inefficient, and I think this idea might also fix some of your other bugs where it feels like the best of each generation are sometimes lost... Rather than discrete generations, you could kill off poor performers by wiping the contents of the least fit many times per second and remaking them as children / mutations of the most fit. 

When you have generations, not only are you wasting CPU on simulating things that don't perform well, you are also selecting only for what is best for the first n seconds, rather than selecting for stability, resilience and reproducability - with "immortal" creatures, the top performers will constantly breed for as long as they remain the top performers. In running or climbing mode, you could show all, but space them out, focus the camera on the current leader and spawn children just off screen  to the right, when a creature is too far off screen to the left of the leader, it is deemed unfit and flagged to be respawned to the right, so you'd always see the best of breed, running past a bunch of slightly inferior mutants, and occasionally the camera will pan right to a new, superior variant.

Also, you could implement a very simple run time mutation and pseudo back propagation: Each frame pick a creature at random, pick a weight, compare it's value to the same weight in the leader. If it is the same, add a bit of random, if they are different, adjust the weight to be more like the leader, but allow it to overshoot. eg if the weight is 0.4 and the same weight on the leader is 0.43, adjust to anywhere in the range 0.4 to 0.46 you could do that constantly - adjusting one or two weights per frame at random - things that don't work will naturally fall off and respawn, but things that do work will keep pace or overtake to become the new leader, without having to go through the birth / death cycle.

Anyway, just some thoughts, I might take a look at your code too Keiwan, I have not written a proper NN before so it should be interesting.


I
(+1)

Hey again,

 It's been really inspiring and educational for me going through your code,  thank you for making it available.  I have a couple more things to add after looking at it.

You're using averaged bone rotation.z as one of the inputs, but despite how it appears in the inspector, transform.rotation is a Quaternion which gives you some issues... Unity will automatically convert the rotation (0,0,1,0) to (1,0,0,0) and this rare, sudden spike  just adds to the internal weirdness of quaternion, eg. z is exactly the same at 135 and -135 degrees, and flips negative at around 120 degrees - so the input is very inconsistent. The fact that creatures can overcome this garbled input is testament to how great neural networks really are.  

A simple way to sanitise rotation is using two separate inputs - ie averaging the 2D vectors along the length of each bone, so instead of using  rotation.z, if you use the local transform.up you'll get a couple of nice normalised sine waves  for the "upness" and "rightness" of them, which should average out well and give your creatures far more meaningful input overall.

The other thing is muscle scaling - for me designing creatures was a bit of a struggle, I want to add rigid parts, eg triangles for body and feet, but the extra bone and joint weight means it often struggles to move at all, so I end up adding more muscles to nearby bones to compensate, which make the NN more complicated and slower than it needs to be. One solution would be to scale the force of each muscle by creatureWeight / totalMuscles.

Anyway thanks again for making this and for posting the code. :D

Developer

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.

(+1)

I think the rotational input may have been at least partially responsible for that random thrashing, I modified it to add the transform.up of each bone and use a normalised (x,y) as two  inputs and have not seen the random explosions very often since. Currently using 2100 strength (up from 1500) rather than scaling on the fly, 2100 reduces the need for additional muscles, which may also be reducing the glitches. I've tested out some other changes too which have been effective, but as you mention, these would certainly break existing creature minds.  First, I changed all the sigmoids to tanh and got rid of the scaling on the output as the whole thing now works in the -1/+1 range, as opposed to weights flipping a 0-1 range. This seems to make the initial creatures a lot more active - every muscle is doing something - which usually affects the first generations pretty favourably. I've also started normalising the inputs to +/-1 eg: number of points on ground I calculate as (((float) count / joints.Count) - 0.5) * 2

At this point I will probably start building my own version from scratch soon, there's a lot of things I want to change and add, going full 3D with hinge, ball and rotator joints for a start, and things like hearts which generate a pulse as a sine wave, or touch sensors for discrete and selective input on what is on the ground, or a head bone that provides a single source for height and velocity, rather than an aggregation.... so many ideas! :)