OSC in Games?

Posted on

Had Some Fun This Weekend

Had some fun this weekend :D

So something I've always wanted to have was a decent way of sequencing stuff in games. What does that mean Gaz? Well most super nice things in games are a sequence of events that creating some sort of nice audio visual 'stuff'

Demo-scene coders do this very well and generally use some sort of script specifying what happens when so the music and visuals get nicely synced. It was pretty interesting looking at how these guys did things after a few of the bigger groups chucked a load of their tools and source onto github a couple of years ago.

I'm kind of a lazy swine who doesn't like editing text files, the way this stuff is mostly done and always thought that this would rule if you had some sort of time line you could vary parameters, trigger events and do all that kind of stuff.

Loads of programs have this kind of thing, Max, Maya, Final Cut Pro and even some game engines; Unity, CryEngine and the excellent Unreal Engine 4.

But you know what? This is for home hobby projects. All of those things are tightly bound to either and activity (editing animation, music, videos) or to a specific technology (as is the case with UE4, Unity and CryEngine). I don't really want that, I'd rather write my own cack handed gaming tech that can be instrumented to receive parametric data from any old external program.

So I got a good part of that working after jack-dawing some existing technology and shoehorning it together. Tech piece the first:

OSC

Open Sound Control is a protocol for sending 'stuff'. It's basically a MIDI replacement that fills in some of the horrible gaps MIDI has (low parameter resolution, lag, built around a physical transport {cables! Yuck!}) that can work over the network nicely.

There's a slew of OSC clients and a great little library called OscPack that can receive OSC chatter. And now tech part the second.

Vezér

And this is a generic OSC time line editor. With this you can send information to an OSC server, information that you edit in multiple channels and gets played back, nicely interpolated and sent to an OSC server. It's nice and general, can control MIDI too if you like it and you can find it here.

The Results

Early days but I have a little flying around demo that takes only a couple of inputs (time and field of view) but I got those hooked up to a time line I'd edited.

And it works nicely. The cuts are done by jumping different time points and then increasing / decreasing time at different rates. They sync with some music playing and despite being very remedial looks nice and was easy to put together.

Ha! I even got my iPad controlling the thing using [TouchOsc][touchosc] as you can see below. It's great, the game hasn't a clue what's telling it to do the stuff it's doing. An excellent detachment of mechanics and content :)

There's a lot of potential here. Next up I'm going to try and hook Logic via an OSC -> MIDI bride. Vezér is good but expensive to buy (I already own Logic) and though admirable is a little bit rough around the edges. The other thing I might try is hooking up a tracker like Renoise that already has OSC support directly built in. I wouldn't lose a load of parameter resolution that way and would have less need value interpolation in the game.

gvim $PATH Malarkey

Posted on

What's the problem then?

I've had some funny issues with PATH in gvim and in turn was giving me a bit of gyp running plugins that called external programs (see the excellent Syntastic, ghcmod, a slew of other useful things but most importantly :make)

Sometimes it'd work and sometimes it wouldn't which isn't very computery. I ended up wasting a bit of time on it and this is what I found:

  • It all depends on how gvim is launched
    • If I launched gvim from the command line everything would be fine
    • If I launched from gmrun it wouldn't be fine
    • Or via a shortcut key I'd configured in XMonad
  • In all circumstances running the :!echo $PATH returned the correct values
  • When it wasn't working echoing gvim's path (:echo $PATH {dropping the !}) return a different value

Weird. It's like gvim had two different paths

Do What?

Running a shell command from the ex prompt (:!echo $PATH) spins up an interactive shell which reads .bashrc just fine and returns the correct PATH from the interactive shell's environment.

The ex command :echo $PATH (again no !) shows gvim's environment inherited from whatever process launched it. Plugins spawning processes use this PATH.

If I launch from the terminal gvim inherits the correct path because .bashrc is read which isn't the case for gmrun, XMonad etc.

