Betablocker DS code patterns (part 1)

Some useful Betablocker DS code patterns as used in common live coding situations.

Firstly, when carrying out a sound check before a live performance it’s important to keep some kinds of sound engineers happy generating as many different sounds as you can so they can fiddle around with stuff – of course remember to turn everything up to 8 when asked to make the loudest sound you can in order to leave some overhead to blow the PA.

This is a betablocker program which will play all the sounds in a sound bank at all frequencies. Add more concurrent threads to make it more interesting. Values interpreted as pointers are visualised as arrows:


(the instruction set description can be found here)

In betablocker the beat is always locked to the instruction cycle rate, so fast changing sounds are a matter of optimisation. One of the most common ways around this (and a good way to start things off in a gig) is to use one fast loop program for playing sounds while another slower program modifies the first by overwriting bits of it.

More to follow in this series. See also evolved betablocker genetic programs.

MapReducing plants and players

I haven’t been doing much work on Germination X lately, but we are now up to 101 players, and 766 plants alive at time of writing. Of the 101 players 60 of them are on the first “level” of planting ground cover plants, 24 are at level 2 planting shrubs and 4 have made it to tree planting. 13 have completed the tree planting level and are free to plant what they like.

The mongodb database the game now uses allows you to connect via a console and pull out some statistics using bits of JavaScript with a feature called mapReduce – an idea based on the lisp functions map and reduce (or fold in Scheme) and made popular by Google with it’s search algorithm.

Each tile in the world contains a list of entities (each plants is an entity), so we can “map” over the tiles, creating a new list of plant counts. Then we “reduce” over the counts with another function to find the total. This approach allows the database to do the operations in parallel, and control the amount of memory required – which would be necessary if we had a fair few more players :)

db.tiles.mapReduce(
    // map fn 
    function() { 
        emit("total",{count:this.entities.length}); 
    },
    // reduce fn
    function(key, values) { 
        var result={count:0}; 
        values.forEach(function(v) { 
            result.count+=v.count; 
        }); 
        return result;
    }, 
    // tell it to spit out the result in the console
    {out: {inline:1}}
)

This more complex example tells us the distribution of players by how far they have got:

db.players.mapReduce( 
    // map fn
    function() { 
        if (this.layer==0) emit("ground cover",{count:1}); 
        if (this.layer==1) emit("shrub",{count:1}); 
        if (this.layer==2) emit("tree",{count:1}); 
        if (this.layer==3) emit("complete",{count:1}); 
    },
    // reduce fn
    function(key, values) { 
        var result={count:0}; 
        values.forEach(function(v) { 
            result.count+=v.count; 
        }); 
        return result;}, 
    {out: {inline:1}}
)