This year I decided to do something interesting for Valentine’s day. Rather than battling crowds at a florist, I figured I’d be much better off going with flowers of the digital variety, and I’m not talking shoddy e-cards.

I wanted to create an interactive experience in quite a short time – illustratively, when telling the idea to a friend his response was “you know valentines is tomorrow right?”, so Unity3D was an obvious choice. I had a quick look on the Asset Store during my lunch break and identified some decent free and affordable models. I even found a pre-made environment I liked, which would save me a lot of time.

This paragraph is a placeholder: I’ll enhance this post with details of the development process and assets used when it isn’t 2:30 a.m. and I haven’t just spent 9 hours at work followed by 6 hours of coding.

For now, you can try out the final result. You too could be saying things like:

  • “Where there’s smoke, there’s mushrooms!”
  • “Yeeeeaaah, your rock is on fire” (to the tune of Sex on Fire by Kings of Leon)
  • “Physics is mah bitch.”

valentine-game-preview

Play: Happy Valentine’s Day Ally!

Wrap-up

Total development time: 1340 minutes (22 hours, 20 minutes).
The game-in-a-week challenge has come to a close. It has been an exhausting experience, adding a half-time workload to my full-time work week, but also a lot of fun and very rewarding. I haven’t tracked the extra time spent on the write-ups, but it would have to be at least a couple of extra hours on top of it all. Since I’m completely drained, I’ll structure this wrap-up in self-interview format to keep my fatigued mind on track.

Science Crowbar

Does the final product fit what you had envisaged at the beginning?

In broad terms, the game now has all the major elements I expected it to have by the end of the week, but there are some significant differences from the original picture in my head. Most of the differences are simplifications, but a few are due to a combination of rushing and contingency, and one is due to a limitation of the free version of Unity that I didn’t have time to work around.

Simplifications are mainly around visuals, movement and animation: I used only a single scientist model and didn’t use a variety of textures or scales, which would have helped them look less like clones; the scientists aren’t animated in any way when producing science, whereas given more time I would have like them to perform various science-y actions that would be visually linked to changes in the science bar using a ‘flow’ of animated particles to the science bar; enemies have restricted rotation, whereas I would prefer to allow them to rotate freely so they can be knocked over by a well-aimed strike and have to right themselves; enemies teleport to scientist heads rather than being animated climbing up and latching on, which would add the ability to carefully knock or pry the enemy off before it is fully attached, while trying not to hit the scientist; zombified scientists don’t attack their neighbours, which would add an extra dimension to the game and make things more hectic.

Rushing-related changes were mainly the environment textures. I had originally pictured a more metallic grated flooring with some embedded lights and other features, and metallic paneled walls with plenty of consoles, lights and other features, but in the late-stage rush I grabbed some of the first textures I found that looked alright. The room is also quite bare; given time I would have added features such as broken areas of flooring, exposed wiring, miscellaneous fixtures, blood smears, dripping/pooling water, and so on. Mixing up such features as well as room textures and dimensions would give more of a feeling of progressing through different areas.

The difference that I think has the biggest effect on the feel of the game environment is the lack of shadows. The free version of Unity has some significant limitations on out-of-the-box dynamic shadow support, and the limited timeframe left me no opportunity to look into alternatives. Without the time constraint I would have spent the necessary time to get something akin to the shadows in Alien Swarm.

How does development with Unity and C# compare to development with SDL and C++?

I won’t make a direct comparison between SDL and Unity, that would be pointless since SDL is a simple wrapper around low level APIs and Unity is a fully functional game engine – it’s an apples and oranges comparison. I could compare the languages but I’d be writing all night – suffice to say that C++ is a lot easier to get wrong and a lot slower to develop.

The more relevant comparison to make is the overall experience. Working with C++ and SDL is all about building up from nothing and putting together something over which you have complete control. The control is nice, but it comes at an enormous cost in time. Unity does a lot for you, primarily with asset importing and management, and with object interaction, but also in numerous other areas too extensive to list here. This makes a huge difference to the development process: it lets me be thinking about what elements I want in my game and how I want them to interact with each other, without being dragged down into the minute detail of exactly how everything will be rendered. In short, Unity gives you the wheels so you don’t have to invent them, and throws in the chassis, engine, drive train and diff for good measure. They leave the steering, body-work and paint job up to you.

What aspects of development were easy under severe time pressure?

As a software developer, I’m most comfortable with the coding side of things – in a small project like this I didn’t hit anything that really challenged me in that area. Some other parts were made easy by Unity, such as getting the basic level put together, positioning elements, attaching scripts and dealing with collisions and basic physics interactions.

Scoping was also easy, which sounds a little counter-intuitive  with such limited time, scope-creep was basically impossible. There wasn’t an opportunity to incorporate any new ideas other than the most trivial tweaks and corner-cutting. Since I knew I didn’t have time to add anything, I didn’t waste any time entertaining the idea of major new features.There were also some elements that were made easier simply because I had a good excuse to cut corners. I went for simple movement in a simple environment, so there was no need to start pulling out A* or even greedy search – I’m interested to see what kind of path finding is baked into Unity or available as libraries or extensions – I’ve been directed at A* Pathfinding Project and iTween so I’ll give them a try, probably in my next project.

What aspects of development didn’t hold up well under time pressure?

The major group of activities that didn’t hold up well was anything new. Typically I’ll spend a while reading up on and trying out technologies or techniques with which I am unfamiliar before I start using them in a project, but with less than 24 hours of development time I could only afford to do quick research on things as they came up.

Model manipulation and positioning gave me some strife when combined with parenting. This feels like another inexperience thing, but it gets a special mention because it looks like something with several moving parts, all of which I need to understand to use it properly.

Creating atmosphere gets an honorable mention here too, basically because there wasn’t time for it. Once I have all the major elements in place, I would ideally spend some time playing with lighting, shadows, models, textures, audio and animation to get the game feeling the way I want. I was only really ready for this as I made the last changes to this project, so it was something I just couldn’t fit in. I ended up with a much brighter and more sterile-feeling scene than I would have liked.

Has this challenge highlighted any major gaps in your knowledge?

Definitely, particularly around Unity. This was definitely expected, in fact it was one of the desired outcomes of this challenge. The areas I’m most acutely aware of my lack of knowledge are lighting, exactly how scale is calculated with parenting and instantiation, and an in-depth understanding of Unity’s component model, particularly around object access through parental relationships. By focusing my learning in these areas I can ensure that I maximize my practical skills faster than just trying to learn absolutely everything, which is extra-important when game dev isn’t my day job.

Would you do this or a similar challenge again?

The challenge has been an exhausting experience, but also a very fun and rewarding one. I’ll definitely look at similar challenges in future, after I’ve had some time to recuperate, and with some appropriate changes to help maintain a bit more balance.

What would you do differently in similar future challenges?

I think next time I would prefer to allocate a little more time and a more ambitious project, e.g. Friday to Sunday spanning 2 weekends. This project was fun, and about right for my limited experience with Unity, but next time I should be a lot more on top of the fundamentals so I’ll want to aim for a more polished product with a bit more depth. I could even look at using some leave and taking on something even more ambitious, like getting Grey Out to market in 10 days.

