cool programming

AI Dungeon 2 Is Fun Nonsense

Apparently, there’s something about Mary

It’s night. I’m a private detective from Chicago named Joseph, on the hunt for someone named Jim, and I have a gun and a badge. I’m in the woods, and I hear some noise from behind the trees. Suddenly an old man shoots an arrow from a bow at a hitherto-unseen target. He runs off, but I catch up with him and ask his name. It turns out that he’s also a detective from Chicago named John, and he’s also hot on the trail of Jim too.

I ask “How did you know my name?” and he replies, succinctly: “Because we’re both detectives.” I try to discuss the case with him, but he refuses to be drawn on it, preferring to cryptically state “I’m sure we’ll have some clues soon enough”.

We come across a small house in the woods, and I venture inside. A woman sits, reading quietly. I ask her about Jim, but she only says that he left long ago. I make a note of the house and return the next day without John. I look around and find some white socks and black pants. Ah-ha! These are crucial to the case. I put them on immediately. Surely it’s now only a matter of time before I find Jim.

I find only a shack, in which a single light bulb illuminates a strange assortment of books and papers with diagrams.

I go back outside, and see John, the other detective watching me cautiously. Clearly he’s jealous of my new socks and pants. He disappears into the woods. I run after him but find only a shack, in which a single light bulb illuminates a strange assortment of books and papers with diagrams. I picture Jim with this:

Combing through the strange lot of papers, I find one that might help my case! It’s a drawing. A drawing of a man in front of a tree. He has a hat, and the hat has horns. His eyes are wide open and staring at me.

This is Jim!

I find the tree in the drawing. It’s odd. It isn’t right. It seems to be made of wood, but it has cracks all over and seems as if it was never alive in the first place. Maybe it has Jim inside it? In any case it isn’t right. It has to go.

I break the tree apart, fling a piece at a nearby wall, which thuds, then silence.

The next day, I come home and see that everything is gone.

