Perl 6 on steroids: Through The Window
Posted: 23/03/2014 Filed under: Perl | Tags: games, perl, perl6, steroids 5 Comments
I got into programming because I wanted to write games. I played games as a kid (wolfenstein 3d, putt-putt, I don’t remember the rest of the names), and I thought “when I grow up, I’m going to write games!”
I never really did; at some point I realized I’ve written more compilers than games: whatever happened to the childhood dream? So I thought I’ll write some, to try and learn something new.
With two friends from work I went to javascript game programming conference – it was the only game conf I’ve ever heard of, so I thought “javascript or not, let’s see how gamedev geeks party”. The universal “let’s create idiotic games and make a lot of money on ads and In-App-Purchases” attitude of the startup crowd discouraged me a little bit, but I tried to ignore that bit and focus on the technical content. I never liked javascript, I didn’t really want to use it for any kind of programming, and frankly, working in Perl and Python I grew tired of dynamic typing altogether, but I thought “hmm, maybe if I created a superset of JS that has nice type annotations, that the compiler checks and then drops, emitting vanilla JS, that wouldn’t be so bad to write code in”. I consulted a friend of mine, and, as it usually happens, it turned out that such thing already exists: it’s called Typescript, and Microsoft created it long ago. Oh well, let’s give it a try.
Why am I writing about all this? Where does Perl 6 come in? Thing is, when I started programming in Typescript, I got annoyed. It’s severly underdocumented, undersupported, development is not pleasant, because you get some errors from the compiler and then different errors from a browser, but the worst thing is: it was slow! It was so slow it was unbearable, and I thought “ah, screw it. I’ll be better off with Perl 6”.
I chose Perl 6 for performance reasons! Ain’t that something to tell my grandkids about.
Of course, creating games in Perl 6 is not so trivial: I’ll have to write the engine/framework/whatever myself. Time to roll the sleeves up and get to work.
I got quite motivated by http://lessmilk.com. This guy creates a new game every week to learn game development. Cool thing! He was describing phaser.js in one of his articles, so I created Steroids, and modelled it after Phaser.
Why steroids? Well, at some point I ported my C Asteroids to Perl 6, as a proof of concept, to see if it can indeed handle 60fps games (it can), and the “steroids” bit somewhat got stuck in my mind. Also, being on steroids gives you much more flexibility than, say, being on the rails. Don’t worry, nothing bad about being on Steroids: Just ask Duke Nukem, he got by just fine.
So, Perl 6 on Steroids was born. I started writing a running-jumping game, and abstracting the commonly used bits to a module as I went on. Why a running-jumping game? Well, you asked for it: it’s time for another backstory:
Ever wrote in a backseat of the car as a kid, looking out the window? Did you imagine a person running along the car, jumping over obstacles? I did, and from what I’ve heard I am not the only one. Thus, “Through the Window” was born: a game where a man runs along the horizon, jumping over trees and cows, being the first showcase for Steroids, and a reason for it to exist.
The post is getting lenghty enough, and there’s much to announce still, so I’ll run through the 80 lines of code really quickly to show you what Steroids gives you. You can read the entire source code here
class Game is Steroids::Game
You create a class that inherits from Steroids::Game. You need to define at least two methods for it to make any sense: create() and update(). The former initializes the game, and the latter is called 60 times per second to update the game state.
Some of the things you may want to do in the create() method:
self.load_bitmap(‘background’, ‘assets/background.bmp’);
self.add_sprite(‘background’, 0, 0);
Pretty self-explanatory. Steroids handles loading bitmaps from disk for you, and putting them in a scene.
self.load_bitmap(‘runner’, ‘assets/runner.bmp’);
$!runner = self.add_sprite(‘runner’, 50, GROUNDLEVEL);
$!runner.y -= $!runner.h;
$!runner.gravity = 1;$!runner.when({ $_.y > GROUNDLEVEL – $_.h }, {$!runner.y = GROUNDLEVEL – $!runner.h;$!runner.velocity[1] = 0;});
method update {if @!obstaclesand @!obstacles[0].x < ($!runner.x + $!runner.w) < (@!obstacles[0].x + @!obstacles[0].w)and $!runner.y + $!runner.h > @!obstacles[0].y {say “===========================================”;say ” Game over! You traveled $!distance pixels “;say “===========================================”;say “”;self.quit;}
if $!distance > $!last-obstacle + 40 and rand > 0.9 {my $s = self.add_sprite(<cow tree>.pick, self.width, GROUNDLEVEL);$s.y -= $s.h;$s.velocity[0] = -12;@!obstacles.push: $s;$s.when({ $_.x < 0 – $_.w }, {self.remove_sprite($_);@!obstacles.shift;});$!last-obstacle = $!distance;}
if self.is_pressed(“Space”) and $!runner.y == GROUNDLEVEL – $!runner.h {$!runner.velocity[1] = -22;}
I enjoyed having the game running on the android platform. It would be nice to have a perl6 platform like kivy (kivy.org) for app development.
[…] I kept the best thing for last: tadzik has been working on a tiny game development framework on top of SDL2 and has made an example game with that. On top of that, he’s called out a game development contest that’ll go until sunday. Find all the details on his blog. […]
Is there any chance to have the perl6 language running on the android platform soon? If this were possible, it would have a big impact on the use of perl6 language.
The blocker that I know of is that Dalvik (Android’s VM) doesn’t support invokedynamic, which is a JVM feature that rakudo-jvm relies on. Either we have to wait until Dalvik catches on, or we’ll have to work out a version of Rakudo-jvm that doesn’t use invokedynamic (which would be slow). So: it should be possible at some point, maybe even soon if somebody gets around to it :)
There’s possibly another solution which follows the Retrolambda approach. Read jnthn’s response to http://irclog.perlgeek.de/perl6/2013-07-25#i_7370179. That said, I suspect it’s considerably more work than the weekend it took Esko to create Retrolambda. ;)