Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411275 Posts in 69323 Topics- by 58380 Members - Latest Member: bob1029

March 28, 2024, 05:24:13 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogsSnailLife (prev. Gastropoda). Browser based snail simulation.
Pages: 1 [2] 3
Print
Author Topic: SnailLife (prev. Gastropoda). Browser based snail simulation.  (Read 6827 times)
Liza
Level 1
*



View Profile WWW
« Reply #20 on: September 19, 2014, 01:22:46 PM »

I took a month off of Gastropoda to participate in the js13kGames challenge, and now I'm back to snailing.

Right now I am focusing on creating a rudimentary brain. I'm kind of winging it and have no idea what I'm doing. So far I've created various sensors and attention/recognition neurons, and have started making the memory tables. I have a full explanation of what there is so far in a blog post with code snippets: http://liza.io/braaaaaainsss/

Up next:

* Fix snail display in jar (currently snails are for some reason not displayed crawling around, though this was working yesterday..)
* Start searching through memory tables for recognized objects once an object is focused on
* ...figure it out as I go along.
Logged

Gamedragon
Guest
« Reply #21 on: September 19, 2014, 08:42:37 PM »

I am loving the look of this! Snails are awesome. Snails with traits and genes are even better.
Logged
Liza
Level 1
*



View Profile WWW
« Reply #22 on: September 19, 2014, 11:14:32 PM »

Thanks! I think I've kind of bitten off more than I can chew so far with this brain thing, we'll see how it goes.
Logged

Liza
Level 1
*



View Profile WWW
« Reply #23 on: September 21, 2014, 11:04:29 AM »

Nothing fun to show yet, but I'm now firing neurons that make a snail move on the x and y axis in the direction of a focused object. So the snails decide which object to focus on out of all the objects it can perceive with its senses in the jar, then sees if it can remember that object or not, then decides if it's curious about the object and moves toward it if so. This is not at all visualized on the jar profile page yet (the only place you will be able to see snail movement live). I will have to install something like Latchet for this, which I guess is what I'll be looking into next.
Logged

Liza
Level 1
*



View Profile WWW
« Reply #24 on: September 27, 2014, 12:35:46 AM »

You can't see it, but these snails are no longer moving around randomly! They're pinging the server every 5 seconds to get the snail's targetPosition from the db and then moving toward it using the snail's currentSpeed attribute.

Logged

Gamedragon
Guest
« Reply #25 on: September 27, 2014, 12:58:30 AM »

How are you going with the brain thingy. If you get that to work I will possibly worship you and offer you burnt sacrifices.
Logged
Liza
Level 1
*



View Profile WWW
« Reply #26 on: September 27, 2014, 01:17:02 AM »

How are you going with the brain thingy. If you get that to work I will possibly worship you and offer you burnt sacrifices.

So far the brain is in the very beginning stages - basically where I left it off in my previous linked post.

To recap: I check each snail's sensors (olfactory, optical, tactile, gustatory) for any inputs - ie any detected object, whether another snail or item. I then assign input weights to each input based on various criteria like distance, receptor strength/quality, etc. Then I send the input with the highest weight to the attention neuron and then to the recognition neuron, where we check if the snail has any memory of the object it detected (so far no, as I'm not yet storing memories). Then, we decide at random whether the snail is "curious" about the object or not (temporarily random - eventually this will be based on other factors). All of that information goes to the decision neuron, where the snail decides what it wants to do (right now if it curious it simply tries to approach the object). It then fires relevant motor neurons for approach (ie left, right, up, down, based on where the snail is in relation to the object it's trying to approach).

It's all very rough right now and there's a LONG way to go. Now that movement is more correctly represented in the jar based on the above snail movements (though not entirely) I think I'll go back to brain work.
Logged

Liza
Level 1
*



View Profile WWW
« Reply #27 on: October 15, 2014, 12:19:15 PM »

It is happening!

The brain has been driving me crazy  Droop

I know you wouldn't think so, but making a brain is pretty hard.

I had mating working before, but now that I'm trying to make all snail behavior go through the brain I had to basically reimplement the trigger for various mating events _and_ build stuff like snail instincts and memories for mating.

The basic gist is similar to biting (which is the motor neuron that gets triggered when a snail is near what it thinks _might_ be a food source, or sometimes another snail).

  • Snail notices an object using its sensory neurons. It might be an item or another snail
  • Snail decides if it's curious or not (partly based on scent signature and the snail's currently simplistic sex and food drives)
  • Snail approached object and MAYBE tries to mate with it (or bite it, or do nothing)
  • Other snail sees if it wants to reciprocate
  • Snail's currentArousal goes up each time it mates.
  • When currentArousal >= requiredArousal, it's sexy time
  • Breeding event is created
  • Egg laying event is created
  • Eggs are laid within an hour of breeding
  • Eggs hatch within 24 hours
  • Baby snails!!  Toast Left