Assuming I was taking a challenge during a work week, I would also be looking at ways to prevent the challenge distracting me too much from other aspects of my life – it isn’t the end of the world to have dishes pile up for a week, but it is something I should be able to avoid. Ideas for this include more specific time constraints during the week (e.g. hard maximum of 2h on work days), and a change to morning-only development (i.e. get it done before work).

Finally, I would encourage others to follow along with their own challenges – the same or different doesn’t really matter as long as they’re happening at about the same time. This challenge was a bit of a spur-of-the-moment thing, but with a little more foresight I’m sure there are plenty of people keen to challenge themselves.

Will you do any more development on Science Crowbar?

Definitely. I’ll keep a copy of the one-week version of it, and make that available soon, but there is plenty to learn as I take the project beyond the working-prototype stage and flesh it out into a complete and polished game.

Update: play Science Crowbar online now! Big thanks to Blocky Pixel for hosting.

Day 7 – Audio Antics

Development time: 20 minutes (running total: 1340 minutes).

Four simple audio samples make a big difference to the feel of the game.
Just a quick addition this morning to round things out. I used my chest, a role of tape and my own voice to sample a few sound effects. The audio isn’t very clean, but it’s certainly good enough for a last second addition before wrapping up the project. I attached the spark noise to the particle emitter prefab that does the spark effect, letting it play when instantiated; for the enemy I added two audio sources for when they’re hit and access them as an array, playing a more crackly sound when they die or if they’re already dead; for the scientists I have a single sound play when an enemy attaches to them.

Goal for the next week: deploy somewhere

With sound, I’m now happy enough to call the project complete, but there is still some work to be done. What good is jamming together a game in a very short space if I don’t share its hurried glory with the world? Stay tuned for a playable web version as soon as I can sort out some hosting, and a wrap-up post with some final thoughts on the project.

Day 6 – Model Mayhem

Development time: 200 minutes (running total: 1320 minutes).

I was so pleased with my crowbar experience yesterday that I set out with the same approach to find models for the enemy and scientist. I hit a few more snags than expected, but managed to put out the inevitable last-minute fires and finish with a working, not-too ugly but very quiet game.
Initially, I looked for a nice tick model to use for the enemies, but decent tick models can be pretty expensive, definitely outside my budget of $0 for this project, so I tried some alternatives and found a nice classic headcrab model by 3dregenerator that’s perfect for my purpose and falls under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License, which suits my purpose for now since this is not a commercial project, but is important to keep in mind: if I ever turn this into something I want to sell I’ll have to find an alternative model or seek permission from the creator to use it.
Not quite the size I was aiming for.
Despite an initial scaling issue, importing and applying the headcrab model to my enemies was straightforward. Unity’s prefabs helped a lot here, as I was able to apply the drag a new copy of the enemy prefab, apply the new model to it, make necessary adjustments to related components, then drag the modified prefab copy back into the prefab.
I also ended up locking rotation completely as the most time-efficient way to stop them hopping sideways or backwards – a down side to using a model other than a nondescript blob. A preferred solution would be to allow the enemies to turn and fall over, and have them spend some time righting themselves. While this would look better, there simply wasn’t time for something that falls in the category of extra polish.
New models.
Next was the scientists. With the clock ticking I grabbed the first reasonable scientist model one I found, from the same site and under the same license as the crowbar I found yesterday. These guys just hang around at the bottom of the screen, so I didn’t spend the time to get them posed or animated, nor even to get their textures applied properly, since it would make minimal difference to the final effect.
Out with the old, in with the new.
Things were still looking pretty plain, so I had a quick look around for some textures for the environment. I found a suitable tile pattern for the floor, and a different tile pattern for the walls. The license for these textures is worth noting, since there is a specific limitation on use for Open Source projects. If I decide to distribute my project files I’ll probably have to find alternatives.
These still give a fairly sterile feel, but once again time constraints mean that good-enough will do, and it’s definitely an improvement on the grey. How the scientist got into this room with no doors or windows is a mystery I leave players to puzzle over.
Applying textures to the environment.
I hit some issues with rotation of the scientist model, which I solved by having the scientist GameObject parented to a GameObject with the model that had appropriate rotation applied. This solved the rotation issue but led to a nasty situation where the child object could be moved away from its parent, leading to major problems with enemy attachment as they appeared to ignore the scientists, then start floating in the air at what appeared to be random positions.
Debugging position issues. The box collider was temporarily added to better show the position of the parent GameObject.
I chose the simplest solution to the positioning issue: turned off physics for the scientists. If they don’t move they can’t move away from the parent object. It isn’t a real solution, and some interesting effects such as falling over are lost, but it does make the game work right now, which is basically all the matters with the deadline so close.
Problems with parent-child positioning. Both green wireframes should be centered on the same point.
Almost out of time, there were still 3 issues I wouldn’t want to have in when shipping. The first was enemies occasionally falling through the floor or get knocked over a wall, which made a level impossible to win as the enemy accelerated away to safety. Rather than mess with complicated collision issues, I took a used a simple hack to solve the problem: enemies that find themselves more than a small distance below the floor will immediately report that they have died, then become inactive. Problem solved.
The second remaining issue was that enemies didn’t actually move toward scientists, the would just hop straight ahead and hope they end up close enough to attach, which would often leave them jumping repeatedly into the back wall with a scientist not far away. I solved this one properly, detecting the nearest surviving scientist and leaping in an appropriate direction. It makes for a much more hectic experience as you see the enemies closing in on your final scientist.
Approaching scientists properly.
The final issue was that dead or zombified scientists were only identifiable by the enemy on their head, which was fine until you kill it, then they look fine again even though they aren’t. Ideally the zombified scientists would start attacking their neighbours and need to be put down, but there simply wasn’t time to get that done today, so I’ve gone with a simple texture change to keep them identifiable as standing corpses. Rather than search around for or create a new texture, I tried the enemy texture – with a bit of adjustment to the tiling it was good enough so I stuck with it.
A more distinctive look for zombified scientists.
And that’s it. Bed time on a work night and all the elements are in place, almost; I didn’t get around to adding sound, which would make a big difference at this stage.

Goal for day 7: add sounds, ship it

I noted in yesterday’s post that I could make an argument for sneaking in a little more development on Monday morning. I am now making that argument. The game really needs some sound, but rather than stay up late and feel exhausted at work tomorrow, I’m leaving it until tomorrow morning. It is still within a week since I started on Monday afternoon 🙂
I still need to get to work at a reasonable time, so all I aim to do is sample a few sounds and add them to the major game events.

Day 5 (afternoon) – Surviving with Crowbars

