Liza Shulyayeva

On Your Mark, Get Set, Crawl!

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: Gastropoda race start

Go! Gastropoda race progress

Why did this snail turn around?! Gastropoda race turnaround

The last racer, straggling behind: Gastropoda last racer

Race results:

Gastropoda race results

Rethinking Racing. Also Cool Snail Art!

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 Nicholas Lives, who kindly offered to team up for 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:

Gastropoda snail 1Gastropoda snail 2Gastropoda snail 3Gastropoda snail 4

You should also check out the game he’s working on, We Need to go Deeper.

Snail Brain Semi-stable and Reviewing Visual Traits Set During Breeding

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:

Gastropoda snail brain draft 1

Now it looks a little more like this:

Gastropoda snail brain draft 1

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:

Lemurs Bagheera Family

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).

Lemurs Bagheera Family Tree

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):

Lemurs Bagheera Visual Traits

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:

Lemurs Bagheera littermates

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.

From Amazon Web Services to Digital Ocean

Amazon, I quit.

I tried, Amazon. I really did. For the last few months I tried to make it work with an EC2 instance for Gastropoda. I tried two main methods of deployment, both of which worked sporadically at various points:

  • Elastic Beanstalk. Main Problem: Alongside seemingly miscellaneous issues causing EB to terminate and re-spin-up EC2 instances, it would also spin up these new instances in wrong availability zones, causing instances to not be deployed in the right zone to utilize by reserved instance.
  • CodeDepoy. Main Problem: CodeDeploy was my preferred solution. It worked great. Push to GitHub and it would start a deployment. This was a bit more nitty-gritty to set up than Elastic Beanstalk, but also provided more control. However, one day my EC2 instance just couldn’t be connected to…by anything…

I ran into various problems with the EC2 instance itself regardless of deployment method. The last straw was my EC2 instance suddenly going down one day when nothing was being deployed or changed at all. Or rather, it said it was up, but nothing could connect. I tried a few different solutions and configurations, tried cloning the instance, setting up a new one, etc. Finally I got sick of it. I’ve heard great things about Digital Ocean from many sides, including the Laravel community. During this latest bout of EC2 problems @lauhakari and @niklasmodess recommended Digital Ocean again and finally I caved.

I set up a $5 droplet on DO and was fully operational by the next day. It still gives me plenty of flexibility and control, but somehow it’s just not as fiddly. I decided to try out dploy.io for autodeployment. After a pain free setup everything seems good knocking all the wood.

“We want to help”

The funny thing is that the Amazon twitter account has a couple of times told me they want to “help” when I mentioned having EC2 problems on Twitter. They recommended I post my issue on the AWS forums. While the social media response is admirable, the offer of assistance rings hollow. I have made threads on the forums and have seen others make threads - usually after one fairly speedy response from Amazon, which tends to not solve much, further communication in the thread is dropped and no more support is extended. Usually you end up solving the problem yourself or it magically resolves itself a few weeks later (which is actually what happened in the case of the last thread I created about Amazon’s GitHub autodeployment instructions failing).

I should note that I am still using S3 for this blog. But as for EC2…I think I’m done.

Snail update

Gastropoda has been chugging along slowly but surely. I’m focusing on fixing bugs in the brain and the snails’ environment detection. I need to move on to racing functionality soon, but I don’t want to do that until I make sure that the main brain stuff is working as it should.

I have also added item rot. Some items (usually consumables) will rot and disappear from the jar if left in there too long. Some snails will later also be more picky about the kinds of food they eat based on its rot stage (keep in mind snails tend to actually prefer slightly rotten food).

One interesting bug I ran into recently was a weird error message about eggs not being able to hatch. They couldn’t find the jar they were meant to hatch into! After some digging it looks like the doe snail actually somehow died mid-mating, resulting in the eggs being laid in jar ‘0’ (basically the death or unassigned jar). Then when hatching the snail eggs were trying to get some jar attributes, but since it didn’t exist everything just failed miserably. I did have a check for this implemented on snail death (if a snail dies all of its unlaid eggs are meant to be deleted), but I guess there was some sort of timing issue there. I added a second check during actual hatching just in case.