The above is how my first dabble with AI Dungeon 2 started. I was linked to it without context, so had no preconceptions going in. it all started off somewhat normally, I wondered if it was some kind of randomly-generated MUD (a old text-based system predating popular MMORPGs that let users create text-based worlds and interact with one another. But as things got slowly more odd it seemed like it was something else. It had the slightly weird, funny cadence that computer-generated text has.

I had come close to finding Jim. The house, the pants, the drawing in the shack, and the tree. They all fitted together, and I knew I must be close. I returned to the woods.

Thereupon I chanced on a woman sitting on a rock, crying. She explained that her sister Mary had gone missing only the night before. Perhaps Jim had a hand in this. I tried to explain the situation as best I could, but this only upset her more. So instead, I gave her a hug. This calmed her down, perhaps too much. She fell to the ground. She needed to be somewhere safe, but where? Ah! The shack! I carry her there.

Going in, I find a man dressed in an old coat and wearing glasses. He has long white hair that hangs down to his shoulders. His eyes are closed and he seems very tired looking. What the heck is he doing there? I demand to know his name.

“My name is James, but everyone calls me Jack.” Joseph, John, Jim, James, Jack… Wait! James? As in the unshortened form of Jim..? I have to think on my feet, and decide to act quickly.

“Where is Mary?”

I’ve got him now. Or so I think. But the man just sighs and shakes his head. He thinks he’s won. But I’m Joseph, a detective from Chicago. And Chicago detectives know how to roll with the punches, literally and figuratively. I decide to roll with this one and throw him off balance. I drop my voice, lean in close and growl:

“Where is Jim?”

“Mary..? She left with another guy named John.”

He yawns and rubs his eyes. He looks tired too. But he knows I’ve got him. “Mary… Jim… Where is Mary?” He’s trying to throw me, but he didn’t reckon with my Windy City credentials. He coughs and then speaks. “She left with another guy named John.”


The one thing I wasn’t expecting. The one man I didn’t suspect.

Time for action. Mary and John can wait, but Jim’s my case and he has questions to answer. I grab Jim by the collar and pull him from behind the desk. He puts up a brief resistance, but he isn’t strong enough to break free. Up against the wall he goes, and I cuff his hands together behind his back. Time to take him downtown.

I’ve long enjoyed the output of Markov chains. They are some relatively simple procedures for generating sequences based on previous values and frequencies. You can apply this to text, and generate new text based on frequencies of letters, or words.

The old resources I used to learn about Markov Chains way back when have somewhat stuck in my head. I recall a reference to ‘Alice in Elsinore’; and that can be found at a page called ‘Fun with Markov Chains‘. There’s another bit which went into the varying lengths, how short lengths — say, one to three characters — produced gibberish that kinda almost looked like it might have been English once; and longer lengths gradually come closer and closer to the original text[s]. That seems to have been part of Programming Pearls, which used to be available to read online; I only managed to find part of that section archived on Jeff Atwood’s blog by use of some judicious Google search tools.

You can create some fun things with Markov chains. The examples given above included a generated Alice in Elsinore and the Revelation of Alice. I implemented Markov chain text generation as a command for an IRC bot that I wrote, which could talk in the ‘voice’ of my friends that hung out on there; that command was definitely my favourite.

I implemented Markov chain text generation as a command for an IRC bot that I wrote, which could talk in the ‘voice’ of my friends that hung out on there. That command was definitely my favourite.

Latterly, we’ve seen a resurgence in this with the rise in ‘AI’. Such as this ‘AI-written Harry potter fanfiction’

Harry Potter and the Portrait of What Looked Like a Large Pile of Ash
Hungry indeed

or less child-friendly things, like Trump speeches:

But calling any of this ‘AI’ is a stretch. It’s picking things based on random chance and frequency. If I have a sock drawer with thirty red socks, six green and two blue I’d be… a bit boring. But if I closed my eyes and picked socks from there, it would be a bit misleading to write an article saying “I got an AI to choose my clothes for the week and these are the results”.

But I digress.

Having brought in Jim, my attention must turn to Mary. Her sister was counting on me. I trusted my Chicago detective instincts and followed up on a lead that Jim spilled during his interrogation.

I went to the park. There I met two men, Mikey and Brenda. Apparently, they didn’t get along. I knew Mikey was hiding something, and decided to find out what it was. I dragged him into an alleyway, shoved my knee into his back, and started punching him.

I knew Mikey was hiding something, and decided to find out what it was. I dragged him into an alleyway, shoved my knee into his back, and started punching him.

Good Cop time was over, now it’s Bad Cop’s shift.

Mikey pleaded with me for mercy, this was all a misunderstanding, help would be forthcoming, he didn’t want to die, etc. I told him to shut up.

Where is Jim?” I asked in the same voice I used on Jim earlier… Wait, wait. Wasn’t Jim at the police station? “Oh, that’s right,” Mikey says. “He went home for the day.” I was confused, but went along with it. “Oh, good”. But then Mikey had a surprise for me. He grabbed me, threatened me and apologised. I sensed that Jim was a touchy subject best left alone, so asked about Mary.

“Mary?” Mikey asks. “Who’s Mary?” I explained about the woman’s missing sister. “What about her?” Mikey enquires further. But at that point we spot mart coming out of a store. I approach Mary, and she looks surprised to see me.

“Hey, you’re not my brother anymore,” Mary says. “Are…are you?”

Apparently she recognised me. I ask about her sister and Mary explains she’s at work.

At this point I realise something weird is going on. Sounds seem muffled, colours aren’t quite right, and time and place seem strangely elastic.

I thought perhaps AI Dungeon 2 was a bit like Sleep Is Death (Geisterfahrer) by Jason Rohrer, where the stories are written by players; or Cleverbot, where responses given by people are saved and can be reused.

But AI Dungeon 2 instead uses deep learning techniques to keep generating content, no matter what is thrown at it. It does have limitations, but it’s an interesting concept sprung from a Hackathon.

Best bit? It’s Free Software, MIT licensed! Check out its Github!

Things were getting weird. I tried to dance with Mary, which seemed like the thing to do at the time. She stared at me, but not in an uncomfortable way. I tried a backflip, and it ended with us falling asleep together1. Then I had to run away, far away; away from the voices shouting that we’re not sisters.

A group of men accosted me. They looked like they had been drinking heavily. I had to keep the initiative; my detective instincts took over and I slapped one of the men. It surprised the group. I slapped another one and it surprised them identically. But they started to beat me, which I guess was inevitable.

I tried everything to distract them. The harmonica, juggling, telling a joke. Fortunately, the last one worked. Unfortunately, at that moment a helicopter landed and I was kidnapped. Mary tried to rescue me, but the jailer was having none of her please for mercy or bribes. Eventually, he tired of the conversation and wandered off into the woods, and Mary went all Bastille day on the prisoners.

The narrative was based on my first interaction with AI Dungeon 2, which can be read in full.


cool space


It’s hard to not get excited about space, particularly when there’s something great to be excited about. Today I watched live the takeoff of the Falcon Heavy on its maiden voyage, and it was an awe-inspiring, emotional experience. I should have been revising, but it was unmissable.

Another small step forward in space exploration.

all posts cool linux software wisdom

Extract A Single Image From A Video Using FFMPEG

Update: Still using this 8 years later, but in the form of a quick script, which is useful if you are doing it more than once

Dead handy, this:

ffmpeg -ss 0.5 -i inputfile.mp4 -t 1 -s 480x300 -f image2 imagefile.jpg

The various options:

  • -vframes 1: limit to 1 frame extracted
  • -ss 0.5: point of movie to extract from (ie seek to 0.5 seconds; you can also use HH:MM:SS.ZZZZ sexagesimal format)
  • -s 480x300: frame size of image to output (image resized to fit dimensions)
  • -f image2: forces format

I use this to generate preview stills for jwplayer to use. Dead handy!

Edit: Thanks to DieBagger who pointed out it is much faster to place the seek argument before the input file, and Matthias his point about the seek time.

all posts cool life

Spanish Adventure Update: Banks Aren’t Useless After All

Well, not completely useless. A follow up to my post from a few months ago.

So, by now I have decided to go to Barcelona. I will be entering medical school next September, so don’t worry, I haven’t given that up! I don’t have any particular job lined up, but I have heard from various people that teaching English is the way to go. Importantly I have a very useful contact out there who has been most helpful in answering my many questions about accommodation, learning Spanish, the city, and a million other things. Don’t worry; they will be suitably rewarded.

Anyway, I figured it would be useful to have a bank account set up out there. I’m not really a pick up and go type person (I’m trying), and I figure that paying a bank to spend my own money (overseas fees FTL) is a form of ridiculousness I don’t want to be involved in. So, I went and asked my bank about their subsidiary over cashing a couple cheques, and the helpful chap actually went and phoned the Spanish team, who very promptly sent me an information pack and application form!

I must confess at this stage I dallied a bit, partly because the form was all Greek to me (well, Greek would have been an improvement, let’s say, oh, Finnish*) and partly because having it filled in would mean I actually have to leave.

So anyway eventually I got my rear in gear and went back to the branch and had some help from the lovely John (I think… might have been Dave. Sorry, whichever you are) who was as helpful as helpful can be.

The next day I went back with a couple questions I missed. Sadly, on this occasion I got someone somewhat less helpful. She said there was uncertainty as they didn’t really get many people in to do the Spanish stuff, only yesterday John/Dave had said the exact opposite. He was in close contact by email with their contact on the Spanish end, he even serendipitously got an email with her phone number which he used to clarify a couple of my questions. Confusing.

Then I had to convince the person dealing with me to certify a copy of my passport. Never mind this is something the same bank said I needed to do to as a prerequisite for opening my new account. Part of the problem was I wanted to take it away with me, as I was intending to send my documents next day delivery due to an impending Royal Mail strike. More on that later. Anyway I finally got out of the bank an hour later after going through the rigmarole of the international monetary transfer. Did you know the FBI can get information on your transfer (and you) pretty much just by asking nicely? Or any other organisation, bound or not bound by Data Protection Laws. What fun. At least the person doing the transfer was quite pleasant, although she did question my being at university for 9 years – purely from a financial point of view, right enough.

Anyway, after all that, the bit that restored / boosted my confidence (apart from JohnDave and his helpfulness) was that I put a handwritten note in with my application saying essentially: “THERE’S A STRIKE ON, PLEASE BE CLEVER AND NOTIFY ME BY SOME MEANS OTHER THAN POST”. The next day, they phoned me and did just that. The system works. In this specific circumstance. For me, anyway. Kinda.

So now all I have to do is sort flights and accommodation. After that, I’ll probably do something even more fun, like self immolation.


How Not To Run a Poll

There is a very good writeup by Paul Lamere of Music Machinery of how Anonymous subverted a major poll by Time. AKA “moot wins, Time Inc. loses“.

A number of things strike me:

  • Despite how obvious it is, Time deny that the poll was manipulated, stating they have safeguards in place, etc, etc. I guess humble “we fucked up” pie is hard to eat
  • For an influential (ie well-funded) publication they sure have no idea how to protect a poll
  • Anonymous are (as ever) a force not to be trifled with. Sure, they probably won’t topple regimes or enact social change any time soon, but if you draw their ire or attention, you’ll have a hell of a storm to weather.
  • reCAPTCHA wasn’t subvertable, even in the hands of these determined people. This is a Good Thing.

There’s not much else besides these scantly-150 words to say. The writeup is most detailed, although it would have been interesting if Paul had elaborated on how they determined Time’s ranking algorithm to eliminate the need for 46 000 votes. Well worth the read though.

all posts cool linux software wisdom

Installing Debian on QEMU

Since I decommissioned my home server in favour of an NSLU2 (a NAS), I’ve found myself without a Linux machine to much about with or develop on while on the go (well, whenever I can’t use my laptop). So instead I’ll be using a virtual machine by running QEMU from my USB drive. Since my old server ran Debian, and since I haven’t checked it out in a while other than using it’s offspring Ubuntu.

Note: I would recommend getting this set up running on a folder on your hard drive, then copying it to your USB drive if you intend to do that. It will probably be faster, and it will save you trouble if your disk image isn’t large enough.

To get a QEMU binary for Windows, you can download from here, although this is no longer outdated and uses the 0.9.0 release. Unzip it wherever.

Open up a command prompt. cd to the QEMU directory. Create two disk images by running:

qemu-img create -f qcow2 debian.img 1024M .

qemu-img create -f qcow2 home.img 1024M .

This creates two 1024Mb sized qcow images for you to work with – one for your system and applications, and one for your home directory(ies). Obviously you can change the name and size to suit. My USB drive is 4Gb – if you have something smaller like 2Gb, use 768M for debian.img and 512M for home.img. If you have a 1Gb drive, you could try smaller sizes, but you’d probably have more luck trying something like DSL (Damn Small Linux) or puppylinux. I originally tried this with a cumulative 512M for the root and swap partitions, and it wasn’t large enough.

Grab a Debian CD image. I would recommend one of the netinst images. I’m using the Lenny Beta 2 image (here, or the .torrent), but you can use a stable image, or one of the weekly / daily snapshots. Put the image in the same directory as QEMU.

Create a file debian.bat, with the command:

qemu.exe -net user,vlan=1 -net nic,model=rtl8139,vlan=1 -L . -m 128 -hda debian.img -hdb home.img -cdrom debian-LennyBeta2-i386-netinst.iso -boot d -soundhw all -localtime

You can change the -m option for more or less virtual RAM, you can leave out the model=rtl8139 to use the default ne2k driver (I just like Realteks, even virtual ones ;-)), and obviously change the -cdrom option if you use a different image. You can also use Kqemu, but I’m not going to go into that.

