A Game of Snails is nowhere close to being complete or even really playable, but I’ve decided to get as much of it done as I can before the end of May and then just put it online – regardless of completion or bugs. There are no rules to One Game a Month, after all, and I can then continue to work on a more complete release for the month of June. Or, if I feel like a break from snails, make some other quick game in the meantime and let it rest until I want to work on it again.
I’ve decided to go ahead and upload all the code to GitHub. It’s unbelievably messy. Hopefully I’ll get to clean it up a bit before the end of May.
As for the actual state of the game – today I got the server running on Heroku. It took a few hours in total (I had no idea what I was doing). The client is still being run locally, but using the Heroku-hosted server. Since I’m trialling AWS for the year already I wanted to use EC2 for this, but had problems with the verification phone call and impatiently decided to go for the free Heroku to get something up. I felt that it was important to get something running outside of my local environment asap instead of panicking about deployment at the end of the month. I’m using MongoHQ to host the database for the snails – free version of both Heroku and MongoHQ.
Remember my old feature list? I’ve updated it (mostly the Race section), but really not much has been completed in terms of gameplay features. I’ve mostly spent the past few weeks working on GUI and server stuff. Now I can finally start working on a proper race formula. This may not be done before the end of the month, but we’ll see.
As for actually getting this thing onto Heroku, the main things I needed to do were:
- Updating my package.json
- Creating a Procfile (the Heroku documentation says this needs to be a text file, but in reality the extension should not be .txt)
- Enabling long polling as Heroku does not support websockets.
- Moving all the server stuff from the lib folder and into root
- Listening for the proper server port that Heroku assigns, not 3000 as I was using on localhost.
- Updating the database to connect to the one I set up in MongoHQ
- Updating port on the client.
It doesn’t seem like much in the end, but all of this took at least a couple of hours to work out (with various breaks).
So right now…things seem to work. One thing I should have thought about but didn’t was how slow the server responses are compared to running locally…which is of course to be expected, but I was not expecting this much delay. It takes maybe 0.25 – 0.5 seconds to perform some actions.
Up next, I’ll try to get a rudimentary race formula up and running and then maybe make the whole thing look a little more presentable. I don’t know if I’ll have time to do much else before the end of the month, so May’s One Game a Month entry will be a broken, incomplete game (for now).
Yestreday I realized that I don’t actually want to run a half marathon. It’s not like I couldn’t, if I trained up for it. I’ve done the distance before. Heck, I even entered the City to Surf half marathon in Perth with every intention of running it until I broke my foot a couple of months before the race. And it’s not like I don’t think running a half marathon would be a great achievement. It’s just that I don’t really like running. There are people who talk about how much they love to run and how awesome it feels. I am not one of those people. To me anything after 1km is just boring. I can usually manage 5km without it feeling like too much of a drag, and 10km is pushing my limit. But anything over that is just so dull. For me, it feels awesome at the end – looking at your time and seeing how much you’ve improved or how far you’ve run. It’s a matter of balancing the lack of enjoyment I get during the run with the enjoyment I get afterwards. And of course, afterwards, you remember the run as being great because the sense of completion makes it feel great. You conveniently forget that it was dull torture at the time – until the next run.
This is probably not what most people want to hear coming from a person who runs on a semi-regular basis.
Anyway, the last week has been pretty awesome. Work is putting on lots of summertime fitness activities – CrossFit, interval sessions, Yoga. So last week I ran 5km on Monday, did CrossFit on Tuesday, and ran a (slower than usual) 10km on Friday. Yesterday I ran 5km at lunch and then had a training session for Tough Viking after work, which involved more running, stair climbing, hill intervals, and cross training. I’ve also signed up for the Midnight Run and a team 5k run event where every team member does 5k. In short…I will be sore this summer.
I’m taking a couple of days off of running due to what I think may be a calf strain (let’s hope it’s not a stress fracture, but those are pretty uncommon in the fibula). Tomorrow I’m aiming for a 5km, then Yoga, and on Friday I’ll aim for a 7 or 10k run.
So here’s what’s been happening. In pictures!
A walk on Thursday, May 9
Chillin’ in a tree
I’ve never seen a flower like this before!
Apparently the government gives Swedish people free summerhouses. The waiting list is something like a hundred years, but they are so pretty.
It’s finally green!
A 10km run on Friday, May 10
Part of my running route, around Södermalm
They may look stupid, but they’ve saved my knees
Stockholm has lots of these outdoor exercise areas – and people actually use them!
I may be smiling, but my legs were killing me in that moment.
Skansen on Saturday, May 11
I’m on a horse!
I suck at stilts
Dandelions on Sunday, May 12
Posted on: May 15th, 2013 by admin
No comments - in fitness, life
Tags: fitness, running, skansen, stockholm, sweden
I knew this would happen. Out of all of the new things that I have to learn to do for this snail game, the part that is the most tedious and difficult for me is the UI. Every part of the UI. You’d think that I’d be able to use web design skills from my previous life to make this at least a little intuitive, but nope – this blows. And it’s not just designing the thing that’s the problem, it’s finding the best way to implement it, too.
I’ve written about structuring a GUI system for my space game before and I’m using a similar method now – relying on trigger entities and a few dedicated GUI entities. Except this time I’m also throwing HTML forms into the mix, since clearly this isn’t complicated enough.
And it’s getting to the stage where it doesn’t seem like I’ll ever be able to work on the actual game mechanics again because for the rest of my days I will be sitting here creating trigger kinds, attemting to get stupid scroll bars to work, then redoing everything when I realize the layout is majorly screwed and unusable.
My GUI system is based on trigger entities. Trigger entities are anything clickable. No, I don’t know why I didn’t just call them buttons. Screw you, shut up. They’re triggers. Crap.
Ok so there are various “kinds” of triggers. Each trigger instance has a “kind”. For example, yesterday I was working on ‘upArrow’ and ‘downArrow’ trigger kinds. When a trigger with the kind of ‘downArrow’ is clicked, it calls
this.parentEntity.scrollDown(). Then you have to keep track of each trigger’s parentEntity (which is what spawned the trigger). This is important because when you want to close a menu you have to make sure all of the triggers are destroyed, and loop through each parentEntity (these are sometimes nested) to close it.
Aside: Every time I say something like “it’s hell”, I think about how stupid it is. Here I am sitting in a coffee shop enjoying my cheesecake and I think detangling a fricking UI system is “hell”. How pathetic is that? It’s not hell. It’s a piece of cake. I have running water.
Anyway, I just want to get the main UI elements done and usable. Except after the actual race list scrolling is done I’ll have to make the race triggers clickable to spawn race details…then create a way for people to actually enter their snails into a race…and then I can start running the actual race…and then it’s more GUI stuff as I attempt to find the best way to display the race results. Gah. The whole rest of this game is going to be about fricking buttons. I mean triggers.
I was meant to write this blog post four hours ago. Instead I got home and decided that since this one would have quite a bit of pictures in it and I’ve been running into bandwidth issues I may as well find a better solution for image hosting (as opposed to uploading everything to this server). I signed up to Amazon S3 on its free trial account and have been attempting to set it up ever since. Now I don’t even want to write this stupid post anymore, but I will anyway because darn it I didn’t spend all this time and effort to set up one fricking S3 bucket just to give up at the very end.
I was meant to go for a run this weekend, but this did not happen so instead I’ll do one of those half-assed at-home workout efforts on a full stomach just to make me feel like a little less of a lazy slug.
Saturday – end to end on the green line
Hot or Not
The weekend was mostly good! We decided to be extremely rebellious and get on the train going in the other direction from our station today. It was very exciting. We ended up going to the very end of our line and got off at Skarpnäck. I thought the buildings around the station looked really cool, but other than that there wasn’t really much to do…it was almost lunchtime and we were a little hungry, but stopping to eat at a restaurant called “Hot or Not” in this kind of weird looking neighborhood didn’t seem that appealing.
So we figured…let’s go in the other direction, to Hässelby. We did some quick phone-Googling and decided that it sounded pretty interesting. Lots of people seem to want to live there so it must be a nice neighborhood, right? We’d grab a nice lunch at a cafe or something while there and explore and it would be full of awesome awesomeness.
The train trip to the other end of the line took about 45 minutes to an hour from Skarpnäck. And…we got out to a whole lot of nothing. Near the station were two food places – a pizzeria and some sort of fast food cafe. Unfortunately by this time @locust9 was feeling a) extremely hungry and b) kind of sick, so we just wanted to shovel some food in us and go home. We ventured out to the water hoping to find a nicer cafe, but this did not happen. Instead we wandered back and ate a sad meal of “fish ‘n’ chips”. Which sounded good at first, but then I remembered that when Swedes say “Fish ‘n’ chips” what they really mean is this:
Swedish “Fish ‘n’ Chips”
I did think the giant forest on the other side of the water at Hässelby looked really interesting, though. It’s the kind of forest you imagine people having adventures in. The kind of forest that makes you want to write a story about getting lost in a forest. The kind of forest where werewolves, zombies, and other monsters live. I said that we should come back there when we’re feeling less sick and better prepared to walk along the water and then maybe find a way to cross into the forest.
So we ate some pathetic fish and chips, got back on the train, and headed home.
Sunday - Södermalm
It’s amazing how much there is to discover in Stockholm. I go to Södermalm every day both for work, running, and just for fun and there are new streets, parks, and views to discover each time. We got delicious crepes for lunch, then went to an awesome, tiny closed-in park with an amazing view of the water.
We sat on a bench, drank coffee, and talked about Jesus. Not…in the way you think.
And then we discovered a little wooden bridge just behind the park fence. It had even better views of the water. The weather today was pretty much perfect. I hope it stays like this all summer…and winter…and every other season. I heard that Swedish summers were great, but I didn’t know they would be this great.
Posted on: May 5th, 2013 by admin
No comments - in life
Tags: hässelby, skarpnäck, södermalm, stockholm
Over the past couple of weeks I’ve been attempting to get up at 5am to work on snails before going in to actual work. It’s been working for the most part apart from a couple of slip-ups and basically goes like this:
- Alarm rings at 5, I peel one eye open
- I turn off the alarm with an indistinguishable grumbling sound
- I sleep for either 5 more minutes or 2 more hours…
When I do manage to get up before 5:30 or so I get quite a bit of snail work done. This morning I finished race creation as well as displaying currently active races on the client. Up next I’ll be opening race information and making a way to actually enter snails into a race. I’ve got the basic structure set up, but nothing is hooked up yet.
I figured I’d write a quick blog post about breeding, since someone asked me how it works. Breeding and racing are the two main parts of the game. Breeding is in a functional state, though I’m sure there will be many changes to it in the future. I’ve also included an actual real-game example of the kinds of offspring that are produced below.
You can’t talk about snail breeding without talking about the fact that some (most?) snails are hermaphrodites. I have always found this interesting and knew I wanted to work a less traditional method of using sexual orientation during breeding for this game. It’s also important to note that breeding, genders, etc in A Game of Snails do not accurately reflect real life – they are inspired by real life, but I took plenty of creative liberty with the entire babymaking process.
(I’m writing this in a hurry this morning and will proofread it tonight so you may see some minor errors)
Each snail has an
orientation attribute which can be an integer between
100. Every starter or newborn snail starts out with an orientation of
0. A positive orientation means the snail identifies more as a male and a negative orientation means the snail identifies more as a female. An orientation of
100 indicates that the snail identifies completely as male (and
-100 as female).
Let’s say we have two snails named Spot and Blot (I’ve chosen androgynous names on purpose…) Spot and Blot are both adult starter snails with a sexual orientation of
0. Now let’s say we want to breed Spot and Blot together, so we put them both in the breeding jar.
After a short matchmaking period, Spot and Blot decide they like each other and want to mate. This means one snail needs to take the male role of injecting its spear-like penis into the other snail, which takes on the female role. But Spot and Blot are both totally neutral in gender, so which is which? Well, it’s random…if both snails’ orientation is identical, the decision regarding which snail acts as a male and which acts as a female during the mating is completely randomized.
So let’s say Spot is randomly chosen to be the male and Blot is chosen to be the female. The orientation attribute now instantly changes for both snails as follows:
Spot.orientation = 100
Blot.orientation = -100
As soon as a snail is chosen to be male during a mating, its orientation gets kicked all the way up to
100 – the maximum male identifying value. As soon as a snail is chosen to be the female, its orientation does the same in the other direction, to
Spot and Blot mate and produce a newborn snail with a neutral orientation of
0. They get removed from the breeding jar.
Now that they are back in their normal jar, their orientation slowly starts ticking back over toward
0, at a rate of 1 step every 5 seconds (for example). This would mean that both Spot and Blot would be of totally neutral orientation again after 500 seconds/8.3 minutes.
However, let’s say Spot gets bred again only 5 minutes/300 seconds later, this time with a new snail named Knot. This means that Spot’s orientation is still at
60. While not exactly the strongest male identifier, Spot still identifies as a male at this time. Let’s say Knot also identifies as a male with an orientation of
70 at the time of the mating. So which snail mates as a male and which as a female?
In this situation, Spot would be more likely to be chosen to take on the female role than Knot because Knot is feeling a little more masculine (with a higher male-identifying orientation value). Now that Spot has been chosen to mate as the female, its orientation goes all the way down to
-100 and Knot’s goes all the way up to
There are two main timers that are used during the breeding process. The first is the breeding jar’s standard matchmaking timer (which right now I think is 10 seconds, with a slight degree of randomization). The timer gets reset each time a new snail is placed into the jar as long as there are at least two breedable snails in there. So let’s say we put in Spot, then Blot – the matchmaking timer starts. If no other snail is placed, Spot and Blot will be matched in 10 seconds. However, 5 seconds in we put in Knot and the whole thing restarts again. This gives us the opportunity to pick two random snail matings out of a group instead of mating as soon as we’ve put in just one pair. The snails can sniff each other out a little and see which way the cookie crumbles.
Once two snails are paired up the arousal timer starts. Each snail has an
arousalTime attribute. This is how long it takes the snail to actually be ready to mate after it’s paired. The snail with the highest arousal time is always the one that dictates how long we have to wait for the mating.
Once both snails are aroused, the mating takes place – both snails and the newborn (“foal”) are placed back into their main home jar. Eventually I may include a pregnancy timer, but for now babies are born instantly.
But what actually happens during the birth of a snail?
All snails have traits that are passed on to their foals.
Visual traits are represented in the
genes attribute. We have
genes.shellColor, genes.patternColor, genes.patternShape, genes.eyeColor. Each gene has two alleles.
When two snails mate, we pick out the foal’s gene for
shellColor out of a virtual Punnett square of sorts.
Let’s say we have a stag and a doe with the following genes for
shellColor (uppercase being dominant and lower case recessive):
shellColor allele1 = R
shellColor allele2 = r
shellColor allele1 = B
shellColor allele2 = b
The various options that the foal would land with are:
We randomly choose one of the four options above for the foal. In the case of an rb or RB matching the R is always dominant (I have three alleles for color in all – red, blue, green)
So for example if the baby snail ends up with rB for its shell color its shell will be of a blue shade, close to but not necessarily exactly the same as the shell color of the doe.
Here is an actual example of the breeding process and the offspring it has produced (if you’re confused about why the green snail shows up twice, for the purpose of this example I had to breed one of the snails with its offspring). I’ve placed gender markers to show which snail bred as the male and which as the female, but remember that in reality their orientation starts ticking back to neutral after the mating.
Hidden traits like the core stats –
speed, endurance, weight, later
aggression – work a bit differently. Here I just take the average of the stag’s and doe’s attribute and randomize it a bit by offsetting by a certain percentage. Not the best way of doing it, but for now it works.
That’s the gist of breeding for now. There’s still work to do, but now I’m focusing more on racing as the breeding is at least mostly functional.