It’s Not So Bad. We Have Snail Babies, After All

Sometimes I think about what I’ve been working on in my spare time since the beginning of last year and I’m like “What the crap, Liza. You’re spending your time trying to make toy slugs. Go learn a useful skill or something.”

The reason I keep getting drawn to simulations in the first place is the idea of virtual life, something with some sort of autonomy and - ok, I’ll say it - sentience. I know I won’t get to this point with my snails.

All aboard the robot train


JakeThompson: Karinario told me that he likes you…but don’t say that I told you ok?
Guest14361: Ok
JakeThompson: ok then….
Guest14361: Do you hate life?
JakeThompson: Can’t say that I do…
Guest14361: Mmk
JakeThompson: *hits computer* stupid thing.
Guest14361: Calm down
JakeThompson: But I don’t want to calm down
Guest14361: Do you hate me?
JakeThompson: Never! ure like the coolest person ive met so far
Guest14361: Awe thank you
JakeThompson: No prob.
Guest14361: I’m ugly
JakeThompson: Have you always been ugly?
Guest14361: yes
JakeThompson: Great…People say that I’m in denial….I wonder why that is…
Guest14361: People suck
JakeThompson: What’s your favorite food?
Guest14361: Pizza
JakeThompson: uh huh
Guest14361: What’s you’re fav food
JakeThompson: Figure it out yourself.
Guest14361: Pizza?
JakeThompson: Before you go any further, can you make sure that you’re actually making SENSE from now on?
Guest14361: You’re an asshole
JakeThompson: That was mean.
Guest14361: Bye!
JakeThompson: Bye.
Guest14361: Bye!
JakeThompson: Stop repeating yourself.

When I was a teenager in Alabama I spent a couple of years working on this chat bot on a site called Personality Forge. Thousands of keyphrases and responses later I had a bot who could fool a few unlucky people into believing that he was a person for a little while (mostly if they catered the conversation to his training in vulgar themes, which were among the more popular topics with passing human speakers) and managed to place something like 13th in a yearly chat bot contest called The Chatterbox Challenge. But just like with snails, the idea that drew me to wanting to make a chat bot in the first place wasn’t the thrill of having a program fake a conversation with a few hardcoded sayings. I guess I was excited about playing a game in which I simulated a truer simulation of life, AI twice removed.

I was trying to find out some old details about my bot on Google for this blog post and ran into this in my search - a snippet of a book in which he turns out to have been extremely briefly mentioned. It’s pretty cool to see your bot’s name in a book (I actually considered buying it because it sounds like a really interesting read, but it apparently costs >$170 on Amazon - what?!), but the context is actually kind of what I’m ranting about here:

“Examples of the ‘best’ chatbot answers to the remaining eight questions in the round assessing ‘regular’ conversational systems, as awarded with maximum 4 points by Shah as judge in CBC 2005, are shown below (the name of the system is left of their response):

Do you like me?
Jake Thompson: One hundred percent!”

-Creating Synthetic Emotions through Technological and Robotic Advancements by Jordi Vallverdú

After once again spending too long trying to remember my password to the Personality Forge, where the bot was made, I tried to dig up the response in his language center but could no longer find it - I must’ve made some change since the challenge. But here’s how he would respond to a question of “Do you love me?”, which would be pretty similar to how he’d have treated the above. You can see the original keyphrase affects his mood (asking the bot if he likes you will give him +1 to happiness and be treated as a high-importance phrase judging by the rank). In this case he wants the speaker to reveal their own feelings first and then answer based on this:

Do you like me?

The whole bot is this. Hardcoded keyphrases and responses with some wildcards thrown in and some rudimentary “mood” magic. I don’t know why most people make chat bots. Maybe the above generic response of “One hundred percent!” would be acceptable for some since it manages to not sound completely off-base in relation to the question, but when I saw my bot’s replies to The Chatterbox Challenge judges’ questions back in 2005, and the responses of bots who were much much more sophisticated than this, all I could really feel was disappointment. When you look back at the transcripts some may be amusing and it might be pretty cool when the bot manages to carry on some sort of conversation, but it’s so clear that it’s just a hunk of nothing underneath. At the time I wanted to make something more like ALICE, but even ALICE didn’t live up to the thing that made me like the idea of chat bots.