Development time: 90 minutes (running total: 1120 minutes).
Saturday afternoon presented very little additional development time due to an impending social engagement, but I managed to get survival mode working well again, and started the search for better models for the main game elements. I would have liked to do more, but I console myself with the knowledge that I found a decent free crowbar model with very little time investment.
Shiny new crowbar model.
To get survival mode fully functional again, I added a class to keep track of a survival game and had it implement the enemy spawn controller interface mentioned in part 4. Using the same interface made the code in the main controller for starting a survival game very simple. With a few modifications to the UI, I had survival mode fully operational again, with a more modular structure that will be easier to understand and maintain later.
I had considered trying to quickly throw together some basic models of my own, at least for the crowbar and the enemy, but a quick search turned up a nice free crowbar model with an appropriate licence for my use. A quick look through the license FAQ shows that I’m free to use the model as long as I don’t distribute it in a format that someone else could extract and use it, which is something I’ll have to keep in mind when it comes to distribution.
Crowbar scale tweaked to look good from the current game perspective.
Unity made importing of the new model dead easy, so all I really needed to do was tweak the scale to look right and make a few code changes to get the movement correct. Using stock models is a very effective time-saver under such extreme time constraints, particularly for someone like myself with little 3D modeling experience, so it is definitely an option I would look at for future projects, and for the remainder of this project. I’m sticking with free models for now since I haven’t allocated any budget for this project, but while looking around I noticed plenty of decent stock models in the sub-$10 price range, which is definitely worth the several hours I would take to make something equivalent.
New crowbar in action

Goal for day 6: polishing it all off

I haven’t mentioned it yet, but you may have noticed a missing day. Tuesday I had martial arts training, so although Monday was day 1, day 2 wasn’t until Wednesday. That means that day 6 is really the end of my development week, although I could make an argument for sneaking in a little more on Monday morning since I started on Monday afternoon.
The goal for the final day is obviously to get the project finished, but the specifics aren’t as straightforward as just getting everything done; there simply isn’t time for that. Any team that ever wants to ship a product will generally have to make some hard decisions about what they don’t have time to do, and this project takes that to the extreme. There are easily several weeks of work in polishing even such a simple game to make it perfect, but I only have half a day (with those pesky social engagements chewing up more of my weekend).

In some ways the extreme constraint makes the decision a lot easier, as it changes the question from “What can I afford to leave out?” to “What do I absolutely need?” – a far less ambiguous question. I have a basically working game, so really all that’s absolutely missing is visuals and audio. Leaving a little time for last-minute tweaking, that’s all I have time for anyway, so I’ll do that: find models for enemies and scientists, textures for the floor and walls, and sample a few basic sound effects.

Day 5 (Morning) – Sparks Fly

Development time: 270 minutes (running total: 1030 minutes).

This morning was one of those rare occasions when I had just enough time to finish everything I intended. I won’t pretend it was anything beyond luck, but it still feels nice. There is now a visible science stat generated by surviving scientists, gets used up in a burst of sparks when hitting enemies, and gives a nice boost to damage.
Science stat at work.
I used a scrollbar to mimic a progress bar for the science meter, which was very quick and close enough to what I want. The game controller keeps track of the amount, and the code for scientists to generate it and the damage amplification is trivial. I added sparks using a particle emitter – ideally I would use a single emitter, perhaps attached to the crowbar, and have it emit bursts of particles, but I had some trouble accessing the emitter programatically so decided to cut my losses and use the less efficient option of instantiating emitters from a prefab and destroying them after a few seconds.
Death by science.
Not the prettiest sparks in the world, but good enough without spending long on them.

With the science stat working close to the way it was originally envisaged, I tackled the final major problem with gameplay. Up to this point the crowbar’s movement has been limited to a plane a few units above the ground, and had to be waved through the enemies like a magic wand to make them die. That isn’t the sort of feel I’m going for, and meant that mindlessly flailing back and forth was a winning strategy. To get more of a bludgeoning feel, I moved the basic plane of movement up to about the scientists’ head height, well above the hopping height of enemies, and added a bashing animation activated by a keypress.

A jaunty angle
The movement uses a coroutine that activates over several physics update frames. It moves down and rotates forward for 4 frames, then does the reverse. The rotation uses local coordinate space, whereas the movement uses world space – the default local space movement would cause a net forward movement due to tilting of the y axis, which isn’t desired here.

At last, some proper bludgeoning…

With these changes I’m just about ready to try for some sort of difficulty balance, but I’ll be leaving that to the last minute since it’s a task that can balloon out to any number of hours, and I can make up lies about the target audience if people start claiming it is too easy or difficult.

…to death!

Goal for day 5 (afternoon/evening): survival and special effects.

Survival mode isn’t properly functional after the spawner changes made for campaign mode, so I’ll spend a little while getting that back up and running. Tutorial mode can wait until tomorrow or later, but I’ll add some basic instructions to the main menu as a stopgap. I’ll spend any remaining time today on adding some textures, models and audio.

Day 4 – totally playable

Development time: 240 minutes (running total: 760 minutes).

Like day 2, progress was slower today than I had hoped. I spent longer than I meant to and didn’t get get everything done. Unlike day 2, however, I am quite pleased with my progress. The difference? Today’s extra time was all spent making things more awesome!

“And just what is so awesome about it?” I hear you ask. Well, First off I added a class to keep track of a campaign game: things like current level, surviving scientists, and some variables related to enemy spawning rate. The campaign class made implementing campaign mode in the main controller as simple as creating a campaign object and hooking it up to the enemy spawner. The main controller still choreographs level transitions and handles all the menus.

Main Menu – I’ve been ambitious and presumed I’ll manage to get a tutorial level made this week.

On the topic of level transitions and menus, I spent a while beefing up the UI. There is now a proper menu with a few game modes, pre- and post-level overlays, and a game over overlay. Using overlays with a simple button to proceed saves a little development time compared with choreographing the peri-level events with coroutines, and is fine for my purposes. Even so, messing with fiddly GUI code often takes longer than it seems it should, but that’s not where all the time went.

Start your engines!

Level complete!

I also spent a while messing with the spawners, particularly the enemy spawner, to make the game flow for campaign mode simpler. Both spawners can now remove all the objects they’ve spawned ready for the next level. Enemies had a tendency to pile up when they were spawning individually in random locations, so I changed the enemy spawner to spawn waves, with enemies distributed more evenly along the top of the play area. I also added an interface to the enemy spawner that describes some values related to spawn rate. By implementing this interface in the campaign class, the game controller can link the current campaign object to the spawner and they can sort things out among themselves, but I keep the flexibility to hook the spawner up to other implementations for a different spawning experience (e.g. for controlled spawning in a tutorial level).

HUD, and spawn waves

Finally, I messed with enemy activation so that their corpses hang around for a sensible time before disappearing. This was necessary since they appeared to be teleporting when they were recycled, and they could be recycled almost instantly, which was somewhat jarring. This will not be such an issue when spawning is moved off-screen, but who knows when I’ll get around to that?

Game Over!

Goal for day 5 (morning): kill them with science!

With game modes basically working, all that’s left of the fundamental game concept is the science stat and associated damage modification, so that is the task for Saturday morning. I’ll also tackle the bash-on-click functionality to get things feeling nicer and bring the difficulty up somewhat. I’ll evaluate my progress and set new goals around lunch – that should help avoid getting too caught up in minor tasks and losing the second half of the day to useless fiddling.

Day 3 – Lose!

Development time: 200 minutes (running total: 520 minutes).

