That One Idea

You probably have a list of project ideas. You wrote it down on a an actual piece of paper a long time ago. After a while you moved it to a text file on your desktop, which you later moved to a file on Dropbox so that you could add ideas from anywhere. Next, maybe a note on Evernote or Google Keep so that you could strike out an idea you completed (always fun). You maybe even graduated to a Trello board.

There are couple of items on that list that survived all of the transitions. They're not amazing by any means, but they're solid, and someday, soon, you're gonna strike them off as well. I just started working on one of those ideas that have been with me for a long time, and it feels good to see it come to life slowly but surely.

The idea came from a real need. I had a long period at work where my days were very busy and yet I felt I was not advancing the main project I worked on. At the end of each day I would try to break down why I didn't have time to work on my main task, what were the distractions (meetings, other projects, mentoring other developers) and how much time I put into each one, but the hours just didn't add up. What I wanted was a time tracker (which there are tons of), but one where I could just put down a sentence describing what I just spent time on and how much time and let the tool do all the rest. The concept I came up with is super simple, and you will probably understand it in five seconds. I call it hashtime.

Click the image to pause the animation.

The Stack

I usually use my side projects as an excuse to learn and experience some new technology, library or framework, but it's not easy to keep the balance between putting time into learning something and actually advancing the project. The stack for the last side project I worked on included React, Redux, PostgreSQL and NodeJS. All were new to me except for node so it took a while to get going, and by the time that happened I kind of lost my momentum. Oh I'll get back to it, it was a great idea, but it kind of fizzled out. For hashtime, I thought it would be cool to dogfood the tool for the actual work I put into it, so I wanted to get something working really fast and I figured I'd maybe use stuff I already know instead of learning something new. Turns out I didn't need to comprise.

I chose Firebase for the backend and database, and vue.js for the frontend. Firebase is a "backend as a service" which used to be based around a real-time database, but has recently grown into a full blown backend with the addition of hosting, authentication, storage, analytics and more. The first thing I usually work on is authentication and a user model which usually takes some time, but with firebase you get pretty much everything out of the box, including a drop-in UI solution for web, iOS and Android. Getting up and running was super easy and I had something working in no-time. Not having a backend feels weird, but so far it hasn't set me back in any way.

For the frontend I felt that I needed something lightweight, as this seemed to me like a simple application (don't they all at first). I'd heard a lot about the simplicity and straight-forwardness of Vue.js and decided to try it out. The boilerplate I used is based on Webpack and it's pretty good. It includes hot-reload, linting, testing and CSS extraction. Together with vue-router I got a basic SPA application up and running pretty fast, which let me test out the tool using the work I had put into it which is pretty cool.

Long But Not Lost

Like many other projects, this is not the first time I've started working on this idea, and it probably won't be the last. It's typical (for me at least) to start working on something, lose momentum and stop only to come back to it again starting fresh with a different stack (obviously, otherwise where's the fun?). Will I finish it this time? Well no project is ever really finished is it? it can always be better. I think the better question to ask is will I put it out there this time? It being a polished product, or a working prototype. Maybe a proof of concept? Some screenshots? A Blog post?

Yes!

Feedback Wanted

If you have some suggestions or if you would like to use hashtime, shoot me a comment/email/tweet.

Elm Plane - a Flappy Bird Clone in Elm

The really interesting topics are the ones you don't really get at first. For me, reactive programming is such a topic - I understand enough to get by, but I don't yet think in a functional reactive way. So, what better way to get into that state of mind than to try writing something in a language where there is no other choice but to write pure functional reactive code?

It's been a while since I learned a new language. Sure, I read the odd blog post about Go or Rust and I can definitely recommend the book "Seven Languages in Seven Weeks" for a glimpse into some interesting concepts, but it wasn't until I heard about Elm on the JS Jabber podcast that I thought, this is exactly what I need! (I later heard about PureScript in another JS Jabber episode and it sounds very interesting as well).

I wanted to quickly pick a small project to start working on and settled on a flappy bird clone. There are a lot of blog posts about Elm which helped me get started, so I'm not gonna talk about basic Elm stuff here as I feel it is pretty much covered (check the end of the post for links to a few of those posts). Instead I'm going to break down the code and describe some of the interesting bits in depth.