If I wanted to make a more “proper” chat bot it would have to be a learning bot. Learning bots back then to me sounded fascinating and still do. Maybe, maybe one day a chat bot capable of learning could surpass its programming, is what my wishful thinking is telling me. At one point I was interested in trying to make one of those, but then I got distracted by other things and eventually by snails.

Fake it till it makes it?

At Interzone Games I got to work with a lot of really smart people. One of them was Jason Hutchens, who created a chat bot called MegaHAL (and before that HeX, who won the Loebner Prize Contest in 1996). I remember right before I had actually accepted the job offer (or maybe soon after) the whole team went out for drinks and we talked briefly about the idea of strong AI and intelligence in relation to robots. That’s the first time I remember actually talking about this with anybody in person and it was interesting enough for me to still remember parts of the conversation despite the alcohol consumed that night. We talked about whether the definition of intelligence even matters - maybe if the bot is good enough to make people think it’s intelligent, that qualifies it as intelligent. Maybe that’s all you need. I mean, everyone I speak to in real life could be a robot, but I perceive them as intelligent, sentient beings because they manage to convince me. And that makes sense - if a bot can fool you into thinking it can think or is sentient or whatever it is that you hope it would be, maybe we should just accept that it is. But the real test is probably not a bot fooling some random external person interacting with it. I think the real test is the bot fooling its creator.

My Personality Forge chat bot could never have fooled me into thinking he’s intelligent or sentient (even if he could fool other people…which he also can’t). I know he’s just a collection of preset phrases. I can talk to him and often remember exactly when I put in a response and why (usually I’d peruse transcripts, find parts where he’d get stuck, and add responses to those parts as I went - that’s how his language expanded and became so questionably-themed). Even if I can’t remember adding a certain phrase now, years down the line, all I have to do is go into his language center and do a search. The other thing is lack of change. My bot has been a 16 year old “human boy” since 2003. He never changed or evolved into anything. Life changes. In a true life simulation, the subjects have to change somehow.

So the snails

I guess the snails were a way for me to try to go one step beyond a rudimentary chatbot. Snails are considerably lower on the totem pole than humans in terms of intelligence, but I figured that would allow me to build in much more perceived depth and realism by simulating a simpler system better. It’s not even artificial “intelligence” that I care so much about as opposed to artificial sentience. But just like with a chat bot, I don’t think these snails are ever going to surprise me or convince me they’re anything more than a bunch of hardcoded behaviours. It’s the same thing, really, just in a different format. There are a few positive enhancements, like:

  • Unlike the chat bot, my snails do change. They are born, experience their jars, form memories which influence their behaviour based on those experiences, and die.
  • They do sometimes do things even I don’t expect. But this tends to be a fluke - if I don’t expect something it’s probably a bug anyway and not an indicator of anything special or in any way truly autonomous.

So I have to make them better. I think the further I get with Gastropoda the less satisfied I become with the life side of things. Looking back it’s painfully obvious that all of the layers I’ve been adding - visual and behavioural attributes, genetics, now the brain - have been weak attempts to make my own creation be able to surprise me.

But hey - it’s not all hopeless. We have snail babies, after all.

Gastropoda tutorial

Snail Gym vs Training Jar

I’ve tried implementing a gym for Gastropoda a couple of times now. Both times I put the feature on hold not because I got stuck, but because I realized that I may not really even need a gym.

What I wanted was a way to quickly train snails (that is increase their performance stats like speed and endurance), but not cheat - I wanted to have the training utilize the existing snail brain. So as opposed to have a user click a dropdown to “Run a snail around a track” and then magically give it +5 maxSpeed, I wanted to have a user select what terrain they want the snail to crawl on and then give them items to react to (like an “Attractor” item that would make the snail crawl across the terrain toward it). Then, for example, crawling across a terrain of grooved glass might improve the snail’s endurance or strength.

