Visualising Elastic Versailles

Naked on Pluto is a text adventure game, it’s world is comprised of descriptions, populated by bits and pieces of text from your facebook profile while the space is largely left to your interpretation and imagination. There are some ways of visualising it though.

We have been archiving versions of the game world every hour for the last year in a git repo. In these files the only facebook profile information we have stored are names, which are considered public information in the agreement with facebook. We are interested in using this data to see how we built the game and potentially how people have been playing it (although one snapshot per hour isn’t really enough for that).

I started out experimenting with GraphViz and Gephi but I ended up switching to fluxus and adapting the exquisite code visualiser to read through thousands of dot files to make a dynamically changing graph. This animation shows the process from us building the world to the introduction of the first playtesters over the course of a few months:

Golden Medallions and in-game programming

Once the low level code for a Naked on Pluto bot is written in Scheme, it’s added by the game using secret commands which program the game inside itself, while it’s running. This means the game can be changed while people are playing it – which makes it much easier to add new things without worrying about the disruption caused by restarting the server. We can also work on the game collaboratively, at the same time this way.


(Programming a spybot with it’s behaviour)

Eventually the plan is to be able to program the bots fully within the game client – this is still a long term goal, but there are of course some fairly complex security problems with this idea.


(dressing a AudienceBot with another object)

Not all players have the ability to use these secret commands right now, in order to access them a player has to be carrying a special object (also known as a “Golden Medallion”). This allows you access to all areas of the game, including an “administration room” and various other secret powers.

Naked on Pluto goes to São Paulo

(Originally posted here)

Naked on Pluto has been selected for FILE festival São Paulo 2011 which, in addition to some funding from the Finnish Promotion Centre for Audiovisual Culture (AVEK) allows us to develop the game for an art gallery installation setting.

I’ve been reacquainting myself with bot programming, and trying some experimental and dangerous things with conversations.

As an example, here is a bot that simply repeats things it overhears – if you throw a couple of these in a room and start them going by saying something – chaos follows as they start to repeat you and then each other’s messages:

(define (talkative-action entity graph node)
  (if (and
       (< (random 5) 3) ; do this 3 out of 5 times
       (< (length (pluto-node-old-messages node)) 10)) ; safety valve
      (foldl                ; loop over all the messages
       (lambda (msg node)
         ; get the name of the sender
         (let ((name (entity-name
                      (pluto-node-entity-get
                       node (pluto-message-from msg)))))
           (pluto-say-to-random ; make a new message 
            node                ; to a random entity
            entity
            (string-append ; build the message
             (choose
              (list
               (string-append name " just said: ")
               (string-append "I just heard " name " saying: ")))
             (pluto-message-txt msg))))) ; repeat the message
       node
       (pluto-node-old-messages node))
      node))

Reading/writing clojure

Revisiting my clojure frustrations, I was having problems getting things saved out to be recreated properly when loaded back in. This is something you take for granted perhaps, as a scheme programmer – but by restricting the set of containers I use, I’ve managed to get the right behavior from clojure.

user=> (def a (hash-map :number 43 :list () :string "hello"))
#'user/a
user=> (spit "test.txt" a)
nil
user=> (slurp "test.txt")
"{:string \"hello\", :list (), :number 43}"
user=> (read-string (slurp "test.txt"))
{:string "hello", :list (), :number 43}
user=> (:number (read-string (slurp "test.txt")))
43

As originally suggested by Sam – if I save a hash-map, I get one back when I parse the text – same for lists or normal data. This isn’t the case for struct-maps or records which I tried before. I can also do versioning with hash-maps, where one of the fields is the version number, and structures can change without breaking file compatibility. When you load an old version, you can automatically detect this and convert it on the fly by adding default values for new data, or removing old stuff.

This is essential for production work, especially with an online game – as you need to keep file formats and data structures flexible while doing the upgrades in an quick automated way to match the code which is running.

Here is a section of the Naked on Pluto code (in scheme, but the process will be similar in clojure for Germination X) it gives you an idea of the kind of changes we made throughout the development process:

(let* ((f (open-input-file filename))
         (l (read f)) ; read the file
         (v (car l)) ; first item is the version
         (g (cadr l))) ; second item is the graph
    ; the version allows us to preprocess the graph to fix
    ; things which have changed. do this here.
    (let ((g (if (< v 1) (add-vocab-to-nodes g) g)))
      (let ((g (if (< v 2) (add-message-types g) g)))
        (let ((g (if (< v 3) (add-bot-timers g) g)))
          (let ((g (if (< v 4) (add-old-messages-to-nodes g) g)))
            (let ((g (if (< v 5) (remove-dir-from-edges g) g)))
              (let ((g (if (< v 6) (add-hatface g) g)))
                (let ((g (if (< v 7) (add-votes g) g)))
                    ; g is now up to date, whatever the version was we loaded
                  ))))))))

Naked on Pluto vs Mozilla

We had some trouble following a submission of Naked on Pluto to the Mozilla Game On competition. Aymeric describes the full story here, and it looks like a case of satire mistaken as the real thing, but it’s just a shame that we needed to go public with a blog post before we received any replies from Mozilla to our numerous emails.