So at first I ran into various problems like snails trying to repeatedly mate with lettuce leaves, then snail attacking each other instead of mating and trying to run away, then snails going on hunger strikes, etc. But eventually the snails mated!!! And eggs were produced! Unfortunately...I have no exhaustion or sex drive lowering functionality in at the moment, so they just..kept mating. And laid FOURTY TWO EGGS. I tried to drag them apart (I had to make drag/drop functionality to easily test all this, to be able to relocate snails quickly within the jar), but I left for like five minutes and when I got back they were on top of each other and at it again!

I recorded the whole thing in a blog post: http://liza.io/snail-mating-the-brain-version/

It is now a day later and the 42 snails have hatched. The problem is....maturity isn't taken into account when mating yet, so I ended up with all these baby snails trying to make MORE BABY SNAILS. I put in some temporary solutions (snails have to be of a certain maturity to initiate breeding, if an older snail tries to mate with an immature one the baby snail runs away or bites back, etc). This negative reaction in the younger snail will hopefully also dampen the mood of the older snail to where it won't want to repeat the action again. We will see (so far it seems to be working).

I am looking forward to seeing the baby snails grow. When they first hatch they are almost invisible, so you can't see what their shells and patterns will look like until they're big enough to make out properly (should take a few hours)
Logged

Liza
Level 1
*



View Profile WWW
« Reply #28 on: October 22, 2014, 10:14:16 PM »

Now that I have the general snail approach/run away/bite/swallow/mate decisions working I thought I'd start on training. However, I quickly realized that it's too early for that. If I manage to do the snail's daily life right I may not even need an extra training feature because snails already learn by nature of interacting with things normally.

So I'm going to go back to expanding the range of interactions a snail can have in its jar and refining its decisions and memories.

Memories
Memories currently work like this:

  • A snail can store up to 5 sensory memories
  • If 3 or more sensory memories are stored about the same object, they get converted into short term memories
  • TODO: if the snail gathers enough consistent short term memories about an object they are converted into LONG term memories, which never get erased but CAN weaken over time

Biting vs swallowing
I have also implemented a the swallowing neuron. Previously, the snail could bite an item to swallow it. It could also bite another snail. However, biting can also be more of an aggressive action - just because a snail is biting something doesn't mean it wants to eat it. So when a snail does want to try to actually EAT something, it will swallow. Otherwise, it will simply bite.

Survivability
Snails are also tough to keep alive at the moment - they run out of 50% of their energy each day, and I am having to constantly throw food into the jar to keep them well fed. I have tweaked this slightly by calculating how many  bites a snail should be able to take between idle event checks (similar to movement). A snail takes a bite every 10 seconds. An event checking all snails' idle actions runs every 60 seconds, so every SWALLOW neuron firing will actually fire 6 times each minute (of course there is a way to specify a different interval if we are calculating for more or less time between checks).

Documentation
The codebase is getting large and I feel I need to start documenting the project better in terms of both design and technical documentation. I made a doc site on http://gastropoda.readme.io/ though it has no proper content there yet, just the very bare bones beginnings. I'm going to try to get some basics documented this weekend.

(I am also going to cautiously set the project completion to 20%...very...cautiously)
« Last Edit: October 23, 2014, 02:01:03 AM by Liza » Logged

Liza
Level 1
*



View Profile WWW
« Reply #29 on: October 26, 2014, 10:17:11 AM »

Making decisions has been tough. The decision making code is a huge mess right now.

I've decided to implement something along the lines of Maslow's hierarchy of needs. So far there are only two needs - food and sex. I made a separate "Prioritisation" neuron that handles both weight setting in the inputs _and_ later setting "motivations" for the snails when it comes to decision time (eg 'foodMotivation', 'sexMotivation').

It's working a bit better than the previous system (in that snails that refused to eat before are now eating), but is all still very experimental and needs to be refactored.

Training

I started implementing training, but then realized that because snails already learn from every day experiences in the jar, I should start by perfecting that process first. Because really, if I get this right in theory I don't even need any other explicit "training" functionality. And if I do want to build it (which I probably will), I can base it entirely on the existing behavior/memory/learning implementation.

Also, I took some time off of Gastropoda to play Beyond Earth this weekend, and hope to take more. So progress is a little bit slower.
Logged