I simulated a jar in the gym to do this. Basically I’d create a temporary “training” jar that wouldn’t get saved in the database and offer the user dropdowns for which terrain to apply, which item to place (and how far away), and what treat to give the snail (if any). The user must already have these items in their closet (so they would’ve had to purchase them previously). Then I could check the snail’s reaction to the item/s by using checkOneInput() in the brain, as many times as I want. This would allow the training process to go quickly (since I could just loop through however many iterations of checkOneInput() I want, display the snail’s reactions/movements, and modify attributes based on what happens).

However, each time I found myself trying to simulate the behaviour of a jar and…well…I already have jars, so when I get to this point I wonder why not just make it a jar?

The one problem with this is that snails are slow. With my original gym above I could loop through training actions quickly and display the result to the user within moments. Here they would essentially be dealing with watching a snail crawling around very slowly with no rapid feedback as to what is actually happening. So I have a decision to make:

  • Find a way to fast forward actions inside a training jar
  • OR make training a long term process, unlike many traditional life sims

I am leaning toward option #2: having a training jar be just like any other jar (no distinction whatsoever, the label “training jar” would basically just be in the user’s head). Sure, it means the training process would be more long term, but it’s snails - that’s how it works. Since I’m trying to make a life simulation and not a game here, I don’t need to provide instant gratification to the user.

But I guess we’ll see what happens! For now I’m going to do a large refactor and then move on to implementing terrains for normal jars.

The Journey Continues - From Elastic Beanstalk to CodeDeploy

A little while ago I wrote about deploying Gastropoda to an Amazon Web Services EC2 instance via Elastic Beanstalk. Since that day I have been running into multiple EB problems. I’m sure that if I took the time to learn I would figure out why these things were happening and how to fix them. Some problems included:

  • Instance starting to fail with unknown errors and nothing in the logs after a bad composer command that is added and then removed. The only fix I could find for this was rebuilding the environment.
  • No way to specify exact availability zone when using VPC, causing my reserved us-west-2b instance to not be utilized and resulting in my having to request zone changes for my reserved instance whenever Elastic Beanstalk spun up a new instance in the wrong zone.
  • Attempting to fix the above with a command and Options.txt file recommended in documentation and AWS forums, only to be unable to get the actual command to even be recognized.
  • Elastic Beanstalk seemingly terminating and recreating EC2 instance without warning or notice.

I learned that Amazon has another deployment option - CodeDeploy. It’s much different than Elastic Beanstalk and doesn’t seem to manage as much stuff for you, but appears to provide more control and doesn’t decide to terminate your instances at random. So I manually created a brand new EC2 instance in us-west-2a to match my reserved instance and have been able to work with it without terminations or any other weirdness.

CodeDeploy can deploy from either an S3 bucket or GitHub. I’ve set it up to work with GitHub and so far it’s been great.

I want it to be easy for potential collaborators to deploy new versions of the app to the development environment, so was looking into various CI options. Two that I came across were Wercker and Codeship. Both were quick to set up, but Codeship was surprisingly pain free and awesome. However, the free plan only allows 100 builds per month which I have a feeling will not be enough for me. And because Gastropoda is just a hobby project that won’t be monetized, I don’t feel like spending money on a CI system on top of existing web hosting and domain costs. Codeship does apparently provide discounts for educational and non profit projects sometimes, but no matter how small those monthly costs add up and I’m not made of enough money to pay for all these services for a project that won’t make any kind of return on investment.

So I started experimenting with GitHub hooks - if I can set up a hook to automatically trigger CodeDeploy I will be able to avoid using a third party CI solution to automate the whole shebang. I started off by following the instructions in this blog post about integrating GitHub with CodeDeploy, but unfortunately this isn’t yet working. I keep getting a very vague error on the GitHub service. I’ve posted on the CodeDeploy forums and apparently at least one other person is having exactly the same issue. Hopefully I’ll manage to get it resolved soon. In the meantime I’m just triggering manual deployments from my GitHub commits via the CodeDeploy dashboard.

Personality