And you can fix that?

Yes! Set the path you want for all programs in your ~/.login file and this will be inherited by everything.

This is pretty well documented shell behavior, why so tricky?

Well yeah it is. I read this detailing bash startup files pretty early on which put me on the right path (Ha!) but I still ended up wasting load of time for a number of reasons.

The main trap I fell into was not realizing you have to logout and login again for any changes in .profile to take effect which totally makes sense if you think about it for a couple of seconds.

Also I used terminal Vim a lot (works fine) and sometimes launch gvim from a terminal prompt (also works fine) which made testing tricky until I realized some basic home truths about *nix environments are inherited.

And that sent me down the rabbit hole for longer that it should which is why I'm making a not for myself here :D

Babun - Making Windows less Windows

Posted on

Babun is very cool, a very tastefully pre-configured distro of Cygwin along with a useful (though simplistic) package manager called pact.

Introduction to the Babun Project from Tom Bujok on Vimeo.

Sometimes you have to use Windows, it's just the way it is. I find it a bit painful though that's mainly a function of unfamiliarity than any absolute awfulness on Windows' part. I installed Babun earlier this week and the awfulness lessened a bit as it has several things to help me create an environment I feel a bit more comfortable with.

These are the ways that Babun makes me happy:

  • Vim nicely installed and pre-configured
  • Zsh - and even better Oh My Zsh - just the same as one my Mac
    • Git aware too! I really like that my prompt has my current branch in it
  • Nicely isolated - doesn't clash with existant Cygwin installs
  • Update everything script
  • Nice colour scheme and font setup for terminal :D
  • And the terminal is setup well for 256 cols

All in all very happy. I have Vim, Irssi and Tmux using pretty much the same configs I have on the Mac / Linux and can petty much ignore the mouse :D

Shell programming: Iterate through the results of find

Posted on

Iterate through the results of find without messing around with IFS

For my own reference really.

find $in_dir -type f -name "*.cpp" -print0 | while read -d $'\0' file
do
    @echo "$file"
done

Not done much in the way of shell programming before, I'd usually use something like Ruby for this kind of thing. Unfortunately I'm becoming increasingly intolerant of boot up time cost for tiny shell scripts so I'm having a dabble with something quicker.

Initial impressions are it's quite antiquated; overly fussy syntax and doing . That aside though it's also plenty powerful and with a bit of effort you can do most things and yep, it's very quick.

GLSL validation Script

Posted on

I've had to write some GSL recently. Quite enjoyable but the I'd set up a pretty awful development loop. Edit the shader, run the game and then deal with any syntax errors the in game compilation phase come up with.

It's a slow way of doing things. So I spent a -little- bit of effort to compile and check errors for this stuff during my build stage. Details on how to do it below.

It's made things a lot quicker and best of all picks up errors that I was currently missing and would likely not work on all OGL drivers.

Here We Go

A bit specific to my project BUT it's been useful for me in this project so thought it may be worth sharing.

Takes a few GLSL files, concatenates them and then uses the excellent glslangValidator to check for any errors. Any errors are translated into a vim friendly output format.

Caveats

  • You need to specify the type of shader you're validing
    • -t vert or frag
    • Geometry, tessellation and other shader types probably work
    • But I haven't tried them :D
  • Forces #version 150 to the top of all files
  • Assumes path of glslangValidator
  • But that's all easy to fix if you want to
  • It's my first bash script
  • So it's probably shit :)

Might add this kind of functionality to glslangValidator, it seems like something that would be generally and genuinely useful.

#!/bin/sh

__ScriptVersion="0.1"

function usage ()
{
        cat <<- EOT

Usage :  $0 [options] [--]

Options:
-t|type [frag|vert]
-h|help       Display this message
-v|version    Display script version

        EOT
}

typ="vert"