The pattern for writing games in Elm (or applications for that matter) breaks down the code into four parts:

The Model holds the state of the game which will include positions, velocity, score and other stuff like that. This is kind of like the application state in Flux/Redux. Like everything else in Elm this state record is immutable, which means that we're not gonna modify that record, we're gonna replace it with a new record every update.

The Input part defines the inputs for the game (keys, passage of time) and the Signal for those inputs.

The Update part defines what should be the next state of the game based on new inputs (just like a reducer). A few examples would be:

  • When space is pressed the spaceship should shoot
  • When the up arrow key is pressed the character should jump.
  • When a millisecond passes the plane's vertical velocity decreases due to gravity.

The View part defines how to render a given game state. It is completely separate from the Update code.

Click the image to pause the animation.

Model

The Model.elm file holds the default game state, the one which every game starts with. The file also contains all of the relevant type definitions and a constants record that holds all sorts of variables that the game uses that, well, stay constant - size of things, value of gravity and speed etc.

Here's what a game state for elm plane looks like:

type alias Game =
  { state : State                 --1
  , backgroundX : Float           --2
  , y : Float                     --3
  , vy : Float                    --4
  , timeToPillar : Float          --5
  , pillars : Array.Array Pillar  --6
  , score : Int                   --7
  }
  1. The state in which the game is in, can be one of three:
    • In the start screen, waiting for a user input to start a game
    • In an active game
    • In the game over screen, waiting for a user input to switch to the start screen
  2. The horizontal position of the background, used for scrolling the background image.
  3. The vertical position of the plane.
  4. The vertical velocity of the plane.
  5. The timespan left until the next coulmn spawn.
  6. The columns that are currently in the game.
  7. The player's score.

Input

Flappy Bird Elm Plane is a pretty simple game right? the only inputs are one key (space) and the passage of time. So on the first iteration I defined the input type to contain a Bool property and a Time property, where delta is a Float Signal generated by the FPS ticker converted to seconds (delta between ticks).

delta =
      Signal.map inSeconds (fps 45)

type alias Input =                  
    { space : Bool
    , delta : Time
    }

I then defined the Input Signal to sample both on delta. This means that when there's a event on the delta Signal, there will be a event on the Input signal with a value composed of the current state of the of the space key (whether it is pressed) and the current state of the Time Signal.

input : Signal Input               
input =
        Signal.sampleOn delta <|      
          Signal.map2 Input           
          Keyboard.space
          delta

This had an interesting effect. Instead of reacting to when the space key was pressed, every tick the game reacted to whether the space was pressed. So for example instead of "jumping" once when the space is pressed, every tick where the space key was down caused a "jump". When I just kept the space key down it looked like this:

I'm needed elsewhere.

I realized what I actually need is a key down event and not whether space is pressed. Here is the revised Input Signal:

delta =
  timestamp
  <| Signal.map inSeconds (fps 45)

type Input =
      TimeDelta (Time,Time) | Space Bool

