Liza Shulyayeva

Snaily Updates - Bug Fixing and Cleaning Out Old Stuff

Snaily Updates are going to be really brief posts with some short “daily” updates on SnailLife. I haven’t updated in a while because I’ve mostly just been refactoring and bug fixing. But it’s important, and even though I’m not working on new features right now I still want to document some of my progress and what I do each day.

  • Fixed an issue with migration to dead snail table trying to set snail position in a non-existent jar.
  • Added message template for egg hatching
  • Renamed UserMessageManager to UserMessageSender
  • Renamed SnailHistoricalEventManaer to SnailHistoricalEventGenerator
  • Get rid of BreedingController as everything it was used for is now in more specific classes
  • Get rid of SnailOrganController
  • Get rid of TrainingController since there is now no unique training functionality - all snail conditioning is done via interaction in jars and pre/post race action assignments.

My Account Deletion Saga

Update 3, Nov 2 2015 (PM): Well, it’s been…strange. First, it seems my account was finally deleted by (thank you!) After being up all night with libel posted all over it, hours after Jamie Green (the other Livecoding co-founder) and Sam Altman (Y Combinator president) replied to the Hacker News thread claiming they were trying to do something, something finally happened. I have heard nothing from either of them since their original comments and am not sure exactly what spurred the removal of slander from the profile and its eventual deletion. I know some other Livecoding users quit and had a discussion with the CEO in live chat also.

The account was then recreated, seemingly by a third party under the same username. They originally replaced a modified version of the libel on the profile and eventually changed the description. It seems to be someone else who has a problem with and maybe wanted to use this whole saga to their advantage.

First, the CEO of Livecoding has again emailed me this morning and, almost unbelievably, tried to lie yet again. This was before the deletion was done. Our email conversations consisted of this (messages go from bottom up):

He then went to the Hacker News thread about this and started posting defensive copy-pasted comments telling people they were cowards for not listing their names. After this there was more of pretty much the same on Twitter - copy-pasted replies to tweets about Livecoding.

Some responses to this weird and confused behaviour and this unbelievably bad response to the situation on HN have been borderline, and in some cases over-the-line, cruel. As I mentioned in a comment on the thread, I did not write this post to make a joke out of anyone or be cruel to a person who now seems like they might be unwell. I am the last person to defend how has handled this and don’t plan on censoring any accounts of my experiences with them, but in my opinion it is important to stay mature in these interactions and not become a complete asshole.

Anyway, at this point with my account deleted (though username now taken by someone else, but they have now removed my name from the new profile) I think I’ve gotten the best possible outcome. It’s obvious that Livecoding still has no interest in treating this in a professional manner and that they have a lot of growing to do in terms of their approach to communicating with their users, but as long as my details are off of that site that’s all I can realistically expect at this point.

I really hope this post will not need any more updates.

Update 2, Nov 2 2015: The text on my profile has just been changed to “Marked for removal from database”. Perhaps they fixed their “cron job”.

@elgruntox mentioned on Twitter that that he just got banned also and actually managed to have an exchange with the CEO:

I’m not sure where the first line is coming from about any kind of information that they were “doing migrations” (I have had no such communication). I did have communication that my account was deleted as mentioned in the original post below, but that turned out to be false. My videos were already deleted because I deleted them myself one by one before they changed my password, put in a redirect back to home on my account, and updated my profile for me.

Anyway, it seems they removed the libel and replaced it with a more generic message. I guess we’re just back at square one now.

Update 1, Nov 1 2015: It looks like Livecoding have now taken the liberty of updating my profile for me, claiming I am “spamming them” after this review got some attention: link.

I guess writing an account of your experience with their site is somehow considered spam to Livecoding. How professional of them.

The original post follows below:

A few months ago I figured I’d try streaming my development of SnailLife (or parts thereof). I considered Twitch, but ended up going for a site called because it seemed smaller and more obscure. My main goal for streaming would be to keep myself focused knowing someone may be watching - I didn’t actually want to build any great audience for myself as I didn’t want to build up any kind of expectation of streaming, plus I knew that my streams would probably just be really boring. It was more a motivator for me to not procrastinate and browse Reddit or HN and focus on my work.