while getopts ":h:v:t:" opt
do
case $opt in
    t)
        typ=${OPTARG}
        ;;

    h)
        usage; exit 0
        ;;

    v) 
        echo "$0 -- Version $__ScriptVersion"; exit 0   ;;

    \?)
        echo -e "\n  Option does not exist : $OPTARG\n"
        usage; exit 1   ;;
esac    # --- end of case ---
done

shift $(($OPTIND-1))


if [ -z "${typ}" ]; then
    echo "You specify a type of either frag or vert"
    exit 10
fi

tmp_file="build/temp.${typ}"

file_num=0

echo "#version 150" > $tmp_file

for f in $@
do
    echo "#line 0 $file_num" >> $tmp_file
    cat $f >> $tmp_file
    ((file_num++))
done

err=$(./bin/macosx/glslangValidator $tmp_file)

if [ "$?" = "0" ]; then
    exit 0
else
    file_num=0
    for f in $@
    do
        err=$(echo "$err" | sed -e "s|ERROR: $file_num:|$f:|g")
        err=$(echo "$err" | sed -e "s|WARNING: $file_num:|$f:|g")
        ((file_num++))
    done

    echo "$err"
    exit 10
fi

Mysterious ECONNREFUSED with net.connect in Node

Posted on

Hit a minor gotcha playing with Node on the Mac recently.

In an app I'm working on I'd set up a simple Lua repl you can telnet into and it works fine. I've got an idea for making an application specific repl using Node Webkit so I started to write simple node to connect to my application repl:

var net = require('net');

var port = 6502;
var host = 'localhost';

var socket = net.connect(port,host, function() {
    console.log("Sending data");

    socket.on("data", function (data) {
        console.log("received data");
        console.log( data.toString() );
        socket.end();
    })
})

socket.on("error", function(err) {
    console.log("Error");
    console.log(err);
})

Only it won't connect. The lua code is pretty simple and binds to localhost:6502 as well, it works fine with nc or telnet but no beans here. All I get back is a connection refused JSON packet

Error
{ [Error: connect ECONNREFUSED]
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect' }

It turns out that the lua socket code I'm using will set up an IPV6 socket when I bind to 'localhost' while net.connect will try and connect via IPV4. Telent and NC don't care and just detects the type of connection to rightly use.

The solutions are either change the node code to bind to '::1', IPV6's localhost equivalent and connect via IPV6 or changed my server code so it binds to 127.0.0.1. Both work and I went for the latter.

There's a lot of things at play here and I don't which one of the many components (if any) aren't playing sensibly. Should localhost always default to IPV6? Should net.connect try and establish an IPV6 connection if it can't make an IPV4 one? I dunno, I'm pretty new to this but it chewed up enough of my Sunday to want to write it down in case anyone else had the same woes :)

XBOX One

Posted on

A little bit late to the party but I hooked up an XBOX ONE at home this weekend. It's pretty good! I really like the voice interface, it's incredibly spooky selecting, playing, pausing and watching Netflix by barking out commands. And it seems to have an anti griefing feature: my boy cottoned on pretty quickly and tried telling it "XBOX WEAR MUMMY'S BRA". It didn't wear mummy's bra. Or pause, or stop of go home or do anything the boy asked it to do. Phew!

No gamez though. No ones I like anyway. Had a quick blast on Killer Instinct. Beautifully made but not really my type of thing. But I am looking forward to Titanfall. Had some enormously good times playing Call Of Duty 4 a few years back and it'd be nice to return to team based blasting with the added bonus of some Crackdown-esque agility. And mechs of course. Great big filthy mechs. Everyone loves those yeah?

Colours Working Properly in Vim under tmux on Linux

Posted on

I couldn't get my colour schemes looking nice in Vim under tmux and it took me a while to sort it out. Here's what I did. Using:

The steps are:

  • Get tmux running in 256 colours
  • Add some stuff to your Vim start-up
  • Select an appropriate colour scheme

I'm kind of a newb at messing with this type of thing so would be keen to hear about any errs, omissions or inefficiencies :) This is mainly a record for me and maybe helpful to anyone else with similar noob levels of experience trying to sort out a similar problem.

Get Tmux Running in 256 Colours

First of all I needed to get tmux working in 256 colour mode as is it was only running in 16 colours and was the cause of every Vim colour scheme I tried look very horrid. How did I know the amount of colours tmux was using? There's handy Perl script called 256color.pl which you can get here. Running it gave me this:

When I should be getting this:

There's a number of solutions on the web that involve changing the term type in your .tmux.conf file. I had varying success with these and found the easiest thing to do wasn't fiddling with the tmux configuration file but launching tmux with the TERM environment variable to something 256 colour-ish:

TERM=xterm-256color tmux

And then I got the right output from 256color.pl. Phew!

I didn't want to type TERM=xterm-256color tmux every time I wanted tmux so I added this to my .zshrc file (.bashrc if you're running bash I guess)