Liza
Level 1
*



View Profile WWW
« Reply #30 on: December 21, 2014, 05:58:30 AM »

Gastropoda is still chugging away.

I've now deployed the app to an Elastic Beanstalk development environment. This will ensure that recurring events and such are persistently running on an external server with an external database for one (as opposed to stopping each time I shut my laptop lid..) and make it easier to show to anyone who potentially ends up contributing to it for two.

I ran into all kinds of trouble deploying this, but now updating to new versions _seems_ to be fairly painless, so I'm hoping the worst is over. I'm curious to see how much this tiny dev environment is going to end up costing me monthly, though.

I think now I have to improve the user-facing pages and the flow of new users being introduced to the app in general. I'd like to find a web designer to work with since my current hacky version of the website is pathetic, but it would be so much easier if they could actually see and play around with the simulation. This AWS deployment is a huge step towards that, but now I need to make it more user friendly. I've already started doing this by prompting a new user to buy a new jar if they don't have one, kind of taking them to the first step. But the vast majority of the simulation is very much _not_ self explanatory.

I ended up writing a blog post about the deployment process, too: http://liza.io/deploying-gastropoda-to-amazon-web-services-never-forget/
Logged

Liza
Level 1
*



View Profile WWW
« Reply #31 on: February 18, 2015, 02:54:06 PM »

The snail brain, while still very basic, seems somewhat stable now. By "stable" I mean a snail can survive and reproduce without human intervention if it has a steady supply of food.

When I first embarked on the journey to power my snails' actions with a simple snail brain I threw together this diagram in the middle of the night:



Now it looks a little more like this:



Many things need to be refined and added on to. For example, right now a snail's stress increases if it is claustrophobic. However, all snails tend to react aggressively to stress - I need to implement a fight or flight response. Snails either attack other snails or try to run away from the crowding. I alraedy have attributes like fear and aggression (based on stress), but so far aggression is the only one that actually affects the snail's action.

I'm also starting to learn that I should trust the simulation a little bit more. In the past when something weird happend I knew it was most likely a bug of some sort. But now I've been running into more and more behaviours that, while odd, are in-line with what should actually be happening. I'll use this breeding as an example.

Two of my snails - Baloo and Lemur - mated. Baloo ate all of the eggs except for one because he was feeling claustrophobic. Here's what the remaining baby snail's family tree looks like:



However, as the baby grew and its shell color and pattern became more distinguishable I couldn't help but wonder...how did a snail baby coming from two very colorful looking snails end up so...prune-colored. Remember that the snails are hermaphrodites. The gender symbols below only display the role each snail took on in _that_ mating. Their orientation ticks back to neutral post-mating. A snail that mated as a female in one session could mate as a male in another (based on a few factors).



So I took a look at the parents. In this breeding Lemur bred as a male and Baloo bred as the female. Here are four of the visual traits (I'd say the major ones, although pattern radius also plays a big role) and how they came to be (the bolded pairs are the ones that actually got chosen for Lemur's Bagheera as it was being conceived and the values on the right are the final color values and pattern shape chosen for the baby):



And actually...it all kind of makes sense. I mean obviously I'm not going into the actual color-picking here (ie how you get a certain color value based on parents after a dominant allele is picked), but the general gist looks correct at first glance. I guess an ugly prune colored snail _can_ legitimately come from colorful parents.

So out of curiosity I took a look at the dead babies. You can't really see what they'd look like by eye since they died as eggs. _But_ due to a bug that I've since fixed, they continued to hatch after death and just stayed at a scale of ~0.00001 (so almost invisible to the naked eye). I used Chrome dev tools to increase their scale to 0.5 and check out what they would've looked like:



So...all pretty ugly. Either this is as it should be or the actual color value calculations make the colors more and more muddy each generation. I wish it was that pretty green one that survived. But that is not a mess I want to wade into at 11:51 at night.
Logged

Nicholas Lives
Level 1
*


Catch of the Day


View Profile WWW
« Reply #32 on: February 18, 2015, 07:11:45 PM »

Oh man I love the concepts here. I always thought a horse racing game would be interesting, but snails make it even better!

I also notice you mentioned this is all placeholder art, so here's me throwing my art hat into the ring in case you're interested:

(It just so happens I just finished a snail enemy for our game, though it may be a bit too freaky for something like this)


(Pixel art screen for a side project)


(Cuter style I did for a jam game)




Feel free to PM me or email me at nicholaslives at yahoo -dot- com if ya'll are interested in any kind of collaboration. Great stuff either way though! Keep it up!