So I set up an account on Livecoding and did my first stream. A few people actually came in and asked questions about the project, which was cool. I got a message and/or email from someone from Livecoding asking if or when I was able to stream, or what my streaming schedule might look like. I said I would try to stream whenever I could, but with a busy job, a sick cat, and life in general streaming was simply not on my list of priorities so I could not commit to a schedule.

I streamed a few more times and then life got in the way as expected (ie my cat almost died) and I stopped. Once every few weeks I would get another message from Livecoding (outside of their usual automated newsletter) asking what my streaming schedule might be as well as saying that they want to get more female streamers on the platform. Basically emails like this:

“Where have you been? ;) We plan to heavily increase the number of female Livecoders so if you have ideas on how we could achieve this, let us know. Could you invite other female coders you know to”

And this:

“Hey Yeliz - This is Michael, founder of

I like your snail game. I want to use you to inspire other women and young girls to get excited about software development.

How often are you on”

Each time one of these came in I kept explaining that with everything else going on streaming was not my highest priority and I would not commit to a schedule - so in reply to “how often?” the answer was basically “not often”. At some point it got pretty frustrating to keep receiving these emails, but whatever.

A couple of weeks ago I got another email from Livecoding. “Viewer Feedback” - with “tips” on how to get more people to view my stream. Including handy items like:

Yeah thanks, Livecoding

This looked like an at least partially automated email, but I am not sure to what extent because in the few streams I did do I chose to not talk and just code, and maybe interact with people in the text chat when they had question. This was sort of the thing that led to my not feeling like being on Livecoding anymore. I just felt there was too much recurring pressure to stream when I clearly communicated that I will not be streaming regularly. Not only that, but I never wanted to stream to get a big viewership or cater to viewers - I wanted to stream for my benefit, to keep myself focused. These unsolicted “tips” indicated to me that Livecoding clearly did not seem like the right channel for this anymore.

I decided to delete my account until I can work with Livecoding’s expectations and actually stream on a regular basis as they kept asking me to do.

I quickly found out that you can’t just delete your account. You have to put in a support request asking them to delete your account. So that is what I did and here is the exchange that followed:

Asking Livecoding to remove my account Livecoding asks why I want my account deleted I explain my reasons for wanting to delete my account Livecoding promises to delete my account soon

So far so good. They asked why I wanted to delete the account, I explained, they said they’d do it soon. The next day I asked for some clarification on when the deletion would actually take place:

Asking Livecoding for clarification on when my account will be deleted

This was met with silence.

7 days later I sent another email, now feeling a little bit frustrated. It has now been over a week. Here is the exchange that followed:

Reminded by another email, I follow up with Livecoding on my account deletion Livecoding stating that their email newsletters are separate from their account deletion My explaining that despite the newsletter being separate, I checked and my account is still not deleted Livecoding states my account will be deleted 'on our next cron job. Nothing complex.' I ask when the next cron job is scheduled to run

My last question was, again, met with silence.

At this point I spoke out publicly on Twitter and got the following reply from Livecoding’s Twitter account - of course, my account would be deleted “soon”. I let them know that their last “soon” was over a week ago with no clarification of when their “soon” is. Guess what answer I got. That’s right. None, as usual.

Livecoding replies to my tweet: We'll process your request soon I let them know that their last 'soon' was over a week ago and that they have not yet clarified when 'soon' will be

So I started posting daily updates about the status of my account on Twitter. The situation at this point was frustrating and the incompetence was laughable. I updated my Livecoding profile to highlight the problem. I mused if posting some inappropriate content in my profile would encourage them to finally delete my account.

I didn’t post anything bad in my profile yet, but just the mention of it seems to have kicked some gears into motion, because I received this email this morning, from Michael the great Livecoding CEO.

Livecoding replies: sorry for the delay. We had a lot going on. Done now.

I guess that cron job had a lot going on. But hey, excellent! Something happened! All is right with the world! We’re all good!