alias tmux="TERM=xterm-256color tmux"

Add Some Stuff To Your Vim Start-up

Vim needs to know there are 256 colours for it play with so you need to tell it in your .vimrc. That's pretty easy, just add this line:

set t_Co=256

Select An Appropriate Colour Scheme

I have a shit load of Vim colour schemes installed from some bundle I got from here :D What I didn't realise is not all of them will work properly in Vim as they were designed for Gvim. To find ones that did I type:

:colorscheme *256<TAB>

And I get a list of all the schemes designed for 256 colours. A bunch of schemes without 256 colours in the name work as well but it's a bit hit and miss whether they do.

And here we are using wombat256 :)

Why Do This? Why Not Stick With Gvim?

Gvim was getting a little bit slow for me from time to time so I was hoping that using the terminal would be a bit nippier. Is it? Yeah a little I guess. What turned out to be a bigger advantage was being able to keep together a bunch of shell processes together as a session I could attach and detach from. I'm currently doing some hobby coding with ClojureScript and to develop for that I need to be running:

  • Vim
  • cljs compiler auto-building any files that change
  • http server
  • Irc (obviously)

They're all terminal apps (I use irssi) and this makes it easy to have all of them running nicely together in split windows as per below. There's no http server on that screen. It's running as part of the tmux session but as I don't need to see it's output very often I just run it in another window.

Creating a Feedback Effect is Pretty Simple

Posted on

Someone asked about video feedback effects for a computer game. It's a powerful tool that can produce amazing effects in the hand of a master but the core principles are really simple. These are the notes I wrote :)

Feedback is a loop where you have a current state and an operation on that state to create a new one. Audio feedback is a good example. The current state is what's going into the microphone and the operation is the audio being amplified, coming out of the speakers and then going back into the microphone.

If the input is silence and the operation adds no new content then the output is silence, not very interesting. Add some input and you can start a feedback loop where you don't need to add any more input but your initial seed will cycle around. If the feedback overloads you can end up with the system getting overloaded

The trick to feedback is tweaking the input and operation so it doesn't overload but gives you an interesting effect.

This is generally how audio effects work; deary, reverb, chorus or flange are all examples of feedback loops that are carefully constructed to produce feedback loops with interesting outputs that don't overload to a screaming howl.

And you can do the same with video. You actually do this in analogue pretty much the same as audio by pointing a video camera at the same screen it's outputting to. Pointed at a black screen isn't very interesting but if you introduce just a little input into the system you'll get interesting patterns generated. The light travelling through the camera and onto the screen gets corrupted by being quantised into transmissible information and those corruptions end up being magnified with every iteration. It's like taking a photocopy of a photocopy of a photocopy.

http://www.youtube.com/watch?v=mKK-q3yjph4

So doing something similar on a computer is kind of easy. You just need a couple of off-screen buffers, a shader to act as the operator and some kind of initial input.

Here's an easy start:

Create textures you can render into - 0 and 1
Clear both of them

