Book Review – Marooned In Realtime

Marooned In Realtime By Vernor Vinge

Sometime in the near future humanity invents the “bobble”, a device that generates a perfect stasis field, time does not pass inside at all. Totally impervious, Bobbies can be used as weapons, shielding, long-term storage, or as a one-way time machine into the future. Far into the future in an unpopulated Earth, a small collection of people who (for various reasons) have bobbled for immense amounts of time decide to collectively bobble again for 50 million years.

But one person is left behind, forcibly unable to bobble, effectively murdered as she lives out her natural life while every other living human is in stasis. 50 million years later, the others immediately realise that they have a murderer in their midst. Can old-school detective Wil Brierson crack the case?

Marooned in Realtime attempts that most tricky of feats – the hard science fiction murder mystery, and it comes pretty close to succeeding. The rules of the game (how the bobbles work, the various motivations and personal histories of the suspects, etc) are well laid out and the book never feels dull, almost an action thriller rather than a detective story.

I completely missed the clues that pointed to the murder, the solution hinges on a rather subtle point. But by that stage it didn’t matter because the story has widened in unexpected ways as the full implications of what the characters have discovered about the world and each other becomes clearer. Mystery, action, spaceships, aquatic monkeys, evolved dogs, what more do you people want?

Highly recommended if you like this sort of thing.

Brandy in a Rifle Bottle

They say you can’t judge a book by its cover, but I have always thought that you can judge a drink by its bottle. The fancier the bottle the more wretched the drink seems to be a good rule to live by.

I don’t know anything about brandy and it might be fantastic, but I am going to avoid this one:

(sorry about the picture, it is not actually that colour)

Google+ Social Media Features

Blog writers want feedback. For ages now I have been running a plugin on this blog that allows readers to quickly post things I have written to Twitter, Reddit, Facebook, etc in the hope that some of my wittier and more insightful musings might be widely distributed. The icons were there for years and, as far as I can tell, the icons were clicked exactly none times. None.

So I have removed that plugin and am trying something else.

Google+ is Google’s attempt at social media (previously) and I am liking a lot of what they are doing. It is sort of like a mixture of Twitter and Facebook, you can follow people without them reciprocating and anything you post can be shared with only a subset of people. +1 is Google’s equivalent of Facebook’s Like button.

If you are logged into G+ you can click on the +1 button to show you approve of the content and want to see more like it. You can go back through the archives and +1 as many articles as you want – go ahead, I’ll wait.

In addition, I have added my Google Plus feed to the sidebar on the right. I am not sure if I will keep this, I post very few updates, but we will see. I quite like having my long form blog posts and my short for G+ updates visible in one place.

Game Review – GoatUp

Jeff Minter, with his alter-ego/software company, Llamasoft, has been creating ungulate related games for as long as I can remember. On the Amiga games like Llamatron and Attack of the Mutant Camels were ridiculously over the top arcade perfection, with retro (even then) graphics, lofi sound, and pixel perfect controls. GoatUp is a fine addition to Minter’s metaphorical stable (as opposed to the real stable he probably owns.)

20110927-002135.jpg

In GoatUp, you control an incredibly nimble and fertile nanny goat who must jump from platform to platform to climb an impossibly tall tower into the sky, picking up bonus items and powerups along the way. Every so often you will meet a billy goat, kissing billy goats gives you more points and also causes you to get pregnant. After a while you instantaneously give birth to a kid that follows you around, if you survive long enough you can get a long chain of offspring trailing behind you. This is useful for defeating enemies, but disturbing if you stop to think about it. Luckily, there is no time to think – you must always be climbing and the game is hard, hard, hard.

The old games lived by their control schemes and GoatUp provides several. The only one that really works well is moving via tilting left or right, and jumping with a touch. You can tell that some thought has been put into the controls, and they work much better than the tilt controls in other games. Speaking of old games, GoatUp’s graphics are deliberately designed to look like various games from the 80′s, some pretty obscure. Part of the fun is trying to remember the particular game that is being invoked.

Recommended if you like this sort of thing.

Arduino Powered Tachistoscope

About fifteen hundred years ago I wrote WordApp, a Java applet tachistoscope that reads a text file from either the local filesystem or the Internet and displays it one word at a time. The idea is that it trains your brain to recognise words quickly, increasing your reading speed. I thought it was a little silly, but according to me web host’s logs WordUp still sees a bit of use even though I haven’t touched it for years.