Logged
Liza
Level 1
*



View Profile WWW
« Reply #33 on: February 18, 2015, 10:06:00 PM »

Wow your art looks great! How do you feel about projects with some finicky technical constraints? I'll send you a PM with some details in a bit Smiley
Logged

Nicholas Lives
Level 1
*


Catch of the Day


View Profile WWW
« Reply #34 on: February 18, 2015, 11:12:48 PM »

Wow your art looks great! How do you feel about projects with some finicky technical constraints? I'll send you a PM with some details in a bit Smiley

Well I suppose it depends on what you mean by finicky, but hey I'm up for a challenge. Lookin' forward to that there PM dawg.  Gentleman
Logged
Liza
Level 1
*



View Profile WWW
« Reply #35 on: February 21, 2015, 06:40:26 AM »

Racing in Gastorpoda has been implemented for months in its most basic state, but has never really gotten the attention it needs. So things like jars, in-jar positioning, and movement ended up evolving past the stage of the racing and making the current racing system kind of an outdated one.

Basically, right now racing is kind of simulating my simulation of jar movement. But really, I now have jar movement so I don’t need to try to simulate it when racing. All I really have to do is create a jar, put the entrants in it, place an Attractor item at the other end, and watch them go.

Right now in racing the snails’ steps are calculated based on time. So we basically loop through all the entrants until they’ve all either finished or dropped out and record their places as they come in. I would later be implementing stuff like snail interaction if two snails are side by side (one snail might try to bite the other, for example). But if I just make the whole race take place in an instance of a jar I don’t have to worry about any of those things. The snails will interact naturally.

This does mean that I’ll have to reimplement some attributes I used in current races to work in a jar context. Things like initiative (which dictates which snail starts moving faster), endurance (which, when depleted, causes a snail to be unable to move any farther and drop out). So it won’t be a simple plug-in-a-jar-and-done thing just yet. I’m also creating a virtual user, Mr Casinir, who will own all of these racing jars (since we don’t want any individual user hosting a race to have ownership, otherwise they’d be able to drag the snails and items around and ruin the race).

So I guess I’ll be ripping out the whole current racing system and doing this instead.

Also - check out the cool new iteration of the snail by PureBredGentleman above, who kindly offered to contribute art for Gastropoda. This is just the first iteration of a new snail and I already like it a thousand times better than the ugly placeholders I’ve been living with for over a year now.




Two of the snails have also mated, so I'm waiting for the eggs to hatch tomorrow morning if they don't cannibalise them by then.
Logged

alvarop
Level 9
****


ignorant


View Profile WWW
« Reply #36 on: February 21, 2015, 11:41:53 AM »

Looking cool. The amount of detail you talk about just makes my brain explode each time I read this devlog.
Logged

i make games that can only ever be played once on http://throwaway.fun
Liza
Level 1
*



View Profile WWW
« Reply #37 on: February 21, 2015, 01:14:55 PM »

Looking cool. The amount of detail you talk about just makes my brain explode each time I read this devlog.

