Art History of Games

A short note to draw the attention of the two of you to this event that pal Ian Bogost and related/sundry other chums are putting on: Art History of Games to be held February 4th, 5th and 6th right there in Atlanta. Sounds delightful — wish I could make such things as this. I’m fond of these sorts of thoughtful considerations and probing lenses upon things that are often mistakenly trivialized — Art History and Games. Fantastic. Seems like they’ve commissioned a few games, including one involving enormous game pieces and what sounds like a cunning form of bribery.

Check out the schedule and weep with me in sorrow for not being able to attend..

Continue reading Art History of Games

Locative Play

Ian Bogost‘s and his Persuasive Games operation have introduced an iPhone game called JetSet
— a curious little gem that situates specific locations as the enforced zone for game play.

Very interesting play mechanic — a location-based game that you can basically only play when you’re at any one of a huge list of airports in the world. And, your score (if it’s good enough..) goes up on that airport’s leader board. The only way to play, say — Madrid Barajas International Airport is to go to Madrid Barajas International Airport. You have to physically be at the airport to play and get on that airport’s leader board, get that airport’s “souvenirs” (this game’s equivalent of blue gems), and so forth.

Oh, the game — okay, you’re a security screener dude screening passengers, and the "prohibited" list changes so you’re constantly having to figure out what to remove from the traveler, from the mundane — shoes? hat? water bottles? coffee? to the obscure — bacon? rocks? snakes? robots? pudding cups? hummus? There should be a way to put leader boards up along on my Dopplr page and Dopplr personal annual report!

It’s simple and an exciting play mechanic that’s intimates at the near future of all kinds of interactive experiences as the digital continues to leak out into the real world. Nicely done.
Continue reading Locative Play

Autonomous Game Controllers


Continuing on my strange pursuit of designing weird interfaces that disrupt conventional game interaction rituals, I put together a bit more of my “PSX” project. You probably don’t recall, but this is the project where I’ve created a little “dongle” that can fool a PS2 (or Playstation 3, as it turns out..) into thinking that the dongle is actually a Playstation controller. You can also hook up a real Playstation controller to it and it can “read” the controller buttons and joystick and pass that data through, or do whatever you want with it. It appears as an TWI/I2C device to anything that talks to TWI/I2C my favorite TWI/I2C talking thing — the Arduino.

You can see here that the dongle — the white box with those annoying, huge Playstation connectors on either end, one male, one female — has four wires going into it. Those are for power, ground and the TWI signals, SDA and SCL. The power and ground are necessary because the Arduino (at least this one here) and the dongle run at different voltages. The Arduino is a 5V device, while the dongle is a 3.3V device, so there’s some level shifting going on inside there.



So, that’s all fine. It works, etc. But then the question that’s actually more intriguing than building the thing..what do you do with it?

Well, I have some ideas, including hooking up a bike to it and attaching a giant human form kick-boxing dummy to play old school fighting games. For some early fun and nonsense, I connected a Wii Nunchuck up to it to control Playstation games with Wii-y gestures and stuff. Which could be cool if I find the right game, or spend a little more time thinking things through rather than just writing and revising microcontroller firmware to make a TWI controllable device, and doing Catia to CAD-up and print plastic enclosures.

But, in the meantime, I decided to do an absolutely crucial bit of game science. Something that I am entirely sure is mulled over constantly, but never properly investigated. The question is best stated thusly: how long would it take the Little Prince to roll up an entire room based on a random path algorithm?

How long indeed. Well, short answer is a long time. I let it go for about 70 minutes, after which he had just 10 things to go in a particularly tricky location that required rolling across a narrow bridge. At this point, I took over..but check out the 8x speed video anyway!

Katamari Autonomy from Julian Bleecker on Vimeo

I wrote a quick little Arduino code for my PSX dongle to have the Little Prince roll forward and then, after a few moments, make a random directional change. (Or stop, take a load off and look around the world.)

This was all done by sending TWI commands to the appropriate registers in my little DIY Playstation 2 controller emulator. All the buttons and the joysticks can be emulated as to their state through a series of write-to registers. If there’s a controller stuck in the other side of the dongle, there are a complement of read-from registers so you can see if any of the buttons are pressed and how much the joysticks are displaced. (I set up an “escape” buttons sequence — pressing both L2 and R2 — to bring control back to the normal joystick so I could navigate menus or take control over, which I had to do after I realized, with four items left, the completion of cleaning the room would probably not happen before the universe ran out of steam.)

Here’s the Arduino code. Pretty straight forward Wire / TWI library stuff.

#include "nunchuck_funcs.h"

#define is_bit_clear(a, n) (0 == (a & (1<<n)))
#define is_bit_set(a, n)  (1 == (a & (1<<n))

#define is_button_pressed(a, button) is_bit_clear(a, button)
#define is_button_released(a, button) is_bit_set(a, button)

