Project Serpent: Days 5 and 6

I didn’t have time to write a blog post yesterday, because I was moving to San Francisco1. I was still doing work though, and today I’ll write a catch up post (in addition to my day 7 post later).

Yesterday (was that the earliest day I haven’t written about? I think so) an enticing thought occurred to me, about how to integrate my [GAME phase, 'GameClock ::: FPS 5] effectful programs into the Javascript model of “compute only in small chunks, so as not to monopolize control of the browser”. The idea was simple and glorious: just write an Effect that provides a “yield” command, and have the handler for that command register the continuation as a JS callback rather than applying it directly!

I spent most of the day thinking about various aspects of this — what type it would need to have and the finer details of how it would work. When I finally got off the plane and arrived at my new home for the next few months, I sat down and started writing some code, and things became much clearer.

Except… they also became a bit less clear in other ways. I don’t recall all the specifics now, but as my ideas started taking shape in the code I was engulfed in a hail of bewildering errors that came about from the specific way that Idris’s Effects library works rather than anything about the semantics of my code. Rather than deal with them late at night, I finally decided to just go to bed and figure out how to massage Idris into accepting my definitions tomorrow.

Likewise, yesterday was mostly spent scrutinizing strange type and inference errors and trying to figure out what I could tell the compiler to make it understand why my code is acceptable. This process was a bit frustrating and took a few long hours, but finally at the end of it all I had shut down the worst of these errors for good, and was able to write this simple program that ticks the gamestate at the correct rate by always sending the snake forward:

dummyGame : { [GAME (Playing False rules), 'GameClock ::: FPS 5, NONBLOCKING] } Eff ()
dummyGame = do
  delta <- yield
  newFrame <- 'GameClock :- tick delta
  if newFrame
     then do collision <- turn Straight
             if collision then playAgain startState else value ()
     else value ()

This piece of code does everything correctly — respecting the frame rate and returning control to the browser after every frame — without having to manually break up the control flow at all. I’m pretty happy with how it turned out!

I still don’t have a way of drawing the game state yet, but that can be solved pretty simply: all I need to do is write an effect that provides drawing commands! I’ll be working on that later today.

  1. actually Berkeley, but I am enough a stranger to the area that I consider them the same. 

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s