Haha good! Now let's hope I can implement all this stuff properly. I knew going into this that it was overly ambitious, but because it's a hobby project that's been in the works in some stage or another for about ten years now I didn't (and still don't) care.

I've got a really exciting other feature planned, but it would be such a big addition to the existing functionality that I'm still afraid to say it out loud  Who, Me?
Logged

Liza
Level 1
*



View Profile WWW
« Reply #38 on: February 22, 2015, 02:27:38 PM »

In my previous post I wrote about rethinking racing (aka ripping out the existing racing system).

Today I got most of the work done on that. There is a lot left to do, but as of right now:
  • A new jar gets created when a user hosts a race
  • When the race starts all entrants are placed into that jar in order of initiative, on the left end of the jar
  • An Attractor item is placed on the right end of the jar
  • The snails begin crawling toward the attractor item, their actions checked every minute just like in a normal jar. Snails can change direction and perform other actions live as this happens (and can be observed doing so)
  • As a snail touches the item its time is recorded and it is returned back to its parent jar in the owner's stable
  • When all snails finish and are relocated back to their owners' jars all items within the jar are deleted, and then the jar is deleted
  • The race is marked as "Finished" and results are displayed.
This has taught me that my way of estimating the snail's position (between its last current position and target position) is nowhere near accurate enough. The snail that was coming in first visually actually finished 2 seconds after another snail in the race. I'll need to work on this. Here are some screenshots:

Ready:


Go!


Why did this snail turn around?!


The last racer, straggling behind:


Race results:

Logged

Liza
Level 1
*



View Profile WWW
« Reply #39 on: May 31, 2015, 02:04:43 AM »

The Laravel 5 migration is complete and I'm back to substrate mixing and brain bug fixing!

Actually, I think now that basic mixing is done I'm going to do a few weeks of just bug fixing. The substrate has no effect on snails' attributes or behaviour yet, but it will. For now you can just mix different substrate items together into new substrate items.

I'm still not sure what the best way to create images for the custom-mixed substrate might be. The possibilities are pretty much endless - you can mix any substrate-type item with any other substrate-type item.

So what happens is - the user goes to their closet. They pick two substrate items to mix together. Then this whole mess happens:
 
Code:
protected function mixSubstrate() {
    $itemID1 = Input::get('itemID1');
    $itemID2 = Input::get('itemID2');


    $item1 = $this->findItem($itemID1);
    $item2 = $this->findItem($itemID2);


    $item1WeightG = $item1->template->weightG;
    $item2WeightG = $item2->template->weightG;


    $resultingItemName = Input::get('itemname');


    $item1Attributes = $item1->template->nutrition->getAttributes();
    $item2Attributes = $item2->template->nutrition->getAttributes();


    $imageTitle = preg_replace('/\s+/', '', $resultingItemName) . '.png';
    $fileToSaveTo = '/assets/img/items/terrain/custom/' . $imageTitle;


    $resultingImage = Utility::MergeTwoImages($item1->fullImagePath, $item2->fullImagePath, $fileToSaveTo);


    // Create resulting item template
    $resultingItemTemplate = new ItemUserTemplate();
    $resultingItemTemplate->description = 'Custom item created by combining ' . $item1->template->name . ' and ' . $item2->template->name;
    $resultingItemTemplate->weightG = $item1WeightG + $item2WeightG;
    $resultingItemTemplate->name = $resultingItemName;
    $resultingItemTemplate->typeID = $item1->template->typeID;
    $resultingItemTemplate->ownerID = Auth::user()->userID;
    $resultingItemTemplate->imageSubdir = 'terrain/custom/';
    $resultingItemTemplate->imageName = $imageTitle;
    $resultingItemTemplate->save();


    // Create resulting item nutrition template
    $resultingItemNutrition = new ItemUserNutrition();
    $resultingItemNutrition->templateID = $resultingItemTemplate->templateID;
    foreach ($item1Attributes as $key => $value) {
        if ($key !== 'templateID' && $key !== 'updated_at' && $key !== 'created_at') {
            $resultingItemNutrition->$key = $item1Attributes[$key] + $item2Attributes[$key];
        }
    }
    $resultingItemNutrition->save();


    // Create item of new template
    $resultingItemProperties = [
        'templateID' => $resultingItemTemplate->templateID,
        'ownerID' => Auth::user()->userID,
        'isUserTemplate' => 1
    ];
    $resultingItem = $this->createNewItem($resultingItemProperties);


    // Delete original items
    $item1->deleteItem();
    $item2->deleteItem();


    return Redirect::back()->with('resultingItem', $resultingItem);
}
To actually create the image for the new item I added a new utility function:
 
Code:
public static function MergeTwoImages($imgPath1, $imgPath2, $fileToSaveTo = null) {
    $x = 50;
    $y = 50;
    $root = $_SERVER['DOCUMENT_ROOT'];


    $finalImage = imagecreatetruecolor($x, $y);
    imagesavealpha($finalImage, true);


    $sortedImages = [$imgPath1, $imgPath2];
    sort($sortedImages);


    $image1Layer = imagecreatefrompng($root . $sortedImages[0]);
    $image2Layer = imagecreatefrompng($root . $sortedImages[1]);


    $opacity = 50;


    ImageCopyMerge($finalImage, $image1Layer, 0, 0, 0, 0, 50, 50, $opacity);
    ImageCopyMerge($finalImage, $image2Layer, 0, 0, 0, 0, 50, 50, $opacity);


    header('Content-Type: image/png');
    if ($fileToSaveTo) {
        $fileToSaveTo = $root . $fileToSaveTo;
        imagepng($finalImage, $fileToSaveTo);
    }
    return $finalImage;
}

The results look like this (this example is experimenting with mixing 1kg oak leaves with 1kg sand):



It'll do for now. After some bug fixing I'll go back to substrate and start having it actually have an effect on the snails.

The above is using placeholder terrain. Nick has made some excellent terrain illustrations since that I've been using since, looking much better than my dodgy icons:



Logged

Pages: 1 [2] 3
Print
Jump to:  

Theme orange-lt created by panic