Don’t worry! It isn’t lose as in development-failure, just that the loss condition is now implemented so it is possible to lose the game. Today’s development was steady and I covered most what I wanted again, with a lot less problems than yesterday. I even made a quick fix to my collision issue before work thanks to a tip from Doolwind.

I spent a while cleaning up the enemy spawning script, and fixing a bug in which enemy transform and rigidbody properties weren’t properly reset during recycling, causing them to spawn in unintended locations. Once cleaned up, the enemy spawning script made a decent starting point for the scientist spawning script, I just had to remove some unnecessary timing elements and make a few adjustments.

Scientist spawning.

I added some extra walls to keep the enemies in, and added inert box colliders to the spawners to make their scale visible, since I’m using it determine the area in which to spawn things.

With the scientist spawner able to determine when all the scientists have been attacked, it was time to add some higher-level choreography to the scene. I created a basic game control script that keeps track of game state and game mode, with a few methods the spawners can hook into to report important events (enemy and scientist deaths). I added a display for score (just the number of enemies killed at this stage), and a simple label to indicate game over state.

Game Over!

Finally, I had the game controller hook into the enemy spawner and start turning things up as the score increases, for basic difficulty scaling in survival mode. This only works up to a point, as the enemies have a lot of trouble once they start to pile up, but it’ll do for now.

Increasing difficulty (still needs some work).

Goal for day 4: Campaign Mode and Science!

I didn’t get to the win condition or campaign mode today, so those are first on the agenda for tomorrow. Campaign mode will be made up of levels that have an increasing number of enemies to defeat, gaining an extra scientist between levels. I don’t anticipate a lot of complications, just a bit of rearrangement in the spawners and a bit of extra state for the controller, so I should also have time to add the science stat, and possibly move the crowbar up and have it swing down on mouse clicks (for a more satisfying bludgeoning experience).

Day 2 – Stumbling Time

Development time: 180 minutes (running total 320 minutes).

After such smooth sailing on day 1 I was hopeful and naive. I sat down this afternoon enthusiastic and ready to dive into development and get a lot done. I started out well and managed to complete most of what I had planned, but my inexperience with Unity tripped me up somewhat along the way, and overall I spent longer than expected and didn’t feel like my progress was very good.

Issues

The first stumbling block came in the form of colliders and triggers. If there’s an easy way to have both a trigger collider and a physical collider I haven’t found it yet. I was loath to give up my ability to shove the enemies around, so I ended up spending a bit longer than I should messing with parenting and other things. Eventually I went with the simple option that I should have started with – just set the crowbar collider as a trigger and let it pass through things. While cool, the physical interactions aren’t essential to core gameplay so they can wait until I’ve done a bit more reading.

I hit several issues adding enemy spawning, none severe but the extra minutes add up under severe time pressure. First my script wouldn’t run, which appears to have been caused by a naming mismatch. Once it was running I wasted a bit of time trying to invoke a coroutine incorrectly. Finally, I messed around too long trying to add spawned enemies to a list and as children, basically because I wasn’t sure of the type of a returned object and didn’t check the example or documentation as soon as I should have. I wasn’t trying to do anything too unusual here, and I can put all of these issues down to simple inexperience.

Lessons

I know that with a bit of practice, all these problems will start to look very naive. They already seem at least a little silly as I’d already seen some of the solutions in the tutorials at least once, so some of the wasted time was unnecessary. Since wasted minutes are such an issue in this project, I’ll put the lessons here to ensure that for the remainder of the project I don’t waste more than a few seconds on issues I’ve already encountered:

Progress

Despite hitting some snags, I managed to get through most of what I intended: enemies now spawn at the top of the play area and head towards the bottom; enemies lose health when colliding with the crowbar, proportional to its speed; enemies stop moving and change colour when their health falls to (or below) 0; dead enemies are recycled to spawn new enemies.

Enemiy spawning.

I didn’t have time to get scientists spawning, but that should be trivial after working out all the issues with the enemy spawning script. I wasn’t planning to remove the physical effects of enemies colliding with the crowbar, so I want to get that back at some point – either with extra colliders or just by manually changing velocity in the collision event – but other things are higher priority at the moment. The important thing for now is that I can now bludgeon head ticks to death to take out the frustrations of development snags!

Enemy death (red == dead).
Spawning enemies with the spawner as parent.

Goal for day 3: win or lose

Scientist spawning will be easy, and with it I’ll be able to keep track of the scientists and decide when they all have a blob latched onto their heads, so I’ll get the lose condition implemented in the next session. Winning should be simple as well – count spawned enemies and win when enough have been defeated. With winning and loss, this will be a good time to get some basic menus and HUD done. By the end of day 3 I should be able to have a survival mode and a simplified ‘campaign’ mode working. I won’t commit to more than that, since it’s a lot more satisfying to do more than I planned than to do less.

Day 1 – An Excellent Beginning

Development time: 140 minutes.

I have to say this project is off to an excellent start. Unity makes throwing together a basic environment with some simple objects very easy, so I was able to get a play area with a crowbar, a couple of enemies and some scientists put together in very short order, and had enough time to make a reasonable start on the coding.

The crowbar moves around with mouse movement, the enemies make their way down the play area in hops and leaps until they get in range of a scientist, then they leap at him and spend the rest of their life attached to (i.e. hovering above) his head. The crowbar can be used to shove the enemies around too, which was not directly intended yet but does make the game basically playable.

Everything in the scene is pretty basic for now: the play area is a grey plane with a rectangular prism wall at the back (added to stop the scientists tumbling off the edge when the enemies run into them); the crowbar is a skinny rectangular prism in an attractive red; the enemies are squashed spheres, with a box collider as the sphere collider was making them roll; the scientists are simple cylinders.

If I’ve made good progress with the core gameplay by the weekend, I may have time to mess around in Blender and make some simple models, but that’s a whole 4 days away so I’d best not get ahead of myself – I certainly don’t need fancy models to make it work.

Goal for day 2: clobbering time!

I’ll aim to give the enemies health, give the crowbar the ability to take it away, and have the enemies spawning rather than just having a few at the top from the start. There should also be time enough to have the scientists spawn programatically, and have the game end when they’ve all been attacked. If I get through all that with time to spare, I’ll get some basic menu together, but that’s getting ahead of myself again.

Make a game in a week? Sounds insane. Probably is. Read on to discover why I would attempt such a thing.

Day 0 (i.e. before I started)

For my birthday this year I got myself something wonderful: Unity3D. I’ve just spent a week learning it, now I want to see what I can do!

For the month leading up to my birthday I decided to have a go at doing things the hard way and ended up with a decent cooperative block-stacking game with some addictive, annoying audio. That’s a subject for another post.

As development terrain goes, working with C++ and SDL was a bit like a jungle with some well-beaten paths – bring a machete and watch your step, but don’t worry too much about getting lost if you’re an experienced explorer. City folk had best bring a guide.

One of my main reasons for hacking my way through the development jungle was to get an appreciation for how far we’ve come and what’s being done for me by more modern tools. I think it worked.