However after checking the site I saw that my profile was still there…I was no longer able to log in at least. But judging by past experience and the fact that my profile was still visible I was suspicious and tried to change my password, just in case. Well what do you know - it worked. A password reset form was sent to me. Now I was getting angry. This seems to not just be a case of delay or plain incompetence - the Livecoding CEO just lied about deleting my account. I wonder in what world changing someone’s password amounts to an account deletion - Livecoding’s world, apparently!

Now angry at the blatant lie, I posted on Twitter about this and replied to Michael’s last email:

I reply letting them know that my account has NOT been deleted

He (or someone from Livecoding, there is no name signed anymore) quickly responded with the following:

Livecoding: Do you and your friends want to disturb us with this and spamming? We will just ignore you at this point

I’m not sure who “me and my friends” are. I think he was talking about my discussions on Twitter. We certainly haven’t been spamming, a couple of people have simply been discussing my issues with getting my account deleted. My response was:

I reply explaining why I spoke out publicly, asking if they ever plan to delete my account as requested.

And that was it. Again, the expected silence took over and there was no further reply. My profile still sits on Livecoding, undeleted. But they DID put in a redirect back to home on login attempt, presumably to make sure I didn’t post those porn links I joked about.

The seeming incompetence Livecoding management is just plain laughable at this point and I am still not sure what exactly their problem is with deleting an account. Are they just unable to do this? Is their system this crappy? Judging by their lie claiming my account was deleted when it was not it seems they actually want to keep my data and profile on their site for some weird reason. But why?! Why list instructions on how to delete your account on your website and then not honor them?

Of course there are sites that outright refuse to delete all of your information. Livecoding was not one of those sites - Livecoding repeatedly promised to delete my accout “soon”, then went on to claim it deleted my account when my account was still there, visible, and with a resettable password. The way they have handled this in such an unprofessional, misleading manner makes them seem totally untrustworthy and extremely shady in my mind.

I remember Michael’s request in one of his spammy manual emails from earlier: “Could you invite other female coders you know to”

Dear Michael: sure I can! But I won’t. I will instead warn other coders (not just female, since you may not know this but we don’t gather in gender specific female herds), but anyone interested in streaming their projects. Livecoding’s unprofessionalism, continued pressure to stream, unwillingness to let go of your data despite really loving the word “soon” is simply not worth the hassle.

So, Livecoding/Michael, here are some unsolicited “tips” from me to you this time:

  • Get a proper support person. Who is not you, since you are not good at interacting with your users.
  • If you must make people put in a manual ticket to delete their account, actually do what you say you will and delete their account
  • Do not lie to your users and claim you deleted their account when it is blatantly obvious that their account is still there. Out of the dilly-dallying, the seemingly non-existent cron jobs, etc, this is the thing that left the worst impression of Livecoding to me. When you start blatantly lying to people you know you just turned a very bad corner.

To use your preferred phrasing from before, processing a support ticket to delete a user account should have been “nothing complex”. I still do not know what your problem is with actually doing this.

Snail Organs, Immunity, and Ageing

Organs! Immune systems! Old age! Dying from old age!

I’m super excited. I was thinking: “How do I implement old age and death, and health in general? Is health just energy? When the snail is out of energy, it dies? But that seems too simplistic.”

At this point I should have realized that ‘simplistic’ is a good thing. Instead I decided to try to mimic a scenario that is a little closer to real life. Again, I am no snail expert or biologist and mostly I just…guessed. I want to tweak the system when I move more into the research phase of the project vs the implementing random features and fixing bugs phase. I have a feeling this should have been done the other way around.

Anyway - why does any living organism die? It seems that we die either because of some trauma or injury to our internal organs or…old age. But what is old age, really? How is it different from trauma or injury to our internal organs?

From the very brief amount of reading I’d done it’s partly about telomeres and how efficiently our cells can keep dividing as we get older. Telomeres protect our chromosomes. Each time a cell divides, our telomeres shorten until eventually our cells can’t divide anymore. And then what?

I think that’s when we become more prone to age-related diseases. The immune system is apparently highly related to the length of the telomeres. And when your immune system gets worse our bodies can no longer handle various illnesses as well as they used to, which eventually results in that first thing - trauma or injury to our internal organs that we can no longer recover from.