loop:
    Draw something new onto screen 0 (input)
    Draw a full screen quad into buffer 1 using buffer 0 and buffer 1 as inputs using your feedback shader (operator)
    Screen 1 is your feedback texture you use in the main game

    Draw something new onto screen 1 (input)
    Draw a full screen quad into buffer 0 using buffer 1 and buffer 0 as inputs using your feedback shader (operator)
    Screen 0 is your feedback texture you use in the main game

goto loop

Feedback Shader

It has two texture inputs: last screen and current screen and you merge these two together.

Here's an easy one, a simple scale and blend where you take the old screen, scale it slightly, blend with the new screen.

It's pretty easy:

  • Read a texel from the current screen
  • Scale the UVs by a small amount (1.01 for example)
  • Read a texel from the previous screen using the scaled UVs
  • Blend them (try 0.9 of current screen and 0.1 of last screen)
  • Return blended pixel

That should scale the texture from one of the corners as UVs run from 0 to 1. If you want to scale from the centre then you need to subtract 0.5 from the UV co-ordinates before scaling and then add 0.5 back before doing the texture read from the previous screen.

I'll try and find some code this weekend but that's the basics. You can put all sorts of fancy stuff in the shader. It gets fun when you operate on te colours as well. You really need a few input parameters that you can tweak as it's easy to overload the feedback and end up with a white screen. The interesting stuff is where the various parameters and inputs add up to something that's just on the edge of overload. You get all manner of interesting shit then. But to get that type of thing you need input parameters you can tweak and a way of saving off interesting effects.

I Must Hate Myself

Posted on

Well this is fun, I'm having a go moving completely to hjkl for my movement keys in Vim. Over thirty years of trusty cursoring and I'm bunging them in the vim bin.

Man it's awkward but also been one of the most consistently recommended things to do by every bit of the Vim community. Let's face it, they're smarter than me so let's see if I can push through the pain and reap the benefits they keep crowing about. Reminds me of all the chat about the famed "runners high" you hear when starting out running. It does exist, you do get it and it's completely awesome but there's a fuck tonne of grind you need to do first :)

Maybe We're Not So Rubbish After All

Posted on

Wow. It's easy to have eagle eyes when calling out the flaws and problems in the world you work in but sometimes it takes startling fuck ups in related industries to appreciate the near impossible things that actually get done right.

On the way into work I was reading this article on the New Yorker about the launch troubles of http://healthcare.gov the web portal to help US citizens get reasonably priced health insurance.

This is staggering. Post 9/11 the FBI contracted S.A.I.C to update their information systems from a highly antiquated software suite that didn't even allow agents to share pictures to a system that'd help rather than hinder investigation into big cases. The project was initially scoped as costing $12m. It's not that unusual for software projects to test their budgets but the eventual cost? An amazing $600m. Even worse the project was canned in 2005. Amazing.

In games there's a lot if self flagellation about poor project management practises, antiquated development methodologies. The baseline assumption seems to be everything is wrong and there's likely a better way, maybe already practised in "proper software development"

But that said a 500 fold increase in budget for a system that never shipped? It's a whole new world of fuck up and surprisingly not a unique or even unusual story. Last year Standish estimated an annual cost of large scale failed software projects of $55bn with only 33% of the projects surveyed able to be classed as a success. It's not just localised to the states either; there are massive problems for our own Universal Credit system as well.

Every year the games industry deliver increasingly compels software in a pretty timely manner close to budgetary constraints. And because of platform cert constraints on console the projects delivered are relatively bug free. Improvement is important but sometimes we should also take the time to acknowledge there's a lot of magic being made in our world that the rest of the software development industry would find hard to match

Live Coding

Posted on

Not made much of a head way with doing my functional game but got a nice setup with clojure to do live coding.

You get the program running, edit some code and then just hit C-c C-c with the cursor over the function you want to be recompiled. And it all works :D Amazing stuff really and really good fun. You can also muck about in the repl. Quite enjoying this.