Using Unity after doing everything by hand is like driving around a well-designed city. This is my first time visiting, and it’ll be a while before I can get around without a map, but everything is so well laid out that I’d have to be really trying hard to get lost. I’m also driving a hovercraft.

Since game dev is officially a hobby at this stage, I went for video tutorials as a low-stress way of getting a handle on the basics. I dashed through the interface intro, then jumped into a 3DBuzz tutorial series. Overall it was a little slow for my taste, because it isn’t targeted at experienced devs, but interesting enough to breeze through over a week of after-work and a weekend hours.

I’m sure there’s plenty more to learn, but Unity handles the fundamentals well enough that I already feel I know enough to put together a simple game without doing too much wheel-reinvention. Rather than just feel it, I’ve decided to put it to the test, which brings us to this week’s challenge:

In the spirit of a recent 48h game dev comp attended by a friend over the weekend of my birthday, I’m going to see what I can throw together in a few short hours. I have an estimated 8 hours of dev time over the work week, and another 8-16 hours on the weekend, for a grand total of about 20 hours.

For my simple game, I’ve picked one of my simplest game concepts: Science Crowbar. The player will control a crowbar, animated by the power of Science, and will be tasked with protecting scientists from invading Head Ticks that threaten to turn them into mindless zombies. Non-zombified scientists generate more science, allowing the crowbar to continue defending them. I suspect the current game club activity may have had an influence on this idea.

In practical terms, I am aiming by the end of Sunday to create a single game screen (plus menu) without worrying about story progression. Levels will have random enemy spawns with a faster spawn rate as the level number increases. Surviving scientists will continue to the next level, and extra scientists will be rescued between levels (implicitly, for now). There is a lot more I’d like to do with the concept, but I’ve pared it down to the core gameplay and basic difficulty progression for this initial prototype.

So, can I make a stable, simple game in a week with Unity? I’m about to find out.
Place your bets!

Update: check out my progress on Day 1

Christian Neumanns considers that null should not be hated, as elaborated in his article Why We Should Love null. Essentially he concludes that the compiler should treat nullable fields as though they are option/maybe types, and should prevent use of the values before they have been checked for nullity. Some notes follow, as far as I maintained interest.

Therefore some developers try to avoid null. For example, they use 0 instead of null in case of a number value, or their functions return an empty list or an empty string instead of null.

In some cases an empty string is a reasonable substitute for no value. I am thinking particularly of display in a user interface, where showing no characters may be the right thing to do when there is no value. 0 is far more dubious. Some developers doing the wrong thing is more a comment on those developers than it is on the validity of using null. I would not be at all surprised to hear those same developers generating plenty of null pointer errors back in their null-using days.

In real life, we are all used to the notion of ‘nothing’ appearing in thousands of different ways.

This is a total red herring. The problem with null has nothing to do with whether it is reasonable to have a representation of the concept of “nothing”. The problem is when developers fail to consider what their code will do if it gets “nothing”. I suppose this is because we write code to take particular types of inputs and manipulate them, and nothing is not a type of something. For example if I ask someone to hand me a pencil, I am not expecting them to make the motion of handing me a pencil with nothing in their hand – that would be nonsensical.

More than an astonishing 99.999% of the universe is nothing – just empty space.

Make that a very large red herring.

Instead of using a non-null value to represent ‘no data available’ it is (in most cases) much better to use null.

Yes, we increase the risk for null pointer errors. But we decrease the risk for outcomes that are worse, such as delivering wrong results without any error message and other unacceptable or catastrophic situations – for example letting users buy houses for free.

This is true, but also a moot point. Why accept either possibility?

‘unhappy’ is better than ‘very unhappy’.

And both are worse than ‘happy’. This attitude looks how the result of years of doing the best that Java will allow.

Hence, we should embrace null and make it our friend and … love it!

Odd to make such a conclusion before looking at the more relevant alternatives…

Don’t use the Null Object pattern just to avoid null pointer errors.

This, and the reasoning behind it, I agree with. Null is problematic because it can sneak in where an actual something is expected (in many languages). Introducing something else that can do the same is no solution at all. They may have their place though. Again I am thinking of a user interface that could reasonably have a blank space when there is nothing to display – if there is an object that is just giving text to display, a null object that gives empty strings might make for more readable UI code than putting all the conditional display logic in the UI code itself.

If we call get() without first checking the presence of data with isPresent() then we get a NoSuchElementException if there is no value present.

It is a shame that Java is not expressive enough to give a compiler error for this. As a best-effort approximation, a boolean field that is false, and set to true when isPresent() is called would help to catch many of these cases. It would still be a runtime error, but the error would happen any time the code runs so the developer is far more likely to see it before it can cause problems for a user. A major limitation is that as soon as the option container has been checked once it will no longer throw an error, even if it is passed around to different scopes in which its contents have not been confirmed as non-null.

If a method is declared to return an Optional, nothing prevents the programmer who implements the method from (involuntarily) returning null instead of returning a non-null Optional.

This is a weakness of Java, rather than of the Optional pattern.

If we accidentally construct an Optional by calling method of() with null as input, we get a NullPointerException.

This is an advantage over plain null, since it moves the error closer to the origin of the null value. The problem here only exists because of the use of null in the first place. In an ideal world this is something that only I/O drivers would have to deal with. Java is a long way from any kind of ideal world.

The compiler cannot force programmers to use Optional in their own methods. It is up to the programmer to decide whether he/she returns an Optional or simply sticks to returning null in case of no data.

Unless the programmer has heard of static analysis, that is…

Existing standard Java libraries cannot be retrofitted to use Optional because this would break backwards compatibility.

They cannot be retrofitted, but they can be wrapped in facades. A disciplined developer could approach some semblance of sanity in their own code that way.

At the end of my previous learn-Haskell post I was just finished using some lifters for monads for a log parser. The next part of the homework was to make a binary tree to hold the log messages. I think I made something similar in ML as part of Programming Languages on Coursera, and the types for the tree nodes were already defined, so this was fairly straightforward.

The main part to get right was inserting log messages in the correct order:

insert :: LogMessage -> MessageTree -> MessageTree
insert (Unknown _) t = t
insert m Leaf = Node Leaf m Leaf
insert _ (Node _ (Unknown _) _) = error "Invalid Node: a node must not contain Unknown"
insert m@(LogMessage _ t _) (Node l m2@(LogMessage _ t2 _) r) = case compare t t2 of
  LT -> insertOnLeft
  EQ -> insertOnLeft
  GT -> Node l m2 (insert m r)
  where insertOnLeft = Node (insert m l) m2 r

I could have done a few things differently – the error condition could be ignored, but it feels much better to include it so that I have a total function (as far as I understand function totality). I could also have taken a different approach to the last case, using an if then else such as if (t <= t2) then Node (insert m l) m2 r else Node l m2 (insert m r). This may be more readable, now that I think about it, since compare t t2 isn’t quite as intuitive about what is less than what. I could also probably have done something with guards, which might have been nicer.

One thing I would have liked to do is leave off the t in the first pattern, giving insert (Unknown _) = id, but this seems to make it incompatible with the other patterns.

As usual, I am sure there are some abstractions I could use over this code to make it simpler, but I am happy enough with this for now.