My cat Rigel has a damaged bladder. A vet “broke” him and he has been handicapped ever since. The bad news is that he may now need to be on medication for the rest of his life. The good news is that there is a chance, especially since he is so young, that his bladder will regenerate over time. The cells and nerves of his bladder may still kick themselves into shape over months or years and he may be able to take a little less medicine or maybe, if a miracle happens, eventually none at all!

This is how I want the snails to work. Organ damage can be sustained, but with a high enough immune system the snail may be able to recover and at least partially heal/regenerate itself. As the immune system weakens organ damage becomes permanent and the snail is not as able to recover. Eventually the snail is just too weak, its organs start failing, and it dies.

The details

I’ve kind of done it in a really hacky way…like all the experimental features so far…which is pretty much all the features.


So a snail has a base organ efficiency score and an organ efficiency percentage. Eg:

  • baseHeartEffic: 60
  • heartEfficPerc: 100%
  • baseLungEffic: 45
  • lungEfficPerc: 90%

The organs so far are:

Yes, I know a snail has more organs than this. But I have sort of stayed away from organs that already are represented by sensors in the brain. These include eyes (vision is accounted for), mouth (taste is accounted for), tentacles (touch is accounted for). They will be added eventually, but I wanted to focus on the others for now.

All snails start with 100% efficiency for each organ. At first I was thinking of not having baesXEffic at all and just have a 0-100 percentage for each snail, but I realized this would be boring. All snails are not created equal. Just as Secretariat had a very large heart, a snail can have a much stronger or weaker organ than average. A simple percentage standard across all snails would not allow for the amazing outliers of nature that we see in real life.


Snails already have a maturity rate (the rate at which they grow after birth). I decided to reuse this for ageing. Snails age every hour. Until a snail is mature it grows each hour based on its maturity rate. Once a snail is mature it begins to age and deteriorate every hour. The amounts may be small - something like 0.05% decrease in immunity per hour. You will be able to boost immunity with supplements, medicines, etc, but for now we are just focusing on the snail’s natural rate of ageing here.

Each minute we check for idle snail actions. Each minute we will also check for any organ damage as a result of those actions. For example, if a snail is operating at 95-100% physical effort it may have a higher chance of heart, lung, or foot damage.


I have not built recovery in yet. I want to see how long a snail might live without any recovery of the organs. Recovery is to follow!

Wild Snails Around the World

Did you know that there is an entirely separate formula to calculate the distance between two points on the surface of a sphere? I mean…it kind of makes sense when you think about it. The shortest distance between two points without accounting for the curvature of the sphere would go right through the sphere itself, making it pretty useless when calculating physical distance on, for example, the surface of the Earth.

I’ve been working on creating some variation in the attributes of wild snails you might catch in different parts of the world. It’s not perfect, but the snails you find in Mobile, Alabama now look generally different from the snails you might find in Stockholm, Sweden.

So far the general testing rules are thus:

  • The snail shells get less red and more blue in them as you travel away from the equator
  • Snail shells get more green in them as you travel East
  • Snail pattern colors are the opposite of the above
  • Snail eye colors are always randomized
  • Snail pattern shapes and sizes also remin random for now, but will definitely change with the region at some later stage

I have added an idealTemp column to the snail table. The ideal temperature of snails you find in the wild in various regions tends to change (warmer toward equator and colder toward the poles). This means you will need to be quite careful when trading with others or buying other people’s snails (or even sending your snail overseas for a race on a foreign track). You’d need to closely control temperature and evaluate how your snail might perform on a track where it is currently 40C when it is used to a temperature of 20C. Temperature conditioning will need to be a thing.

Admittedly with these rules the snails you tend to find end up being a little more boring. Instead of a totally random mishmash of colors you end up with something more constrained. But I think this is ok. Wild snails are not meant to be beautiful or exciting - users are supposed to breed for those traits. If you regularly find unique, amazing snails in the wild there won’t be as much incentive or excitement in learning about your snail’s genetic traits and breeding for a desired result.