It's all about 60hz too, the recording is a bit slower as I'm using Quicktime's screen record and this is a Retina machine.

The only downside is it's meant having to learn EMACS but actually that's turned out pretty nice. Learning curve like a cliff but horrendously powerful. I'll have another crack at this on the w/e

Jasmine!

Posted on

image

Do you know how hard it is to find non xxx fan fic pictures of Princess Jasmine on Google Image Search?

I'm converting some of my C++ library code into CoffeeScript. Like everyone else I've a set of 3d maths bits n pieces in the form of helper classes so I thought'd I'd get the across first.

Now I mentioned in the previous post was begining to dawn on me how useful test suites would be for dynamic languages but it was something I hadn't had much exposure to. Well that's changed over the last few days and after a bit of research I've had a go with Jasmine that has a node based implementation.

And yeah, it's been really good. The tests are kind of easy to implement and it exposed quite a few minor things I'd missed. Minor things that could have easily propogated out to be major things a long way away from the actually code if the project I'm toiling on got much bigger.

Here's one of the tests for Vec3 that makes sure if you create a Vec3 with no args it returns a zero vector.

  
# Vec3 Tests
describe 'Vec3', ->

    it 'can make a Vec3, no args, be 0,0,0', ->
        got = new Vec3().getArray()
        expected = [0,0,0]

        for v,i in expected
            expect( v ).toBeCloseTo got[i], 10

This one used to fail and in the game code it did so silently.

And now it's all wrapped up nicely in a build task that gets run if any project file changes. Growl even moans at me when it fails.

Test Driven Development seems to be a pretty hot topic recently and I can see how it'd be a pretty cool approach. Start with your tests and then fill out the code until it all passes. I'd be interested in doing something like this for my C++. Anyone got any reccomendations? The hard thing about taking a new approach usually isn't the work to do it but the dead ends you have to go down finding a good path. I've heard googletest is supposed to be pretty good. Any opinions?

References

previous post jasmine TDD googletest

Coffeescript Gotcha #1

Posted on

Good things need shit things for balance I suppose. There's a great little coffee shop up on the Perth Road that serves, funnily enough, really great coffee. And so it should. No wifi though and my current vice is a bit of lunchtime coding. But I have a 3g wifi hub thing. But the battery just run out. And I left the charger back in the office. One day this will all be very simple indeed, in the meantime I need to get a bit smarter :)

Back to the office

So what did I learn today?

Posted on

Arbroath is further away than it looks on the map

Managed to clock > 50km in a day cycling (Ride 1, Ride 2 and Ride 3 ) for the first time today. A small 5km in the morning coupled with a 45km round trip cycle to Arbroath. The intention had been to to cycle there, coffee shop code for a bit and then come back. That'd have worked fine if I wasn't the sort of idiot who leaves the keys for their bike lock at home. So after 5 minutes of cursing I just cycled straight back.

Must admit I'm still enjoying this, only started in earnest 4 weeks ago but I've now built to a pretty solid with daily commute round trip of 20km per day coupled with a longer run at the weekend. I can feel my legs getting and times creeping up. The ride today ended with the longish climb up Grange Road and the big surprise? It was my quickest time so yet :) A jump to sixth in the segment leader board. In your face Vicki Maclean! :D

Cross Domain AJAX Calls - Empty Calorie Learning

I know about this sort of thing now and kind of wish I didn't. After quick change in how I'm organising my home project I hit a bit of a brick wall with this nonsense. Basically if your page is served to your browser from machine A then your web client can't make an AJAX request to a different domain.