I was hunting around for something to do with my Arduino while I waited for some other parts to arrive when I had the idea of making a physical tachistoscope that reads its data off an SD card and displays the text using an LCD display I have lying around.

The SD card contains the text to be shown. One of the potentiometers is used to vary the contrast on the LCD. The other is sampled by the CPU and converted into a delay to vary the speed at which the words appear.

Unfortunately the refresh rate of the LCD is very poor, so the text becomes almost impossible to read at even modest speeds. A better display might help, but I am not going to spend any more time and money on something so simple. Fortunately, the other parts I ordered arrived yesterday so I have other things to play with.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
An Arduino implementation of a Tachistoscope.
This uses both the LiquidCrystal and SD libraries (and repective devices). The 
words are read one at a time from a file on the SD card. A simple variable resistor
is used to control the speed.
In practice this does not work terribly well since the LCD display has a poor
refresh rate.
 
Pins: 
The LCD is connected via pins 2-8. Technically I could get away without the RW pin.
The SD card reader is connected via pins 10-13 (the standard SPI pins)
The variable resistor is connected via analog A0
 
Author: Andrew Stephens http://sandfly.net.nz/
*/
 
#include <LiquidCrystal.h>
#include <SD.h>
 
LiquidCrystal lcd(8, 7, 6, 5, 4, 3, 2);
File file;
 
void setup()
{
  lcd.begin( 16, 2 );
  lcd.clear();
  lcd.setCursor(0, 0);
 
  pinMode(10, OUTPUT);  // required if I ever change the CS pin from 10
  pinMode(A0, INPUT);
 
  SD.begin(10);
  file = SD.open("test.txt");
}
 
// Skip over whitespace, positions the file position at the start of the next
// word
bool findNextWord( File& file )
{
  int r;
  while ((r = file.peek()) != -1 )
  {
    if ( !isSpace(r) )
    {
      return true;
    }
    file.read();
  }
  return false;  
}
 
// Reads a single word (anything up to the next whitespace character) into
// the given buffer
bool getNextWord( File& file, char* buffer, int bufferSize )
{
  int r;
  while ((r = file.read()) != -1 )
  {
    if ( isSpace( r ) )
    {
      *buffer = '\0';
      return true;
    }
    if (bufferSize > 1 )
    {
      *buffer = r;
      ++buffer;
      bufferSize--;
    }
  }
 
  *buffer = '\0';
  return false;
}
 
 
// originally this function did more
int readResistor()
{
  return analogRead(A0);
}
 
 
void loop()
{
  char buffer[17];
 
  if (findNextWord( file ) )
  {
    getNextWord( file, buffer, sizeof(buffer) );
    lcd.clear();
    lcd.print( buffer );
  }
  else
  {
    lcd.clear();
    lcd.print("--end--");
  }
  int v = readResistor();
  lcd.setCursor(0, 1);
  lcd.print( v );
  delay(v);  
}

New Server

Regular followers of this website may have noticed that it has been offline for the best part of 24 hours. This was to get it moved from my hosting company’s legacy server to a more modern machine. I use OpenHost for hosting sandfly.net.nz, they perhaps are not the cheapest option (especially if you consider American bulk hosting) but on the plus side they actually rang me yesterday when they saw that I was lost in the maze of account options that their customer portal provides.

The upgrade went smoothly enough although next time I will remember to disable any WordPress plugins before doing the backup since some of them seem to not like being moved. Bouncing them back to active seemed to do the trick.

All this kerfuffle was just to upgrade WordPress to the latest point release. I think everything is working, although I have lost any WordPress comments made yesterday. Let me know if you see any (unintentional) weirdness.

Game Review : Wrath of Ashardalon

Things are not going well for the villagers that live near the dark volcano that dominates the landscape. The smoke and ash the billows from the inaccessible crater is only a minor problem, far worse are the horrible creatures that dwell in the crevices that split the mountain’s flanks. And lurking somewhere deep within the lava-fulled depths – Ashardalon awaits!

First things first – Wrath of Ashardalon is an official Dungeons and Dragons game, played like you would a D&D adventure with simplified combat with the game mechanics taking the place of the DM. Still reading? Very well, let us continue…