The Time Signal looks pretty much the same (I added a timestamp, but that's only for a randomizer, the rest is basically the same). The Input Signal is now a Signal of a new union type which is either a (tuple of) Time or a Bool instead of a record with two properties.

Here is what the Input Signal looks like:

input : Signal Input
input =
        Signal.mergeMany [Signal.map TimeDelta delta
                         ,Signal.map Space Keyboard.space
                         ]

Instead of sampling on time like the previous iteration, this signal will have a new event whenever there is a new tick or there is a change in the state of the the space key (down -> up or up -> down). This way I can handle discrete key presses.

Update

The Update.elm file holds all the update functions. Following the refactor discussed in the previous section, there are two types of inputs - a time 'tick' and a keydown/keyup event. So I defined two types of functions like so:

type alias KeyUpdate =
  Bool -> Game -> Game

type alias TimeUpdate =
  (Time,Time) -> Game -> Game

The main update function just calls all of the update functions according to the type of input:

update : Input -> Game -> Game
update input game =
  case input of
    TimeDelta delta ->
      game
        |> updatePlayerY delta
        |> updateBackground delta
        |> applyPhysics delta
        |> checkFailState delta
        |> updatePillars delta
        |> updateScore delta

    Space space ->
      game
        |> transitionState space
        |> updatePlayerVelocity space

Most of them are pretty simple, so let's look at one of each.

The applyPhysics function is a function of type TimeUpdate that is responsible for updating the the player's vertical velocity:

applyPhysics : TimeUpdate
applyPhysics delta game =
  {game | vy =
    if game.state == Play
    || game.state == GameOver && game.y > -gameHeight/2 then
      game.vy - (snd delta) * constants.gravity
    else
      0
  }

There are two cases where we should apply gravity to the player's velocity:

  • When the game is in Play state obviously.
  • When the player just struck out and the plane falls to the bottom of the screen.

Otherwise, there is no need for vertical velocity, so we set it to zero on the next state.

Here is an example of a KeyUpdate function, the one that sets the player's vertical velocity to the "jump" velocity once the space key is pressed:

updatePlayerVelocity : KeyUpdate
updatePlayerVelocity space game =
  {game | vy =
    if game.state == Play && space then
      constants.jumpSpeed
    else
      game.vy
  }

When the game is in Play state and the space is pressed, set the velocity to the jumpSpeed constant, otherwise keep it unchanged. The space argument will be true only when the the state of the space key changes from false to true following the Input Signal refactor.

View

The View.elm defines how to construct a frame visually based on a game state. It is totally independent from the Update functions (and vice versa). I'm not gonna go into too much detail since the code basically just defines how to build forms for everything - the plane, the columns, the score etc.

The scrolling background is composed of just two identical images which move left using the backgroundX property of the game state:

The black outlined square is the game view that is actually visible. The images keep shifting left all the time until one leaves the game view entirely and is then placed to the right of the other image.

And that's pretty much it! You can find the code on Github, please share any feedback or questions you have.

Links

Here's a bunch of articles I found useful:

Making Pong

Learning FP the Hard Way

Minesweeper - a brief journey from JavaScript/React to Elm

Writing Game of Life in Elm

The Idea Obstacle

Like most other developers I have more half finished projects lying around than unpaired socks. What I have even more of, are unstarted projects. A lot of times I have trouble even beginning a project just because I have cannot come up with an amazing idea (a merely good one just won't do), so I've been thinking I need to find a way to remove "the idea obstacle" and just start coding.

The Innovation Game

There are tons of free game assets to be found online. OpenGameArt and Kenney's site are a couple of examples. I would often sit in front of the monitor staring at an asset collection and thinking - "How could I take these assets, which were obviously created for a specific game genre, and do something amazingly innovative with them that no one has ever thought of before?"

An RPG about an ancient kingdom where an age old war rages between balls and squares? laamme.

This went on and on. At some point it started feeling like I was making excuses to avoid starting a new project. Either that, or I was simply procrastinating in the guise of looking for something that no one has done before.

The Point

So, what is it? The point that is. What's my actual goal here?

Well, there are several, all of equal importance:

  • Be a better developer

  • Be a better game designer

  • Make something that people enjoy

And you know what?

Wasting time trying to come up with a brilliant idea isn't helping me achieve any of these goals.

Ok, this is good, this is progress. I just need to find a way to start with some of the goals instead of all of them at once. I need to remove the obstacles and just start working. This asset collection is obviously meant for a brick physics type of game? Great! I'll just make just that! This set is clearly a flappy bird clone? Awesome! Flappy bird it is!

Instead of getting stuck in the idea stage, I could use it to learn some new game engine or even a new language that I've been meaning to (goal 1). I can make the basic game, and then find what makes its formula good and how I can maybe tweak it and make it better (goal 2). And maybe if I do that, someone might like it and spend a few minutes with it or maybe find the source code useful in some way (goal 3).

So I'm going to start with this "Default Games" idea. I'm going to find game assets and make the game that is depicted in the preview photo. This is a project that has an end in sight, and more importantly, this is a project I can begin now.

This is my very first blog post. Let me know if you enjoyed it and If you have any feedback please share it!