I ended up with a nice little function to build an ordered tree out of an unordered list of log messages:

build :: [LogMessage] -> MessageTree
build = build' Leaf
  where build' = foldr insert

Looking at that now, I think I mustn’t have sat back and looked at it after I simplified the where clause, because I could as easily have written build = foldr insert Leaf, which is faster to comprehend.

Converting the ordered tree back to a list was straightforward – I’m not totally confident about the performance characteristics, but I doubt that is worth worrying about at this stage of my learning.

inOrder :: MessageTree -> [LogMessage]
inOrder = (`inOrder'` [])
  where
    inOrder' Leaf lst = lst
    inOrder' (Node l m r) lst = inOrder' l (m : inOrder' r lst)

I have been working through the week 2 homework exercises, and had a bit of a rocky start. I got it working without much trouble, but I had a real mess of code:

-- parses individual line from the log file
parseMessage :: String -> LogMessage
parseMessage line = case words line of
  "I" : time : message -> case maybeRead time :: (Maybe Int) of
                            Just t -> LogMessage Info t (unwords message)
                            _ -> Unknown line
  "W" : time : message -> case maybeRead time :: (Maybe Int) of
                            Just t -> LogMessage Warning t (unwords message)
                            _ -> Unknown line
  "E" : severity : time : message -> case maybeRead severity :: (Maybe Int) of
                            Just s -> case maybeRead time :: (Maybe Int) of
                                        Just t -> LogMessage (Error s) t (unwords message)
                                        _ -> Unknown line
  _ -> Unknown line

This is awful – so full of duplication and really not pleasant to read. I couldn’t leave it like that, so I set about at least separating out the code for determining the message type. I ended up with something at least moderately readable:

parseMessage line = let (messageType, rest) = maybeGetMessageTypeAndRemainder line in
  case messageType of
    Nothing -> Unknown line
    Just aType -> case rest of
           [] -> Unknown line
           time : message -> case maybeRead time :: (Maybe Int) of
             Just t -> LogMessage aType t (unwords message)
             _ -> Unknown line

-- partition the message type and remainder of the string
maybeGetMessageTypeAndRemainder :: String -> (Maybe MessageType, [String])
maybeGetMessageTypeAndRemainder line = case words line of
  "I" : rest -> (Just Info, rest)
  "W" : rest -> (Just Warning, rest)
  "E" : severity : rest  -> case maybeRead severity :: (Maybe Int) of
                              Just s -> (Just (Error s), rest)
                              _ -> (Nothing, words line)
  _ -> (Nothing, words line)

It still looked wrong though, with a number of cases mapping to the exact same code. It was at this point that my brain kicked into gear, and I had to laugh out loud when I realized that I was using the Maybe monad and completely ignoring one of the main uses of monads: that thing where you chain them together. I had forgotten what it was called (the back of my mind said ‘bind’, but it is a human mind so I did not trust it fully), but I knew what I wanted it to do, so I plugged this into Hoogle: m a -> (a -> m b) -> m b, and it obligingly reminded me that I’m looking for (>>=) :: Monad m => m a -> (a -> m b) -> m b. It was indeed ‘bind’.

After a short break to make some tea and let my brain process the problem a little with its rediscovered knowledge, I set about setting things right.

My approach would be to use Maybe tuples to pass through the parsed and unparsed sections of a log message. The tuples would increase in size until they were used at the end to construct a LogMessage… but wait! It occurred to me that I may even be able to get away with only using pairs, if I could partially apply the LogMessage constructor. I gave it a little try in ghci:

*Log> :t LogMessage
LogMessage :: MessageType -> TimeStamp -> String -> LogMessage
*Log> :t LogMessage Warning
LogMessage Warning :: TimeStamp -> String -> LogMessage
*Log> :t LogMessage Warning 5
LogMessage Warning 5 :: String -> LogMessage

Aha! So I would be able to build up a log message along the way.

Tried a bunch of stuff, got confused about bind (>>=), nutted it out and used (>=>) but had to add return to the final appendMessage.

At this point I asked on #haskell-beginners on freenode, and got a bit of advice:

jle> so the thing is, if you have m a jle> you can apply all sorts of functions to it, you just need the right lifter jle> if you have an (a -> b), you use fmap jle> if you have an m (a -> b), you use ap (or (<*>)) jle> if you have an (a -> m b), you use (=<<) , or (>>=) jle> fmap :: (a -> b) -> m a -> m b jle> (<*>) :: m (a -> b) -> m a -> m b jle> (=<<) :: (a -> m b) -> m a -> m b jle> so…there ya go

Then went on with a whole lot of information, too much to process for the moment. I was directed to watch the week 4 videos of a functional programming course, so I have added those to the list.

I persevered a bit more and ended up with something that seems about as concise as I can make it:

parseMessageType :: String -> Maybe (TimeStamp -> String -> LogMessage, [String])
parseMessageType line = case words line of
  "I" : rest -> Just (LogMessage Info, rest)
  "W" : rest -> Just (LogMessage Warning, rest)
  "E" : rest -> parseErrorSeverity rest
  _ -> Nothing

parseErrorSeverity :: [String] -> Maybe (TimeStamp -> String -> LogMessage, [String])
parseErrorSeverity (severity : rest) = case maybeRead severity :: (Maybe Int) of
                                  Just s -> Just (LogMessage (Error s), rest)
                                  _ -> Nothing
parseErrorSeverity _ = Nothing

parseTimeStamp :: (TimeStamp -> String -> LogMessage, [String]) -> Maybe (String -> LogMessage, [String])
parseTimeStamp (_, []) = Nothing
parseTimeStamp (logMessage, timeStamp : rest) = case maybeRead timeStamp :: (Maybe TimeStamp) of
                                    Just t -> Just (logMessage t, rest)
                                    _ -> Nothing

appendMessage :: (String -> LogMessage, [String]) -> LogMessage
appendMessage (logMessage, message) = logMessage . unwords $ message

parseValidMessage :: String -> Maybe LogMessage
parseValidMessage = fmap appendMessage . (parseMessageType >=> parseTimeStamp)

parseMessage :: String -> LogMessage
parseMessage = liftM2 fromMaybe Unknown parseValidMessage

parseLog :: String -> [LogMessage]
parseLog = map parseMessage . lines

I can probably simplify some of the earlier functions in wonderful ways of which I am not yet aware, but that will do for now. I can always look back at this later when I have learned more, and laugh at the verbosity of the above.

I did some reading and got through all the recommended chapters of Learn You A Haskell and Real World Haskell.

Playing around

I also explored several concepts, including composing functions that take multiple arguments. I did not find evidence of any built-in functions, so I ended up defining this:

composeDiadic :: (c -> d) -> (a -> b -> c) -> a -> b -> d
composeDiadic f g x y = f (g x y)

(.:) = composeDiadic

I wanted to make this because I was playing around with lists of lists, and found intersperse, concat, and a function that combines the two: intercalate. I wanted to rewrite intercalate as a little exercise, but it did not like concat . intersperse since (.) does not expect any function that takes 2 arguments.

Lecture 2

Algebraic data types are defined like so:

data MyType = Constructor1
            | Constructor2 Type1
            | Constructor3 TypeA TypeB
  deriving Show
  • add deriving Show after a data type definition to automatically make it able to be displayed as a string.
  • type constructors and data constructors inhabit different namespaces, so single-constructor types often use the same name for both.

Pattern Matching

  • Parens are needed for pattern matching around a data constructor that has one or more parameters.
  • Bind the whole value to a name using something like myFuncton name@(Constructor2 a) = <do something with name>

Resolving merge conflicts is something I do now and then, but not every week (if I had to do it every week, there would be something quite wrong with my team’s development process). As a result, I often have to look up some of the syntax. This is a personal reference for the things I usually want to do:

Use a merge tool

git mergetool allows each conflicting file to be opened in a merge resolution tool (whichever is configured or installed).

Just use one or the other version of a file

git checkout --ours path/to/file.md

git checkout --theirs path/to/file.md

For git versions before 1.6.1, see keep either file in merge conflicts

I decided to get my editor set up this evening, before I make a start on the homework exercises.

I tend to use Sublime Text 3, so I am adding Sublime Haskell to get it sorted.

The first instruction is to get some dependencies by running cabal install aeson haskell-src-exts haddock so I go ahead and do that. Most of it seems to work, but it fails when compiling haddock. I could have saved myself a bit of time by reading the instructions more thoroughly, but I was playing games at the same time. The problem was that the haddock version was too new for the version of ghc that I have, and I had to constrain it to an earlier version, like so: cabal install haddock --constraint=haddock==2.13.2.1.

I decided to go ahead and add some of the “optional, but useful” requirements as well:

cabal install ghc-mod
cabal install stylish-haskell
cabal install haskell-docs
cabal install hdevtools

They all seem to work without any problems.

I frequently forget how to bring up package control in Sublime Text. To do it:

  • Ctrl + Shift + P
  • type ‘Install’ to filter for ‘Package Control: Install Package’
  • press Enter and wait for the next prompt
  • type ‘SublimeHaskell’ and press Enter

That’s it, it seems to be ready to go. Entering Ctrl+Shift+P, haskell gives me a nice set of options.

I started on the first homework. The first exercise was simple enough, and I incidentally learned something about monadic map:

I wanted to have my program print a few different test values, so I made an array of print . This didn’t work so well – main is expected to be of type IO (), and I had ended up with [IO ()]. The solution was to use mapM_ with the list of display values.

  • mapM is a monadic map
  • mapM_ is similar but that does not collect its output

The second exercise was too much for my late-evening brain, so I turned in for the night.

At work the next day I played around on GHCi with ideas my brain had come up with overnight, and got it sorted:

Prelude> :type zip
zip :: [a] -> [b] -> [(a, b)]
Prelude> :type zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
Prelude> zipWith apply [1, 2, 3] cycle $ [id (*2)]

<interactive>:1:9: Not in scope: `apply'
Prelude> zipWith (f x -> f x) [1, 2, 3] cycle $ [id (*2)]

<interactive>:1:10:
    Pattern syntax in expression context: f x -> f x
Prelude> zipWith ((f x) -> f x) [1, 2, 3] cycle $ [id (*2)]

<interactive>:1:10:
    Pattern syntax in expression context: (f x) -> f x
Prelude> zipWith ($) [1, 2, 3] cycle $ [id (*2)]

<interactive>:1:23:
    Couldn't match expected type `[b0]' with actual type `[a0] -> [a0]'
    In the third argument of `zipWith', namely `cycle'
    In the expression: zipWith ($) [1, 2, 3] cycle
    In the expression: zipWith ($) [1, 2, 3] cycle $ [id (* 2)]
Prelude> zipWith ($) [1, 2, 3] (cycle $ [id (*2)])

<interactive>:1:20:
    No instance for (Num ((a0 -> a0) -> c0))
      arising from the literal `3'
    Possible fix:
      add an instance declaration for (Num ((a0 -> a0) -> c0))
    In the expression: 3
    In the second argument of `zipWith', namely `[1, 2, 3]'
    In the expression: zipWith ($) [1, 2, 3] (cycle $ [id (* 2)])
Prelude> zipWith ($) (cycle $ [id (*2)]) [1,2,3]
[2,4,6]
Prelude> zipWith ($) (cycle $ [id, (*2)]) [1,2,3]
[1,4,3]
Prelude> zipWith ($) (cycle $ [id, (*2)]) [1,2,3,4,5]
[1,4,3,8,5]
Prelude> zipWith ($) (cycle $ [id, (*2)]) [1,1,1,1,1]
[1,2,1,2,1]
Prelude> let doubleAlternate = zipWith ($) (cycle $ [id, (*2)])
Prelude> doubleAlternate [2,2,2,2,2,2,2,2,2,2]
[2,4,2,4,2,4,2,4,2,4]
Prelude> doubleAlternate [1,2,3,4]
[1,4,3,8]
Prelude> let doubleAlternateFromEnd = reverse . doubleAlternate . reverse
Prelude> doubleAlternateFromEnd [1,2,3,4]
[2,2,6,4]
Prelude>

Two things are apparent from this:

  1. I need to get more sleep.
  2. I would benefit from some review of things like:
    • operator precedence
    • what exactly $ means
    • paying attention to the order of parameters

I was bored for a moment and had a quick play with the next exercise:

Prelude> :type fold
foldl   foldl1  foldr   foldr1
Prelude> :type foldl
foldl :: (a -> b -> a) -> a -> [b] -> a
Prelude> :type foldl1
foldl1 :: (a -> a -> a) -> [a] -> a
Prelude> let sumDigits = foldl1 (+)
Prelude> sumDigits [5,15,2,8]
30
Prelude>

Putting it all together once I got home was a simple matter of stringing a set of functions together:

validate = (== 0) . (`mod` 10) . sumDigits . doubleEveryOther . toDigits

I would prefer all the functions to be strung together the other way, at least with how I think about things at the moment. I would need (a -> b) -> (b -> c) -> a -> c, but Hoogle just matches (.) and some things with Strategy b, which don’t help me. I could define something like (.>) = flip (.), but for all I know I’m stomping on an existing symbol.

Further investigation turned up >>>, which looks promising. I can import it with import Control.Category ((>>>)). The selective import is necessary, since Control.Category appears to have a function (.), which clashes with the (.) from prelude (which looks to be an alias of <<<). I presume from the package name that these operators are getting right into some category theory, so I might do some reading into that later on.

I am pretty sure that Open Sans by Steve Matteson is my favourite font for reading on a screen. Lately, I have found myself opening the browser’s developer tools and messing with the font-face when I want to read anything non-trivial that uses a font I dislike, but turning on Open Sans is less trivial since it is often not available as a browser default.

I could just settle for a default sans serif font, but that makes my eyes sad. I want my eyes to be tiny smiles when I read, so I wrote some code to fix it:

First I made a script that I can paste into the console:

var lnk = document.createElement('link')
lnk.setAttribute('href', '//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800')
lnk.setAttribute('rel', 'stylesheet')
lnk.setAttribute('type', 'text/css')
document.head.appendChild(lnk)
document.body.style.fontFamily = 'Open Sans'

Finding the script and manually pasting it is not ideal though, so I turned it into a bookmarklet:

javascript:(function(){var lnk = document.createElement('link');lnk.setAttribute('href', '//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800');lnk.setAttribute('rel', 'stylesheet');lnk.setAttribute('type', 'text/css');document.head.appendChild(lnk);document.body.style.fontFamily = 'Open Sans'})()

That is much better, except I don’t tend to keep my bookmarks visible on normal pages (just on my new tab page). I looked around and found this little tool: Convert bookmarklet to Chrome extension by Peter Legierski which let me get an icon next to my omni bar. That did the trick. Peter writes about the conversion tool in his blog How to Convert Bookmarklet to Chrome Extension.

Now I can switch to Open Sans with a single click. Thanks Peter 🙂

It is Sunday evening – yesterday was a LAN and I was up gaming until the wee hours. Now I am back home. I have had enough of games for now; I am sleepy, but it is too early for bed; I feel like doing something. Why not Haskell?

I will begin the journey of learning described in learnhaskell, a guide by Chris Allen.

Installation

This was pretty straightforward. The steps I followed are here for posterity:

  • downloaded and installed Haskell Platform for Windows

    • there was one little WTF in the process – after the installation was done, the wizard informed me that I did not have something called “GLUT”, and asked if I wanted to install it. No indication of what GLUT is. A little investigation indicated that it is probably something related to OpenGL. I decided to install it; I doubt I will use it any time soon, but I was feeling adventurous.
  • opened cmd and ran ghci, and played around to make sure it worked:

    C:\Users\Monkey>ghci
    GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
    Loading package ghc-prim ... linking ... done.
    Loading package integer-gmp ... linking ... done.
    Loading package base ... linking ... done.
    Prelude> 1 + 1
    2
    Prelude> let x = 5 in x * x
    25
    Prelude> let f x = case x of 1 -> "hello"; _ -> "goodbye" in f 1
    "hello"
    Prelude> let f x = case x of 1 -> "hello"; _ -> "goodbye" in f 45
    "goodbye"
    Prelude>
    Leaving GHCi.
    
  • looked at learnhaskell and it said I should have cabal, so I ended up running cabal update then cabal install cabal cabal-install, which seems a bit odd but it said to do that in Getting The Haskell Cabal. It seemed to work as the output included Installed Cabal-1.20.0.1 and Installed cabal-install-1.20.0.3.

First Steps

learnhaskell is telling me to do the “Yorgey course” first. I am informed that this will, in addition to equipping me to write Haskell, help me to understand parser combinators. I am glad about this, because the Wikipedia page for Parser combinator does not seem to be helping much with understanding. Perhaps I just lack education about combinators in general, and about context-free grammars.

Much of the first lecture is familiar from previous study. Key points:

  • Integer is an integral type that is only limited by computer memory, whereas Int is just a system integer that can only be guaranteed to deal with values up to +/- 2^29 (may be bigger depending on machine).
  • backticks make prefix operators infix, parens make infix operators prefix:

    1 + 2 == (+) 1 2
    mod 2 1 == 2 `mod` 1
    (%) = mod
    2 `mod` 1 == 2 % 1
    
  • pattern matching is handy for functions. Expressions are checked in the order they are written:

    factorial :: Integer -> Integer
    factorial 0 = 1
    factorial 1 = 1
    factorial n = n + factorial (n - 1)
    
  • guards use pipe character:

    <functionName> <pattern>
      | <predicate expression> = <value>
      | <predicate expression> = <value>
      | <predicate expression> = <value>
    

    e.g.

    foo n
      | n < 0 = 0
      | n < 10 = n + 10
      | otherwise = n
    
  • function application has higher precedence than any infix operator, so f 3 n+1 7 parses as (f 3 n) + (1 7)

  • make lists with [1, 2, 3], or cons operator: 1 : 2 : 3 : []. They are singly linked lists (cons lists), with type [Integer].

  • String is just sugar for [Char], so ['h', 'i'] == "hi"

Other than a reassurance about error messages, that is it for the lecture. Next is the first homework. It looks exciting, with credit card number validation and towers of Hanoi, among other less illustrated problems, but will have to wait until after I have had some sleep.

The course also recommends Chapter 2 of Learn You A Haskell and two Real World Haskell chapters: Chapter 1 and Chapter 2, so I will have a read of those.

I have been confused more learning Haskell than learning any other language so far. I am convinced that the reason for this is that Haskell requires thought a lot earlier in the process than any other language I have learned, and it doesn’t let you keep your hands busy while you figure things out by typing a whole lot of worthless syntax.

Not only does Haskell require more thinking upfront; it also takes away a lot of the trivial little bits and pieces that let you continue to keep your hands busy and feel like you’re really doing quite a lot of stuff, like telling the computer how to iterate over a list or add some things up. With thought at a higher level, it forces me to just think about what the program is supposed to do, and just tell the computer to do that.

How am I supposed to feel like a l33t h4ck3r if I’m not typing furiously for hours on end?

Really I was just writing a post about Haskell to make a note about a few things to check out or remember:

  • yesod for writing web applications in Haskell.
  • cabal describes, and provides support for, Haskell packages.
  • Hackage is the central package archive for Haskell.
  • learnhaskell is guide on github to learning Haskell, with links to several courses in a recommended order.
  • Learn You a Haskell for Great Good! is, as the name suggests, a book for learning Haskell. It has amusing pictures, and that would be enough, but it is also well written (as best I can tell – I am not an editor or critic).

Fraser at work said that yesod is fairly heavyweight and requires a lot of up-front learning before being able to do much. This probably makes it a poor candidate while learning, particularly since it is just in my spare time. He mentioned two more lightweight frameworks:

@mwotton uses Scotty, and also mentioned MFlow, describing it as a “continuation-based thing, so you can write multi-transaction web code in a single function”. It sounds like something to check out once I’ve covered some basics.

Chris Allen linked Magma (algebra), “so you know what you’re doing in Haskell,” so I’d better check that out too.

There is a mailing list for people learning Haskell: Haskell-Beginners.

In a podcast recently, probably NodeUP, there was some discussion about how much more readable console output can be when it has a bit of colour. I heartily agree – distinctive colours allow my visual firmware to very reliably distinguishing different blocks of text; more reliably than layout alone.

By “visual firmware” I am talking about the parts of the brain involved in the pre-attentive process of visual scene segmentation.

I care about effective pre-attentive processing because it means my cerebral cortex gets a far better indexed set of visual data, so I can avoid some of the conscious cognitive load of manually distinguishing the different things I am looking at. Facilitating effective pre-attentive processing is a bit like adding a GPU to a computer: graphics processing can happen separately from the CPU, leaving more clock cycles for general processing.

So, when I was reminded today that some functionality is being added to our command line client, I immediately set out to figure out how to get nice command-line colours across all the platforms the client can run on. ANSI escape codes do not work on a standard Windows console, so I was pretty sure something more would be needed. This looks like the solution: Jansi, a library that allows Java console output to use ANSI escape codes in Windows as well.