Up to 5 adventures can play, each selecting a different pre-defined character but choosing a subset of the available abilities to start with. Each turn, the a player moves his character around the board and possibly attacks a monster if one is in range. At the start of the game, the board consists of a single 4*4 tile but if a player ends his move on an edge then pick a random tile and place it on the board, exposing a new part of the dungeon. At least one monster is placed on each new tile. Usually an encounter card is drawn as well, these have effects (almost always bad) ranging from the current player being hit by an arrow from the shadows to everyone taking damage from poison gas.

Then it is the monsters turn to move, the current player does that before ending his turn. The monsters all behave slightly differently, but the cards carefully explain what to do. Combat is very simple – roll a 20 sided dice and add the attack value to see if it meets the armour class of the defender. Most monsters can be dispatched with one or two hits so bookkeeping is kept to a minimum.

The ultimate goal changes depending on the scenario chosen at the start of the game. In our most recent game we had to fight our way through the random tunnels to find a special tile that opened into a large chamber filled with monsters led by a special “villain” monster with extra abilities. Our first attempt failed utterly but we got there in the end.

One word best describes Wrath of Ashardalon – hardcore! The box contains a vast amount of cards, tokens, thick cardboard map tiles, and 42 unpainted plastic figurines. The figurines are different from the normal D&D figures but detailed and suitable monstrous. The map tiles are very heavy card-stock and the art in nice throughout; full marks for presentation. The rulebook looks good but has a uphill battle trying to explain things, especially since many of the rules only apply during certain scenarios. It was only on our second game that we felt we were playing things correctly and even then we had problems.

The closest thing I could compare Wrath of Ashardalon to is the old Gauntlet arcade game from the 80s. The game forces you to move fast, uncovering the dungeon quickly to reach your goal. The clock is ticking since horrible events befall your party nearly every turn. Trying to mop up every single monster before continuing only leads to defeat; far better to keep moving and conserve your meagre resources as long as possible.

Wrath of Asgardalon certainly can be fun, but is really only for experienced players. The game balance is brutally stacked against the players, so everyone has to be making the most of their abilities all the time. Even then blind chance can completely screw you (and everyone else) over with no chance to counter it.

Recommended only if you have a group of friends who really like Dungeons and Dragons and Losing and Restarting.

Arduino POV Device Part II

Last week I wrote about starting with digital electronics with the Arduino prototyping platform. Getting something working was easy enough but I was dissatisfied with ugly result, especially when my friend Lloyd showed up with his extremely tidy version of the same idea. The piece of cardboard had to go!

My first version used a breadboard and uncut LED leads because I thought that I would want to dismantle the components for reuse. However I have since realised that I am a grown man with a career and can easily afford the $4.50 material cost. Behold POV version 2:



I won’t be entering this in any soldering competitions but it works OK.

The code has also changed. Compiling in what amounts to a 2D bitmap was a quick way to get something up and running but it wasn’t very flexible, especially since in the future I want to display long strings of text. This means storing glyphs (letter shapes) for every letter of the alphabet (plus digits and symbols) – what I needed was a proper font; what I got was this:

I then turned to Python to generate the program data to embed in the new Arduino code. This script slices the image vertically, generating one byte (actually only 7 bits) for each slice of pixels. What comes out is a long list of byte values that can be output directly to the Arduino’s IO pins to display each section of the text, along with a set of indexes that map letters to the start and end positions of individual glyphs in the array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import sys
 
def GetSlice(i, pos):
	t = 0
	for q in range( pos, len(i), len(i) / 7 ):
		t = t * 2
		if ( i[q] != '\x00' ):
			t = t + 1
	return t
 
def GetGlyph( i, pos ):
	end = pos
	start = pos
	data = []
	while (end < len(i) ):
		t = GetSlice( i, end )
		if ( t == 0 ):
			break;
		data.append( t )
		end = end + 1
	return (start, end, data)
 
def GetFont( d ):
    result = []
    i = 0
    currentIndex = 0
    indices = []
    while ( i < len(d) / 7 ):
	(start, end, data) = GetGlyph( d, i )
	if ( len(data) == 0 ):
		break
	i = end + 1
	indices.append( currentIndex )
	currentIndex = currentIndex + len(data)
	result.extend( data )
    return ( result, indices )
 