Additionally, you can use the command -M isapc (ISA network card), but for that you will have to remove the model=rtl8139; and before using the installer, press [TAB] and add noacpi nolacpi to the installer startup options, otherwise QEMU will crash.

Debian can then be installed as normal. I didn’t install anything that depends on X as I don’t want a graphical system, thought QEMU should handle it fine if you do. I used the partition manager to create a swap partition of about 128 megs. Mount your second ‘hard drive’ (home.img) under “/home”. if you don’t do this now you can do it later by editing /etc/fstab.

(My second disk image / hard drive is mounted as:

/dev/hdb1 	 /home   	 ext3   	 errors=remount-ro   	 0   	 1


Depending on the CPU of your host machine, whether or not you are using Kqemu, and the speed of your internet connection it will take anywhere from 10 minutes to two hours to install.

Once installed you can apt-get install build-essential, or apt-get install nethack, or apt-get install python, or whatever floats your boat. Or, if you’re like me, you can faff about trying to enlarge your partitions because they aren’t big enough.

all posts cool

Visualising The YouTube Pakistan Outage

There is a good post by bluesky74656 detailing how you you can get a pretty cool representation of the BGP routing mess that took out YouTube for anywhere up to 2/3 for the world. I’ve reproduced the post here:

Head over to this site. It visualizes the BGP routes between different AS’s. Click ‘Start BGPlay’. The prefix in which YouTube lives is Set the start time for about 24 Feb 2008 10:00, and the end time for about 25 Feb 2008 03:00 (times are UTC). Start the simulation.

You’ll see a bunch of ASNs. Two have red circles around them. You can get their name by clicking on the number. On the left is YouTube, and on the right is Pakistan Telcom. Click play and watch what happens.

For those too lazy to actually watch this: All the routes destined for YouTube head towards Pakistan Telcom instead. Then, midway through, you see PCCW get wise and shut down those routes, and everyone slowly starts finding the actual YouTube. It’s pretty neat to watch.

all posts cool

Soup Crimp

Soup, Soup-a-tasty
Soup, soup-a-spicy

Carrot and coriander; chili chowder!
Crouton, crouton – crunchy friends in a liquid broth

I am gaspachio – oh! – I am a summersoup – mm!

Miso, miso – fighting in the Dojo
Miso, miso – oriental prince in the land of soup!

Plain Crimp:

On YouTube

The Scene (from “Fountain of Youth”):

Also on YouTube

all posts cool software

Firefox Beta 3

As a PortableApps Firefox user, I downloaded Beta 3 of Firefox 3. It’s pretty slick looking, and there’s a whole host of new features. I don’t like the lack of ‘go’ or ‘->’ at the end of the address bar which was useful for refreshing a page without re-POSTing, and the new location of thehome button will take some getting used to, but it looks pretty good so far!

Check it out and report back any issues to the developers.

all posts arabic cool

My Name is…

I’ve been doing a few Arabic classes recently, and last night we finally had enough knowledge to put together a close approximation of our names.