Only it can through the horrid bodge that is JSONP which I got working. But then you find out all requests have to be PUT which breaks the idea of using http verbs to implement a [RESTful interface][REST. So I binned that and have ended up using OSXs built in install of Apache as a proxy to the game that all IO is done through.

And this is great as I'm not getting a better level of separation between my game app and the browser editor client with game only have to handle the REST api. Only the other thing I learned is Apple removed easy access to the Apache server they bundled and in turn had to learn a load of rubbishy rubbish on re-enabling it again and then how to set it up as a proxy.

Also I learnt some stuff about manipulating headers in Apache to allow CORS and also setting Chrome up so it won't moan about trying to do this kind of thing.

And did that move my home project along? No. Gnnnng. It's a shame in some ways, I had a fair bit of energy this weekend, used it up and don't have a lot to show for it development wise.

But On The Plus Side

There's always days like this I suppose and I did learn some a few awesome things. Had a brief look at various bits of JS middleware out there. This thing? it's an excellent thing! I want to eventually have some live shader editing and this will be perfect for it. KickJS already does that kind of thing and it works really well.

As the JS code I'm writing gets beyond a few hundred lines it's apparent some structure and organisation that the language doesn't naturally support. The way different bits of Javascript can know about each other is by polluting the global namespace with a a load of mess. There's a few formalised approaches to packaging things up which I found after playing about with my own solution. It was interesting reading about these, I'll likely go for CommonJS or RequireJS not sure which yet. In turn lead me to an introduction of the upcoming Harmony and tangentially about the imminent Coffeescript 2 release and its exciting Kickstarter journey.

I learnt a bit more about nice development environments for Coffescript and Javascript. After experimenting with have Guard auto compile things for me last week I'm now using Cake (yes, every language seems to have their own build environment, there was make, Ruby's rake so there's also cake of course for Coffeescript) after wholesale ripping off the really pleasant setup in this lovely demo app of Coffee Physics. It's so cool all of this stuff is easily available as source and so easy to learn from. So much great stuff out, just found a port of bullet to JS!

Actually when you write it down, on top of the cross domain nonsense I learnt a lot of good stuff. Not so bad then.

I Learnt I Don't Like Old Naked Men Commenting On The Fancyness of My Goggles

Went for a bit of swimming with Suzey and the boy at the local gym. Which was ace. Charlie's really come along and close to swimming completely solo. Right now he's just got a float to help him along but he's kicking away in the water and putting his head under with a boat load more confidence and verve that the last time we went.

In the changing room after a naked old man looked at my googles and said they were 'fancy'. And I really didn't like it.

References

Strava ride 1 Strava ride 2 Strava ride 3 Up Grange Road leaderboard JSONP Cross Domain AJAX Module Approaches Common Js Require JS Harmony Cake make rake Coffeescript 2 Coffee Physics KickJS Ace Code Editor Coffeescript2 Kickstater JSBullet CORS Chrome CORS Lion Apache REST

Enjoyablility

Posted on

Enjoyablility

It's important to me that I enjoy working on my home dev project. If you're doing stuff for fun well it should be fun. I know that sounds kind of obvious but it's something I missed in the past at times and kind of have a good handle on now. FIrst of all you have to know what you like, right now for me (and I am pretty phase) I really enjoy:

  • Quick turn around of development
  • Learning new stuff
  • Not having to repetitious work

Last night wasn't really like that, it took bit of slog but I think I have my dev env set up nicely now to deliver on fun factor a bit more :)

Javascript / Coffeescript

I've been enjoying playing with Javascript the last week or so. I wrote a little server in node.js and have now moved onto writing an editor for my game in it. And its been a lot of fun. Very fast to develop in, lots of great resources on the web to help you learn and for a dynamic language it's pretty nippy too.

The immediacy though, that's what I like best. Save your file, flip to the browser, refresh and your code is running. I love that, so quick and no horrendous compile / link times. There's even a debugger. Well there's lots of them but the one in Safari has given me break points and variable inspection. That's nice for a dynamic language.

There are some niggles though. Syntactically it's a bit shit. Being able to inline embed anonymous functions often leads to a lot of indentation. You can get stuff like this pretty quickly

$('#tilda').tilda(function(_line, _console) {  
  quakeConsole(_line).success( function(_response) {
     _response.response.forEach( function(str) {
      _console.echo(str);
    });
  });
});
Ooof, look at that nasty trailing brace and bracket storm! The code ties the input from a [JQuery][jquery] based quake style [console in the browser][jqueryterminal] to my game back end (yeah I know, how cool is that?). It uses jQuery to get the node with the console in, sets a callback for any input. Once it gets input quakeConsole sends it to the game and also talks a callback for any response and that callback sends it back to console object. You get a lot of that sort of ping ponging in this sort of work. It really hurts the eyes. It's not fun to type and maintain either. I kept getting it wrong. Some sort of syntactic sugaring for Javascript that got rid of that would be nice wouldn't it? Turns out I'm not the only moany, fussy idiot in the world who's brace averse which is probably why [Coffeescript][coffeescript] exists. So the above now looks like this:
$('#tilda').tilda ( _line, _console ) ->  
    quakeConsole(_line).success (_response ) ->
        _response.response.forEach (str) ->
            _console.echo str
A lot easier on the eyes, quicker to type and easier to maintain. Scope is defined by indention rather than bracing and have never really done Python this is my first time for that sort of thing. A bit intimidating but I'm used to that now. Some help in the [editor][sublime] has made that process a lot easier. [SublimeLinter][sublimelinter] has been really handy which after a bit of fiddling has real time linting support for a lot of languages. Very handy seeing schoolboy errors fussily being pointed out as I type :) There's a bunch of other things Coffeescript brings to the party. As well as Python Ruby seems to have been a big influence too which has made me feel nicely at home. It also makes doing anything a bit class like a lot less fiddly and prone to error. JS can do class based OO but it means a lot of pointless typing. Not any more. There's a few issues, the code you debug is different from the code you right and being new to all of this means I'm debugging quite a bit. That's not been too bad though as the mapping is fairly light and surprisingly easy to map in your head. It's made writing JS more fun for me and I also go to learn something new so result. It does mean a compile stage though and I didn't want to lose any of the immediacy I'd been enjoying so much. # Compiling! Yuck So I wanted to preserve my tight little dev cycle of save in the editor, tab to the browser and immediately try things out. My home project has a nice build environment based around the excellent [Rake][rake] where any data that needs transforming to another format for use in the game is processed there. It only builds files that have changed is pretty quick but even adding that one extra step of invoking a build before trying out my new code rankled a bit. Turns out something called [Guard][guard] is a great solution for this. It's written in Ruby and easily installed as a Gem. Basically it'll sit in the background watching your files and as soon as any of them changes will do some background task for you. Best of all it's really popular and people have written a shed load of different plug ins that support all manner of different actions. And there's one for Rake. With Guard and the rake plug in installed all it needed was a Guardfile that listing out what files to watch and some options for rake to do its magic:
# A sample Guardfile

guard 'rake', :task =>; 'html' do  
  watch(%r{^media/html/.*$})
end  

Simples. A regex saying look at the html src dir and if anything changes? Builld the 'html' target with Rake. It works really really well. I have an immediacy of development that's an absolute joy while being able to use a pre-processed version of Javascript that I'm finding a lot less laborious to write. I've used the same setup to let me edit my CSS in sass as well.

Summing Up

It was a bit sloggy last night but it all feels really good now I have this all nicely in place. Something that's been great using technologies that have come from the web is there's a wealth of well maintained and incredibly useful tools.

Generally if there's something that niggles or your dev cycle seems a bit tortuous then someone has had a crack at solving that problem already. As with most things you need to put a bit of back into researching the issue and finding the right way forward. Chances are there's actually 10 solutions and half of them are shit but put in the effort, embrace the fear of the new and you'll likely find the solution you're looking for.

References

jquery jqueryterminal coffeescript sublimelinter sublime guard rake guardrake sass