As I mentioned before, it takes a couple of seconds for HTML5 geolocation to get your coordinates (and then a few more seconds to get city/country name via the Geoname API). If you for some reason click to search for a wild snail before your location is loaded the coordinates of the search default to the coordinates of your stable.

In addition users will eventually be able to release their snails into the wild. At first it will just mean that someone else can find them. Down the line maybe the wild snails will be able to breed amongst themselves and change the attributes of wild snails in that region.

I have taken some screenshots of wild snails you may find in different places. Here they are:

Mobile, Alabama, US

Setauket, New York, US

San Francisco, California, US

Perth, Western Australia

Stockholm, Sweden

Kyoto, Japan

The North Pole

More Location and Temperature Stuff

I realized I didn’t actually include any implementation details when writing my sleepy post about stable locations and temperature the other night. I figured I’d elaborate on that now.

Having never used HTML5 geolocation features before, I kind of winged it and hacked together something that works for now. Currently I get the user’s location in two cases - on registration, and when searching for wild snails.

Here is how it happens on the registration page:

        function getLocation() {
            console.log('getLocation here');
            if (Modernizr.geolocation) {
                console.log('geolocation in');
                navigator.geolocation.getCurrentPosition(createHiddenInput, geolocationError);
            } else {
                console.log('no native support');

        function createHiddenInput(position) {
            var latitude = position.coords.latitude;
            var longitude = position.coords.longitude;
            console.log('latitude: ' + latitude);
            console.log('longitude: ' + longitude);

            jQuery(document).ready(function() {
                $('#registrationForm').append('<input type="hidden" name="stableLatitude" value=' + latitude + '/>');
                $('#registrationForm').append('<input type="hidden" name="stableLongitude" value=' + longitude +'/>');
                $('#registrationForm').append('Stable Location: ' + getCityName(latitude, longitude) + ',' + getCountryName(latitude, longitude));


Problem - retrieving the location takes a few seconds. If the user happens to register too quickly their location will not be retrieved. As a potential solution I am considering disabling the Submit button until the location is ready…however, what if they don’t want to allow me to retrieve their location at all?

If the user does not let me retrieve their location, it will be set by default to some place in Louisiana. Maybe then I can just display a “Don’t want to be in Louisiana? Wait while we get your location!” message…

So the latitude and longitude is stored for the user’s new account. Then to get the country and city name when displaying where the user is we use the Geonames API. Example:

public static function GetCityName($latitude, $longitude) {
    $cityName = null;
    if (Utility::InternetOn()) {
        $url = "" . $latitude . "&lng=" . $longitude . "&username=myusername";
        Log::info ('connection');
        $xmlDoc = new \DOMDocument();
        $cityNameNode = $xmlDoc->getElementsByTagName("name");
        $cityName = null;
        if ($cityNameNode->length > 0) {
            $cityName = $cityNameNode->item(0)->nodeValue;

    return $cityName;

To get temperature I originally tried OpenWeatherMap but that seems very slow and unreliable. So I am trying out The Dark Sky:

public static function GetCurrentTemperature($latitude, $longitude) {
    $url = "" . $latitude . "," . $longitude;

    $JSON = file_get_contents($url);
    $data = json_decode($JSON);

    $f = $data->currently->temperature;
    $c = Utility::FahrenheitToCelsius($f);

    return $c;

The Dark Sky gives me 1000 free API calls per day. I blew through that in under an hour because I was stupid and calling the API each time I needed to get the temperature. Which is a lot…passive events alone blow through about 200 calls in 5 minutes.

So I added a currentTemp field in the User table and a temp_updated_at field. I added a recurring event to update the temperature once per hour.

Now it is time to start varying wild snail traits based on location you are looking in. I might even embed a Google Map on the wild-snail-collection page so that instead of just clicking “Look under a rock” or whatever you can click on a spot in your general vicinity on a map and see what snail pops up there!

Bringing Snail Stables Down to Earth

SnailLife snail stables have always lived in the ether - in some virtual universe with no physical location. Since I’m trying to make SnailLife based in reality, users’ snail stables should also be based in real locations. This is why now, upon registration, the user’s physical location is used as the location of their snail stable.

Right now in my snail stable it is 15.5 degrees Celsius. I don’t think I’m going to simulate building insulation, so without temperature control it would be about the same temperature in each jar (I may take humidity from the jar’s substrate into account, and have other items adding warmth or cold aside from temperature control gadgets). The user won’t see their exact jar temperature until they install a thermometer in the jar, and they won’t be able to regulate the temperature without installing a temperature controller.


Snail jars have had temperature for a long time, but now that temperature is influenced by real life weather at the stable’s location. This will in turn influence the snails within the jar: their health, mood, etc (this last part is not yet implemented…well, it is only implemented very very roughly).

Different snails will adapt to live better in certain climates, and you will find different kinds of snails in different places. This way if you happen to physically be traveling the world you could hunt for wild snails away from your stable and find totally different patterns, colors, and traits.

Of course, this can only happen if you allow SnailLife to get your coordinates by using HTML5 Geolocation feature. Right now there is no fallback…I was thinking of falling back on location of IP, but that might make it easy for people to cheat and place their stables in rare locations. For now I think I might put you in a really boring part of the world by default when geolocation is not permitted…

Aside from affecting snail health and such in the future, temperature in a jar already affects how quickly consumable items rot. Things rot faster at a higher temperature.

Up next I want to think of a good way to vary snail types based on coordinates. There will be some manually set snail types that are available only in certain areas of the world if I want to make some super cool rare location (eg - get a special snail if you’re at the NASA headquarters!), but for the most part I want to create that variation automatically. I just have to think of a good way to approach this.

Snail Stable Breeding Brands

I haven’t made a SnailLife update in a while, but I had a good reason! For about half a month I’ve been working on an entry into the js13kGames challenge. I’ve entered the challenge annually since it started and this year was meant to be no exception. Unfortunately…I wasn’t really into it this year. It felt like work, and with things at actual work being so busy I found myself not having the time or motivation to sit down and work on it after I get home.

When I work on SnailLife it tends to be relaxing, so I figured why mess with a good thing and decided to go back to snails!

The first thing I did to get back into it was implement stable brands. When a snail is born at a particular user’s stable, if that user has a 3 character identifying brand selected that brand is applied to the snail. It is then displayed in front of the snail’s full name along with its titles (have I talked about titles yet? Snails can become Champions and Supreme Champions if they win enough races). So a snail named Crimson Sunchaser born at Lazerbeam Stables who currently holds two Champion titles and 1 Supreme Champion title and has also birthed or sired enough champion foals to earn it the Champion Breeder title would have its full name displayed as follows:

[LZB] SCH CHx2 CHB Crimson Sunchaser

Ie… Lazerbeam Stables Supreme Champion, Champion x2, Champion Breeder Crimson Sunchaser

Of course most people would refer to this snail by its simple barn name, Crimson Sunchaser.

Currently held champion titles can change (if you get enough CH titles it turns into an SCH for example), but the stable brand can never be removed or modified. If a snail is sold, gifted, transferred in some other way - it will be permanently branded with the stable it was born in.

And that’s it for now! Up next I am implement pre and post-race snail instructions.

I Have Become Crazy Cat Lady, the Buyer of Cat Strollers

I am sorry in advance for what you are about to read. If witnessing the evolution of a mere human into Crazy Cat Lady is something you may find disturbing, turn back now and pretend you never came to this godforsaken place.

I got my cats a cat stroller. Specifically…this cat stroller (in green). This thing had better last us for life.

First, reasoning (aka excuses):

  • Our cats like being outside, both on our cat-enclosed porch and on harnesses in the shared yard. BUT they can’t really walk like a dog does (it’s more like they walk and we follow them around), which makes it difficult to show them new places.
  • Our cats are heavy. Rigel has pretty much outgrown his original plastic carrier (which wasn’t that great quality to begin with). A cat stroller would provide a more comfortable method of transportation (such as to the vet) for both me and him - I don’t have to lug a heavy cat around in a carrier and he gets a much more smooth and comfy ride.
  • Here in Stockholm it is perfectly acceptable to take your pets on public transport. Having had to take Rigel on public transport before, I know how stressful it can be. All the new sounds and smells and people. One thing that doesn’t help is him being low down on the floor in his plastic carrier. Cats like to be up high. Aside from being more comfortable and roomy, the stroller gives the cats a higher position to sit in, hopefully helping them feel a little less stressed and intimidated.

So anyway, it came a few days ago. Here it is:

Pet Gear NV Pet stroller

Kaytu took to it straight away. She jumped in and I rolled her around the house. Rigel took a little longer, but eventually did the same thing.

Cat in Pet Gear stroller

A little later it was time for our first walk! We had a very quick walk around the small shared yard area out front. I didn’t want to go too far too soon and overwhelm them.

Pushing cat in cat stroller

Even David decided to partake in the Walk of Shame:

Cat stroller walk of shame

This morning we took our first longer trip. We didn’t go too far this time, just to a large playground with a small wooded area about a 5-10 minute walk away (in non-cat-stroller-time!)

Two Cats One Stroller

Kaytu seems to have taken a liking to the stroller as soon as it came, even faster than Rigel. But Rigel was more comfortable being outside at a new place. Maybe it’s because he’s been out of the house so much in taxis and on trains out of necessity. I parked the stroller near a bench (the foot brake has already come in handy) and opened the secure top cover. Both cats already had harnesses and their retractable leads on. Rigel stepped out onto the bench and went to explore the nearby bushy area straight away.

Rigel goes to explore

Kaytu, though, was uncomfortable. I don’t think she’s ever been this far from home. I put the cover down a little more to shade her from the outside world and we followed Rigel around in the stroller.

Nervous cat stroller cat

After some exploration we slowly made our way back in the direction of the house.

Cat exploring a bush

Cat next to cat stroller

We rode with the hood up, my holding the leads. Kaytu was a lot more comfortable by this time and sat up front sniffing around. Then she actually decided to jump down and do some exploring of her own.

Cat explores the world

At one point Rigel jumped back in the stroller, rode there for a few minutes, and then hopped back out to do more roaming.

Rigel cat jumps into cat stroller

Rigel the cat walks next to pet stroller

The cool thing is he actually WALKED most of the way home! Kaytu was content to stay in the stroller and be pushed around, but Rigel walked behind me. It was slow going - he’d walk a few seconds, then stop to look around. I would call him and he’d walk again, then stop again. I think he’s starting to learn what “Come” means!

Rigel learns to come!

At one point we were passed by a huge retriever looking dog. Rigel didn’t seem worried at all - he just sat there and looked at it. The owner made the dog sit a few meters away until the dog calmed down (it was very excited), muttering “Friend! Friend!” while pointing at Rigel. Finally Rigel got bored and headed back in the direction of home.

By the time we got back to the yard Rigel was sitting in the stroller and Kaytu was sitting on top of it - it was quite a sight.

Arriving home in cat stroller

Kaytu trying to figure ot what just happened

Cat on top of stroller

Pee-training Rigel

Note: This is part of a series of posts about Rigel the Maine Coon kitten who was given a urinary infection by a veterinarian in Stockholm during a routine surgery and has been struggling with peeing since. You can read more in the Rigel section.

Rigel turned 1 year old on July 22. I was almost afraid to celebrate. We didn’t think he was going to make it to 8 months, having been scheduled to be put to sleep way back in…was it March…and then miraculously peeing at the last minute, on the day we thought we were going to lose him. Here’s a photo of him on July 22:

1 year old Maine Coon

For his Birthday we finished cat-proofing our porch to let Rigel and Kaytu sit there under supervision without a harness. They love it - Rigel now bolts downstairs whenever he hears me going to the door and demands to be let out every morning.

1 year old Maine Coon on porch

The peeing has been…interesting. He has taken to peeing twice a day, but only one of these times seems to be of his own free will. Basically - he has been peeing on his own at 7-8:30am. Then, at 10pm, we bring the other litter box, water, and toys into the bedroom, open a window crack to get some air, and shut all of us in there. David and I watch a show and try to leave Rigel alone (that is, we’re in the same room but not bothering him). We don’t open the door to let the cats out until Rigel pees. Originally this started as a way for me to keep a closer eye on him, to avoid waking up in the morning to find pee in one of the boxes and not be sure which cat it was. This way I can hear when one of them goes in the same room and wake up to see if it’s Rigel or Kaytu. If Rigel goes to pee we let them out because we know he’s peed enough and any pees we find the next morning will probably be Kaytu’s.

But Rigel seems to have seen the connection between him urinating and being let out of the room. Gradually the time between him being locked in and peeing has decreased, though it varies still. A few times he’s entered the box right after shut-in. I guess it’s his way of saying “Screw you guys I don’t want to be in the same room as you and I’ll pee to prove it.”

Sometimes it seems he really doesn’t want to pee when we do this. Last night, for example, he sat on the windowsill as usual for 20-30 minutes. Then we hopped off and went to consider one litter box…no go…then the other…still no go. Then he walked to the door and made a frustrated Maine Coon chattering sound, pawing at the handle. Seeing that it was no use he begrudgingly stomped into one of the boxes, did a nice pee, and went back to the door - at this point we of course opened it.

I guess he’s been accidentally “pee-trained”. On the one hand this seems good - he can make himself pee “on command” when there is something he wants (though the conditions are pretty strict - 10pm on the dot, both boxes in room, window cracked open…it’s like a ritual). On the other hand why doesn’t he feel like peeing by this point himself? If he pees at ~8am that’s 14 hours from morning pee to lock-in. We know he has plenty of urine in him by then. Why does he wait for us to lock him in to actually go?!

Anyway, as long as he’s getting pee out I’m happy. He’s still on medication and we don’t know what the future holds. Every day we’re grateful for a good Rigel pee.

Laravel Log File Backups to S3

SnailLife does a lot of logging for debugging purposes. Aside from the general laravel.log I have separate loggers for each snail and also write logs for stuff like deleted items etc in separate files.

The problem is all the space this takes up on my Digital Ocean droplet in Laravel’s storage folder. If I leave it for a week or two it fills up and I’ll suddenly find my droplet inaccessible or some recurring commands not being able to finish properly due to insufficient space.

Instead of culling the logs more aggressively I decided to set up a backup to Amazon S3. With Laravel 5’s filesystems this ended up being a pretty simple process.

First I set up an S3 bucket called snaillife-storage with a user that has getObject, createObject, and deleteObject permissions.

I set the S3 credentials in the .env configuration file:


Note that I set the region here just in case but in reality I don’t use it. In config/filesystems.php I set up the S3 disk using these credentials (the region setting is removed. I also changed the local disk root to storage_path()):

'local' => [
  'driver' => 'local',
  'root'   => storage_path(),

's3' => [
  'driver' => 's3',
  'key'    => env('S3_KEY'),
  'secret' => env('S3_SECRET'),
  'bucket' => env('S3_BUCKET'),

Then I made a new artisan command called BackUpLogs:

<?php namespace App\Console\Commands;

use Illuminate\Console\Command;
use Storage;
use Log;
use Carbon\Carbon;
use App;

class BackUpLogs extends Command {

     * The console command name.
     * @var string
    protected $name = 'BackUpLogs';

     * The console command description.
     * @var string
    protected $description = 'Back up logs to Amazon S3';

     * Execute the console command.
     * @return mixed
    public function handle()
        if (!App::isLocal()) {
            $localDisk = Storage::disk('local');
            $localFiles = $localDisk->allFiles('logs');
            $cloudDisk = Storage::disk('s3');
            $pathPrefix = 'snailLogs' . DIRECTORY_SEPARATOR . Carbon::now() . DIRECTORY_SEPARATOR;
            foreach ($localFiles as $file) {
                $contents = $localDisk->get($file);
                $cloudLocation = $pathPrefix . $file;
                $cloudDisk->put($cloudLocation, $contents);
        else {
            Log::info('BackUpLogs not backing up in local env');

Note that the directory you specify in $localDisk->allFiles($dir) should be relative to the root path of the local disk - an absolute path does not work.

In Kernel.php I set this to run every hour:

$schedule->command('BackUpLogs')->cron('5 * * * *');

So now every hour all the files in my storage/logs directory are backed up to my S3 bucket and deleted from the local disk.