if __name__ == '__main__':
    if ( len(sys.argv ) != 3 ):
        print "USAGE: program <input> <output>"
        exit()
    data = []
    i = file( sys.argv[1], "rb" )
    data = i.read()
    i.close()
    ( d, indices ) = GetFont( data )
    o = file( sys.argv[2], "w" )
    o.write( "static const int indices[] = { " + ",".join(map(str, indices ) ) + " }; ")
    o.write("\n")
    o.write( "static const unsigned char fontdata[] = { " + ",".join(map(str, d)) + "};")
    o.write("\n")
    o.close()

This scheme is more complex that the original bitmap but allows arbitrary text to be display without lots of editing. The modified Arduino code now looks like this. The first two lines contain the new font data, and you can see that the text to display is simply declared on line 5.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
static const int indices[] = { 0,4,8,12,16,19,22,26,30,33,37,42,45,52,59,63,67,71,75,79,82,86,91,96,101,106,111,116,121,126,131,136,141,146,151,156,161,163,165,167 }; 
static const unsigned char fontdata[] = { 63,72,72,63,127,73,73,54,62,65,65,34,127,65,65,62,127,73,65,127,72,64,62,65,69,39,127,8,8,127,65,127,65,2,1,1,126,127,8,20,34,65,127,1,1,63,64,64,60,64,64,63,127,32,16,8,4,2,127,127,65,65,127,127,72,72,48,62,65,71,62,127,72,76,51,50,73,73,38,64,127,64,126,1,1,126,112,12,3,12,112,126,1,15,1,126,65,54,8,54,65,96,16,15,16,96,67,69,73,81,97,62,69,73,81,62,17,33,127,1,1,71,73,73,73,49,65,65,73,73,54,24,40,72,127,8,121,73,73,73,6,62,73,73,73,6,65,66,68,72,112,54,73,73,73,54,48,73,73,73,62,3,3,123,123,27,27,127};
 
static int outputPins[] = { 12, 11, 10, 9, 8, 7, 6 };
static char text[] = "ANDREW";
 
void setup()
{
  for (int i = 6; i<=12; ++i)
  {
    pinMode(i, OUTPUT);     
    digitalWrite(i, HIGH);
  }
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  delay(2000);
}
 
void loop()
{
  byte row = 0;
  byte endRow = 0;
  char* currentChar = text;
 
  while (1)
  {
    if (*currentChar == 0)
      currentChar = text;
    if ( row == endRow )
    {
        char t = *currentChar;
        currentChar++;
        t = t - 'A';
        row = indices[t];
        endRow = indices[t+1];
    }
    while (row != endRow)
    {
      byte mask = 64;
      for (byte pin = 0; pin < (sizeof( outputPins) / sizeof(outputPins[0])); ++pin )
      {
        digitalWrite( outputPins[pin], (fontdata[row]&mask)? HIGH : LOW  );
        mask = mask / 2; // divide mask by two, moving it down one bit
      }
      row++;
      delay(1);
    }
    for (byte pin = 0; pin < (sizeof( outputPins) / sizeof(outputPins[0])); ++pin )
    {
      digitalWrite( outputPins[pin], LOW);
    }
 
    delay(1);
  }
}

Still to do: This code is not very efficient. It uses digitalWrite() in a loop to turn on the LEDs. digitalWrite() is very easy to use but if you look at the source code you will see it does all sorts of unnecessary stuff for this job. I plan to replace it with direct writes to the required Arduino IO registers.

I also want to make the whole thing interrupt driven to free up the CPU. Why would I want the extra CPU time? I have plans for that as well…

Starting with Arduino

I have a new hobby – digital electronics! Last week I bought an Arduino Uno on a whim from JayCar. Being a typical programmer, I have very little idea how computers actually work on the physical level so this gives me an easy introduction to lower-level coding and electronics in general.

The Arduino is a small board with a fairly capable 8 bit microprocessor (an ATmega328 to be precise) with the IO pins hooked up to convenient headers ready for attaching external devices. The CPU has its own RAM and programmable flash memory, and it comes with a bootloader that can reprogram the flash via the handy USB connection (which can also power the whole board). It is hard to imagine a more plug-n-play device.

I decided that I would follow the well-worn path and create a persistence of vision device for my first project. Mine consists of 7 LEDs hooked up to IO 7 pins (via appropriate resistors), the idea is to make the LEDs blink in such a way that recognisable shapes appear as the LEDs are waved quickly in front of your eyes.