FaceBook

I also wanted to write something about FaceBook as so far we have had zero problems with them over Naked on Pluto, a FaceBook game designed to confront the concept of online social networks.

This could be for two reasons, firstly FaceBook could be a place that welcomes strange and awkward software art and games even if they are a bit critical and have an odd sense of humour (although evidently they can’t be as confrontational as the web2.0 suicide machine).

The other, much more likely possibility is that with the sheer number of applications and games they haven’t even noticed we exist – which in itself makes the space, if not free, slightly “loose”.

Germination X – the next steps

Lina and I have begun work on the next iteration of Germination X which will be more playable than the demos we’ve been working on up till now. We are developing the look and building some of the underlying technology we need for the Pixelache event in March, lots more of this to come, but I’ve begun using the Lirec wiki to start to organise and document things.

The first part I’m looking at is getting characters drawn on paper into a multiplayer game instantly using various computer vision algorithms. This will be used in of one of our workshops at Pixelache, but we also want to prototype characters quickly and easily ourselves. Something which was lacking with the first groworld games, and I tried to address during Naked on Pluto was the effectiveness of making games shapeable by everyone involved in a project. Programming time and effort spent on this kind of accessibility seems to buy you a lot more time throughout a project even if it’s not actually seen or used by players in the end.

About @NopCleanerBot


In our continuing efforts to embrace all “social media”, one of the bots in Naked on Pluto has started a twitter account. Could this be the first character in a FaceBook game to tweet?

The tweeting bot’s actions cause it to wander the world and sporadically report on it’s progress, who is in the same location (bots, players or objects) and snippets of conversations it hears, from players or bots talking to each other. I’m using tweepy, a python twitter library, so I had to do a bit of a cheap hack for the racket->python process communication using the filesystem. The python daemon simply waits for a file to be created by the main bot AI thread and sends the contents of it to the twitter stream. In order to do the authentication with OAuth I needed to set up a Twitter application to get a pair of keys to sign the single user the app will have.

Here is the code for the tweepy daemon:

#!/usr/bin/env python
import tweepy
import os.path
import time

auth = tweepy.OAuthHandler("your consumer key", "your consumer secret")
print(auth.get_authorization_url()) # you need to visit this site, logged in as the twitter user
verifier = raw_input('Verifier:') # then input the verifier code here before continuing
auth.get_access_token(verifier)
api = tweepy.API(auth) # this api allows us to read or write from the user's account

while True:
    if os.path.isfile("msg"): # look for a file called "msg"
        f = open("msg", "r")
        api.update_status(f.read()) # dump the contents into the twitter stream
        f.close()
        os.remove("msg")
    time.sleep(10)

Piksel 2010 (un)stable

Piksel 2010 (un)stable was the 8th piksel, and the second time I’ve been lucky enough to participate. I was there to present Naked on Pluto and general livecoding duties.

I didn’t have as much time or energy to get involved with the other things going on as I’d have liked, so this is mainly a report on my activities. I did see a super talk by Audun Eriksen about the visual programming language scratch and it’s use for teaching kids to make games – very inspiring stuff.

Scratch was where I started with the idea for scheme bricks, so it was great that the next day Alex and I had the functional livecoding workshop, where people could get their hands dirty with some of our live coding performance ideas.

This was followed in the evening by a slub performance, where we got a little carried away by the responsive audience and the rather nice sound system. It’s always good to do performances with stuff you’ve done a workshop on earlier as the participants can put it in context (and tell other people what’s going on!). The image is a link to a video of the performance on giss.tv.

The next day was a switch to Naked on Pluto with Aymeric and a presentation where we discussed clouds, problems with social media, farmville and the intricacies of the facebook graph api.


(pictures thanks to Régine Debatty)

It was great to get questions from people who have tried playing the game before seeing our talk. Hopefully this can be the case as we discuss the project more widely.

NoP: What do we do with your data?

Now we have people playing the game, it’s a good time to explain what happens with your facebook data in more detail. Given the nature of the project it’s important for us to make this clear. Here is a diagram I’ve prepared for the presentation we are giving at Piksel at the weeked:

On the left is the naked on pluto server, the machine in the middle is your computer running the client in the browser, and on the right is facebook’s server.

The first thing to notice is that the NoP server doesn’t ever communicate with facebook directly. The other thing to notice is that we never write anything to your facebook account.

The client only passes your name and facebook ID number to the server, where it gets incorporated into the game world. This information is considered public by facebook so it’s a usual thing to do. We use it to pass back to other players, so they can see who else is playing. The facebook ID is used to get the right icon for the players, but we also use it to find the player’s in-game entity when they log in (they are unique – so two people with the same name can play).

All the other information you can see – your friends and their data, is displayed by your client based on the data read by your machine from facebook. None of this gets passed to our server or other players.

For more information on how this all relates to facebook privacy policy, see the plutonian clothing stragegy.

Originally blogged on the NoP site here.