Every morning I wake up to my cat Rigel wanting to play. He jumps around the bed and brings in his favorite toy ferret, purring and stepping on us until we either get up or put him outside. Then I get up and go to get a plastic bag from the kitchen before I do anything else. I go to Rigel’s jumbo sized litter box, followed by the cat who sits next to me and watches as I clean it. As soon as I’m done he steps inside and does his business. Meanwhile, I leave to wash my hands and start washing up/brushing my teeth in the bathroom. One or two minutes later Rigel turbos in, jumps full speed onto the toilet (I always have to be sure the lid is closed before this happens - there have been incidents) and then into the sink, sticking his head and paws into the water (which I make sure is lukewarm before he gets in). We take turns at the tap for about five minutes. I leave, he sometimes rests in the sink, and then the morning pooping and cleaning ritual is over.

I remember thinking how nice it is that our cat “has a personality” during one of these mornings. It’s comforting that your pet has his own tendencies and habits. And really, I thought, a personality is just the predictable parts of someone. I like that Rigel repeats these steps predictably with me - that’s partly what makes him stand out from any other random cat. It makes you feel like you know him personally and that he has a mind of his own that has formed its own habits and ideas about the world around it - its own personality.

I think snails can also have personality. Reading any number of pet snail forums you’ll see snail owners talking about how some snails like to be handled more than others; some snails love reaching up into a stream of water and others balk at it; some snails will eat a variety of foods whereas others will get hooked on cucumbers. The snails in my simulation, too, need to feel like they have personality. They need their own patterns and habits.

I’m hoping that since the snails already store and reference sensory, short term, and long term memories this can naturally turn into snails’ tendencies to react to certain situations. But right now in the simulation the vast majority of stuff happens under the hood. A snail may be making a decision based on several memories of an object, but as a user you wouldn’t even know it. You’d think “Huh, this snail decided to escape this lettuce leaf for some weirdo reason that doesn’t immediately make any sense to me”.

I need to make these patterns more visible somehow - make the reactions more obvious to the end user.

I’ve already done that in part with the Lab, where you can combine snails and items together (or snails and snails) and see what the snail’s five first reactions are. It’s kind of like a simulation of what they would do if they were in a jar and ran into another object on their own (except in a jar they may also be impacted by stuff like claustrophobia and in a lab environment this would be different).

Anyway, it’s something I have to keep in mind as I continue working on the brain and the snails’ actions.

State of the Snail, 2014

It’s been a long year for snailing. My simulation got a name, my snails got a brain, and a dev environment was deployed outside of my poor little MacBook Air that’s been chugging away like crazy with all the server and VM crap I’ve had to host on it.

I think this is the longest hobby project I’ve ever worked on. I’d say it’s maybe 20% done, but who knows - I’m not rushing to the finish line with this one. Over the past few months the thing that’s been taking up most of my time with Gastropoda is the brain. As soon as this little component went in the simulation became much less predictable and tougher to debug. It’s been a lot of waiting, fixing, waiting again, trying to see why snails made certain decisions that didn’t make sense, etc. It’s still largely like that now, but I think it’ll be worth it in the end.

Here’s an overview of what’s currently implemented in one form or another:

  • User registration/login system
  • Catching of wild snails
  • Snail breeding
  • Optional arrousal suppressant in breeding jars
  • Snail decision making via snail brain (includes feeding, mating, biting so far)
  • Snail recognition and memories
  • Virtual currency
  • Virtual store
  • Purchasing/installing jars
  • Purchasing food
  • Scheduled food delivery service
  • Drag/drop snails and items to reposition within jar
  • Live view of snail positions on jar profile pages via Latchet
  • Snail racing
  • User race creation
  • Basic tutorial
  • Snail scouting (get exact speed, endurance, macro requirements, etc)
  • Snail relationship testing
  • Two food items (macros matching real life information)

Most of these are not at all in their final form. I think breeding is the most fleshed out of the “big” features, but even that will need revision. The most recent thing I did was the tutorial. Up until now you got zero information about what you’re meant to actually be doing after you log in for the first time. This kind of sets you on the right path. It also sets your character and stable names as part of the same process.

Gastropoda tutorial

First Gastropoda priorities for next year:

  • Keep refining brain
  • Flesh out racing, lots to do here
  • Improve the actual site
  • Snail breeding and selling between users

Wish me luck!

Oh and Happy Holidays from my cat.

Rigel Christmas Card

Deploying Gastropoda to Amazon Web Services - Never Forget