My prototype is a little rough, but works fine in a darkened room (I was too cheap to spring for super bright LEDs and the darkness hides my shoddy soldering job.) The breadboard is too fragile to wave around so the LEDs are mounted on cardboard and connected using a couple of metres of CAT5, which conveniently has 8 internal wires to supply the 7 LEDs with a common ground. The total cost is less than $10, excluding the breadboard and the Arduino itself.

The Arduino programming environment is pretty nifty. The language used is a limited form of C++ (no standard library or runtime support for much of anything) with some extra libraries for managing the CPU’s features. Compiling and flashing the CPU is as simple as pushing a button. Here is the code that generated the above picture:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// Array holding the graphic to display
static char* text[] = {
" XX   X     X  XX     XXXX   XXXX  X     X     ",
"X  X  XX    X  X  X   X   X  X     X     X     ",
"X  X  X X   X  X   X  X   X  X     X     X     ",
"XXXX  X  X  X  X   X  XXXX   XXX   X  X  X     ",
"X  X  X   X X  X   X  X X    X     X  X  X     ",
"X  X  X    XX  X  X   X  X   X     X  X  X     ",
"X  X  X     X  XXX    X   X  XXXX   XX XX      " };
 
static int outputPins[] = { 12, 11, 10, 9, 8, 7, 6 };
static int graphicLength;
 
 
void setup()
{
	// setup the initial state of the pins
  for (int i = 6; i<=12; ++i)
  {
    pinMode(i, OUTPUT);     
  }
	// pin 13 is hardwired to the onboard LED, turn it off
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
 
  graphicLength = 0;
  for (char* t = text[0]; *t!=0; ++t)
  {
    ++graphicLength;
  }  
}
 
void loop()
{
  while (1)
  {
    for (int i = 0; i < graphicLength; ++i )
    {
		// find out if the pin is supposed to be on (HIGH) or off (LOW)
      for (int pin = 0; pin < (sizeof( outputPins) / sizeof(outputPins[0])); ++pin )
      {
        if (text[pin][i] == ' ')
        {
          digitalWrite( outputPins[pin], LOW );
        }
        else
        {
          digitalWrite( outputPins[pin], HIGH );
        }
      }
      delay( 1 );
    }
  }
}

Not very efficient but simple enough to get going. I am already working on a more functional version which will have its own font and interrupt driven display.

Google+

Why yes, I do have a Google+ account. Why do you ask?

Actually, it is no big thing any more. Google are slowly allowing more people on as they ramp up their Facebook-beating service. I have been using it for a day now, and I like a lot of what I see. Unfortunately, the rest of what I see sort of mystifies me instead.

Google+ is a Facebook-like service, where people publish Facebook-like status updates to Facebook-like lists of friends, maybe attaching a link or a photo kind of like you do in another social media website whose name has temporarily slipped my mind. Basically, it’s Facebook with a slightly more up-to-date look.

Google+’s main UI difference is the concept of circles. These allow you to easily group your contacts (friends, workmates, family, etc) with a snazzy drag-and-drop interface. Then you can pick which circles get to see each thing you post. It is a lot easier to use than Facebook’s group concept and more offers more granularity without being to complex.

It is early days yet, but there are things that Facebook still does better. Posting a link is nowhere near is easy – Facebook allows you to easily customise the summary it displays where Google+ only allows you to delete the summary, not replace it with your own. Notifications are also slow to arrive, but Google+ does display notifications in the other Google apps (gmail, reader) which is very handy.

One thing I was disappointed not to see what any way to link content from other sites into my Google+ stream. For instance, there is no way to automatically post links to new articles on this blog to my Google+ stream. Facebook sort of allows this with its Notes feature. I don’t use Twitter, but that doesn’t seem to be included either. Google has Friend Connect for following blogs, but that doesn’t seem to be integrated into Google+ at all. It is all very strange.

I haven’t tried the Hangout feature since I don’t have a webcam on my main computer, but it looks like it could be useful if it works as advertised. The Sparks feature (similar to Google news but not limited to current events) seem great, but doesn’t really need to be part of Google+. It would be better as a widget on the homepage.

Social Media only gets it’s usefulness from the number of people who use it regularly. Even if Google+ was as good as Facebook (which it may be soon), there is very little point in anyone maintaining two accounts across different services. Facebook got big because it was a grown-up MySpace, Google+ may be trying for a grown-up Facebook, but Facebook hasn’t annoyed its users like MySpace did (yet). I can’t see a mass migration from Facebook to Google+ happening soon unless Google has a few more cards up its sleeve.