Adam O'Grady

VoIP Adventure Game

First on Gopher, then in LaTeX, it started becoming apparent that I have a predilection towards short, one-shot Choose Your Own Adventure-style stories on strange mediums. So in that vein, I decided to make another one, but this time played via a phone call made to a VoIP (Voice over Internet Protocol) number attached to a virtual PBX.

To do this, I firstly needed a VoIP number. Thankfully my ISP (iiNet) provides a free VoIP number to NBN customers, so that was covered. Next up I needed a virtual PBX, I went with Asterisk. This was an easy install on Ubuntu 18.04, just:

sudo apt install asterisk

Then I had to go through setting up VoIP on Asterisk, and then I was free to start setting up the game. I had written out a little story in Google Slides, using their slide linking feature to document where all the story went.

Voice Recording

Voice recording is obviously painful, no one likes to hear their own voice played back to them. I used Audacity to do the recording, because you can export to Ogg easily. Make sure you record as a mono stream, then install the SoX (sound exchange) tool. On macOS with Homebrew this is simply brew install sox.

Once you have all the recordings done and in a folder, you can convert them all to the .sln format required by Asterisk with the following command:

for a in *.ogg; do  sox "$a" -t raw -r 8000 -c 1 ${a/.ogg/.sln}; done

This also downsamples them to an appropriate rate. Now upload the files to the directory that contains all the Asterisk sound files, it should be something like /usr/share/asterisk/sounds/en_US_f_Allison/.

Extensions Setup

The entire game is setup through extensions and contexts. So starting with your default inbound call context, add the following:

[inbound]
exten => XXXXXXXXXX,1,Answer()
exten => XXXXXXXXXX,n,Set(TIMEOUT(digit)=1)
exten => XXXXXXXXXX,n,BackGround(start1)
exten => XXXXXXXXXX,n,BackGround(start2)
exten => XXXXXXXXXX,n,WaitExten()

exten => 1,1,Goto(house,10,1)

exten => 2,1,Goto(forest,10,1)

exten => 3,1,Goto(river,10,1)

In this case, I’m using XXXXXXXXXX as a cover because my phone line is actually listed there. But what happens is we allow for a single digit press, and then play two voice files. The first says:

You wake up in an empty, verdant field, soft grass cushioning your prone form. You stand up slowly, sluggishly.

The second goes:

To the West is an impassable cliff. Press 1 to travel North to a house you notice in the distance. Press 2 to travel East to a dense forest. Press 3 to travel South to a rushing river that edges the field.

We then wait for the user to press a button, which leads them to the related extension. You’ll notice this runs a Goto, which jumps to a different context with different extensions. You can set up the other contexts like so:

[river]
exten => 10,1,Set(TIMEOUT(digit)=1)
exten => 10,n,Background(river)
exten => 10,n,WaitExten()

exten => 1,1,Goto(inbound,XXXXXXXXXX,1)

This one plays allows for one digit to be typed, plays a sound, and then waits. If the number 1 is pressed, it takes us back to the inbound line and plays that again. You can add multiple extensions and as many contexts as you want to create as complex of a game that you’d like.

If you want to give mine a shot, try (from Australia) 08 6111 9227 or internationally I think +61 8 6111 9227 (be wary of call costs).