#define BTN_SELECT 0
#define BTN_L3 1
#define BTN_R3 2
#define BTN_START 3
#define BTN_UP 4
#define BTN_RIGHT 5
#define BTN_DOWN 6
#define BTN_LEFT 7
#define BTN_L2 8
#define BTN_R2 9
#define BTN_L1 10
#define BTN_R1 11
#define BTN_TRIANGLE 12
#define BTN_CIRCLE 13
#define BTN_X 14
#define BTN_SQUARE 15

// register addresses in the PSX I2C device
#define W_BUTTONS_0 0x00 // (, ^, start, R3, L3, select
#define W_BUTTONS_1 0x01 // (square, x, o, triangle, R1, L1, R2, L2)
#define W_RIGHT_X 0x02
#define W_RIGHT_Y 0x03
#define W_LEFT_X 0x04
#define W_LEFT_Y 0x05

#define R_BUTTONS_0 0x12 // (, ^, start, R3, L3, select)
#define R_BUTTONS_1 0x13 // (square, x, o, triangle, R1, L1, R2, L2)
#define R_RIGHT_X 0x14 // a value from 0x00 - 0xFF
#define R_RIGHT_Y 0x15 // a value from 0x00 - 0xFF
#define R_LEFT_X 0x16
#define R_LEFT_Y 0x17

// I2C address of the PSX dongle
int psx_dongle_addr = 0x72;
int j;
void setup()
  Wire.begin(); // join i2c bus (address optional for master)

// this is the control register. setting it to 1 means that
// we have to tell the PSX device what data to send to the
// Playstation2. Setting it to 0 means that it simply passes
// through the data from the controller to the PS2. We can
// read the state of the contorller at any time.

writeToAddress(psx_dongle_addr, 0x24, 1);

// we'll use count to figure out when to change direction
int count = 0;
int buttons;

// mode is used to indicate either "pass thru" where we can use the
// actually real human controller to control the PS2, or to generate
// data via the PSX dongle.
// pressing both L2 and R2 simultaneously toggles the mode
int mode = 1;
byte randomNumber;

void loop()
  byte val;
  //Serial.println(count, DEC);
 // 0x70 shows up as either ID $20 or ID $E0 on Propeller

  BTN_SELECT = $0001
  BTN_L3 = $0002
  BTN_R3 = $0004
  BTN_START = $0008
  BTN_UP = $0010
  BTN_RIGHT = $0020
  BTN_DOWN = $0040
  BTN_LEFT = $0080
  BTN_L2 = $0100
  BTN_R2 = $0200
  BTN_L1 = $0400
  BTN_R1 = $0800
  BTN_TRIANGLE = $1000
  BTN_CIRCLE = $2000
  BTN_X = $4000
  BTN_SQUARE = $8000

// 0x00 write to BUTTONS_0, 0x12 read from BUTTONS_0
// 0x01 write to BUTTONS_1, 0x13 read from BUTTONS_1
// 0x02 write to RIGHT_X, 0x14 read from RIGHT_X
// 0x03 write to RIGHT_Y, 0x15 read from RIGHT_Y
// 0x04 write to LEFT_X, 0x16 read from LEFT_X
// 0x05 write to LEFT_Y, 0x17 read from LEFT_Y
//Serial.println(getButtons(), HEX);
//int buttons = getButtons();
//Serial.print(buttons, BIN);
//  passThruButtons();