After my last blog post I decided that it was time to deploy Gastropoda to Amazon Web Services - namely Elastic Beanstalk, which utilizes an EC2 instance (reserved) and an RDS DB instance.

I started last Saturday. I’ve just now gotten something running that seems on par with what I have on my vagrant box. I have decided to put together a post of random tips for myself so that I never have to go through this nightmare again the next time I have to set up a new Elastic Beanstalk app or environment.

I started off mostly following these very helpful Laravel deployment instructions. These set me off on the right track, but there were so many obstacles that I ran into that just following this wasn’t really enough.

So…notes.

Differences from instructions above

  • The environment config file in the above ended up not working for me. The environment that was created with eb start was a t1.micro instance instead of the specified t2.micro. This led me to think that other settings probably weren’t taking either. I ended up creating an environment manually through the Elastic Beanstalk dashboard.
  • The environmentVariables config was also for some reason not being applied, specifically - not finding the DB_HOST environment variable. I ended up creating a new set of configs for a development environment in app/config alongside the local config and set my db login information there. Then bootstrap/start.php I added the development environment to detect:
$env = $app->detectEnvironment(array(

    'local' => array('homestead'),
    'development' => array('hostnamehere'),

));
  • To get the hostname, remote into the EC2 instance and run hostname
  • However, this wasn’t working consistently, so to be safe I also forced a specific environment in .ebextensions/02artisan.config:
container_commands:
   01migrateSeed:
      command: "php artisan migrate --env=development --force"
   02seed:
      command: "php artisan db:seed --force"

Migrating and Seeding Database

  • I used Xethron’s Migrations Generator to generate a migration from my existing DB schema on the vagrant box. This was quick and painless.
  • What wasn’t so painless was the migration’s inability to run foreign key commands. There were all kinds of foreign key dependency errors, so I removed all foreign key migrations because by this point I wanted to rip my hair out.
  • I then created seeders for all of my template tables, which are:
    • race_terrains
    • snail_history_templates
    • item_types
    • item_templates
    • item_nutrition
    • recurring_events
  • Seeder example:
class RaceTerrainTableSeeder extends Seeder {

    public function run()
    {
        DB::table('race_terrains')->delete();

        $statement = "
                        ALTER TABLE race_terrains AUTO_INCREMENT = 1;
                    ";
        DB::unprepared($statement);

        DB::table('race_terrains')->insert(array(
                array(
                    'name' => 'Plastic Tabletop',
                    'description' => 'A smooth, plastic tabletop - lightly misted with water'              
                )
            )                 
        );
    }
}

The $statement above is very important. Before I added this, the auto-incremeneted primary key would keep counting up from the previous batch each time I deployed a new version of the app. This broke everything, since I had code and other tables referring specifically to various IDs. This makes sure the IDs increment back from 1 each time the table is seeded.

  • I started off using MySQLWorkbench, but am now using a trial version of Navicat MySQL to connect via SSH - much better

Cron job

  • I had to set up a cron job for Dispatcher to run various events (like recurring store restocking and deliveries, race events, breeding events, etc). I ended up doing this in .ebextensions/01composer.config:
container_commands:
   01optimize:
      command: "/usr/bin/composer.phar dump-autoload --optimize"
   02dispatcher:
      command: "cat .ebextensions/dispatcherJob.txt > /etc/cron.d/dispatcherJob && chmod 644 /etc/cron.d/dispatcherJob"
      leader_only: true
  • dispatcherJob.txt looks like this. Remember that it requires exact path to php and artisan and must have a newline at the end:
* * * * * root /usr/bin/php /var/www/html/artisan scheduled:run > /dev/null

Logs and Storage

  • To get logs from EC2 instance, use this example: scp -i path/to/.pem ec2-user@public-ec2-instance-ip:/var/www/html/app/storage/logs/error.log .
  • The chmod to the storage directory keeps getting reset with each deployment. Currently adding this command to .ebextensions/01composer.config under container_commands seems to have worked. I know, I shouldn’t use 777…will try to lower this as much as possible and see what happens.
   03chmodStorage:
      command: sudo chmod -R 777 /var/www/html/app/storage

More most likely to come…