if(count > 512) {
  count = 0;
//Serial.println(mode, HEX);

// get the buttons
buttons = getButtons();

// mode is used to indicate either "pass thru" where we can use the
// actually real human controller to control the PS2, or to generate
// data via the PSX dongle.
// pressing both L2 and R2 simultaneously toggles the mode
  if(mode == 1 &&
     is_button_pressed(buttons, BTN_L2) && is_button_pressed(buttons, BTN_R2)) {
    mode = 0;
  } else
  if(mode == 0 &&
     is_button_pressed(buttons, BTN_L2) && is_button_pressed(buttons, BTN_R2)) {
     mode = 1;
 if(mode == 1) {
 if(mode == 0)

  writeToAddress(psx_dongle_addr, W_LEFT_Y, 0x00);
  writeToAddress(psx_dongle_addr, W_RIGHT_Y, 0x00);

  if(count == 512) {
    count = 0;

    randomNumber = random(1,5);
        Serial.print("FLIP! ");
        Serial.println(randomNumber, HEX);
    switch(randomNumber) {
      case 1: case 2: case 6:
        writeToAddress(psx_dongle_addr, W_LEFT_Y, 0x00);
        writeToAddress(psx_dongle_addr, W_RIGHT_Y, 0xAF);
      case 3: case 4: case 5:
        writeToAddress(psx_dongle_addr, W_LEFT_Y, 0xAF);
        writeToAddress(psx_dongle_addr, W_RIGHT_Y, 0x00);

writeToAddress(psx_dongle_addr, W_LEFT_X, (float)map(nunchuck_accelx(), (float)0x48, (float)0xB0,
                (float)0x00, (float)0xFF));
writeToAddress(pssx_dongle_addr, W_LEFT_Y, (float)map(nunchuck_accely(), (float)0x48, (float)0xB0,
                (float)0x00, (float)0xFF));

writeToAddress(psx_dongle_addr, W_RIGHT_Y, (float)map(nunchuck_joyy(), (float)0x1D, (float)0xDF,
                (float)0x00, (float)0xFF));
writeToAddress(psx_dongle_addr, W_RIGHT_X, (float)map(nunchuck_joyx(), (float)0x1D, (float)0xDF,
                (float)0x00, (float)0xFF));


int getButtons()
int result = 0x00;

result = readFromAddress(psx_dongle_addr, 0x13, 1);
//  Serial.print(result, HEX); Serial.print(" ");
result <> 8)); // MSB
  Wire.send((int)(addr & 0xFF)); // LSB

byte readFromAddress(int twi_addr, int addr, int bytes_to_read)
  byte rdata;
  Wire.send((int)(addr >> 8)); // MSB
  Wire.send((int)(addr & 0xFF)); // LSB
  while (Wire.available()) rdata = Wire.receive();
  return rdata;

Continue reading Autonomous Game Controllers

Battleship:GoogleEarth (a 1st Life/2nd Life mashup)

I’ve started working on a bit of summer laboratory experiment to see how Google Earth could become a platform for realtime mobile gaming. (Follow the link on the Flickr photo page to the URL you can load in your Google Earth client to see the game board in its current state.)

With Google Earth open enough to place objects dynamically using the tag, a bit of SketchUp modeling and borrowing an enormous battleship model that construction dude uploaded to the SketchUp/Google 3D Warehouse, I started plugging away at a simple game mechanic based on the old Milton Bradley Battleship game.

Battleship, for those of you who never played, has a simple mechanic — two players set up their navy ships on a peg board, hidden from the other guy. You take turns plugging a peg into your side of the board, with each peg hole designated by a letter/number coordinate grid. When you plug a peg in, you say where you put it — E4! If your opponent has a ship in that coordinate (or part of one, actually), they say, sorrowfully, “Hit!” and you register that peg hole with a color to indicate a hit. If not, you just put in a neutral peg to remind you that you already tried that spot. The game continues into one player has sunk all the other guys ships.

The mechanic I’m experimenting with is simpler. One person places their ships using Google Earth and the other person goes out in the normal world with a mobile phone, a GPS connected to the mobile phone. The phone has a small Python script on it that reads the GPS and sends the data to the game engine, which then updates the Google Earth KML model showing the current state of the game grid. When the player who’s trying to sink the ships wants to try for a hit, they call into the game engine and say “drop”. The game reads back the coordinates at which the “peg” was dropped and shortly thereafter, the other player will see the peg appear at the coordinate it was dropped. If the peg hits one of the ships, it’s a Hit, otherwise it’s a miss.


Next Steps
As I continue developing the engine, I’ll probably have the game engine let you know when you call in to do the “drop” whether it was a hit or not, or the opposing player can text or call to indicate the same.I want to put in a “ping” command for the call-in battleship control center to help whoever’s wandering around in the world navigate a bit. (Although the game is only really practical if you limit the boundaries over which it can be played.)

I need a lighter weight battleship — the current SketchUp model is too large, in data size terms and takes too long to initially load (although, it only needs to be loaded once.)

* Experiment with “1st Life” action reflected in “2nd Life” worlds (verso of the folly Ender suffered in Orson Scott Card’s simply fascinating Ender’s Game
* Learn KML
* Learn SketchUp
* Learn Python for S60
* Make a mobile/pervasive game in which one has to move around in order to play Equipment
* Google Earth client
* Apache+Tomcat+MySQL (Java and JSP on the server-side computer)
* Nokia N70 and a little Python app to connect to the Bluetooth GPS and upload the data to the server
* Voice Application (for the battleship control center to drop/ping)
* SketchUp Time Committed
* About 2 days learning stuff, and 1/2 a day programming the computer to make it do things.Why do I blog this?To keep track of and share the near future laboratory experiments I’m doing this summer.

Technorati Tags: , , , ,

Why Games Matter?: Susana's Thesis Project

Susana Ruiz’s MFA thesis project – one of the projects from the 2nd class of thesis graduates to complete their MFA’s from the interactive media division’s, is an embodied explication of the intractable, miserable, life diminishing products of what happens when difference – political, ethnic, religious, skin color – is seen as a bad thing.

The hope here is that the moment of stepping into an experience wherein one is forced to experience that intractability, or to play the role of those who are engaged in the Darfur catastrophe, will bubble the crisis up at the local, individual level, so that it’s more than a news blip, at least here in the US. If you can “play” through the linkages of action and reaction, or live the life of a refugee, empathy and response may arise. The jury is still out on that point, but the motivation is decidedly spot-on.

If digital networks hold any promise for species evolution, I would hope it would be a hack to patch the bad code that makes us think that life can ever be cheap and that things that are different should be annihilated.

Technorati Tags: