Making @HoroscopeBot

Internet, Programming

Tweets by @HoroscopeBot

Last weekend, as a side project, I decided to create an oracle. Like most oracles he spouts nonsense, occasionally happening upon a cogent statement by random chance and serendipity. His name is @HoroscopeBot, and he takes the auspices of Twitter to post a semi-coherent prophecy every twenty minutes.

What inspired this unusual creation? Through another act of internet happenstance, I became acquainted with two prolific bot-makers: Darius Kazemi and Rob Dubbin. As I followed their various projects, I slowly became convinced that bots were more than a mere novelty. Their playfulness with language and meaning was strangely revealing. They were subversive in a world that is increasingly run by algorithms. They could also embrace the inherently unpredictable nature of automation and make it charming.

While ruminating on these bots, I conceived of a simple bot idea of my own. I decided that I needed to make it right away, and devoted an idle weekend to develop the minimum functionality. The idea was to to find tweets of the form “you will ______”. If I prepended two such statements with a zodiac sign, it would create a disjointed horoscope. For instance:

GEMINI ♊: You will come out on the banks of the Rio Grande, but you will have to build a jail.

LIBRA ♎: You will be my queen, but you will NEVER MAKE A FREE THROW IN YOUR LIFE.

SCORPIO ♏: You will understand it, but you will need tissues.

On the technical side, this involved communicating with the Twitter API using OAuth, parsing text with regular expressions, and finding a host that could re-run the logic at set time intervals automatically. Following an online tutorial, I began developing my bot in Google Apps Script.

I initially thought that grabbing tweets would be the most difficult technical hurdle, but the API was actually quite straightforward. The rub was that my application required manual reauthentication every few hours, which is a major annoyance for a program that’s defined by its ability to run 24/7. Twitter has a workaround for this; they will provide you with a single access token that will never expire. However, Google’s OAuth library would not allow me to simply provide it with a token; it wanted to do authentication the “right” way.

To make the bot fully independent, I had to port the logic to Node.js and deploy it on Heroku. This was not a smooth process (mostly due to the limitations of my git knowledge), but the twit library finally enabled me to connect to Twitter indefinitely with my access token. As of Sunday morning, @HoroscopeBot should regularly tweet new prognostications with no further intervention; you can check out the source code on GitHub.

In an interview with the Boston Globe, Darius says he was inspired by Ian Bogost’s idea that, in lieu of writing, objects can embody philosophy. In that context, I’ve thought about what sort of viewpoint my bot is advancing. Maybe it demonstrates the incompleteness of written language. Sentence fragments are fungible, and simple juxtaposition can create unintended meaning; context is always important. Alternately, perhaps it celebrates second-person aspirations. Somebody is saying “you will”, will you?

→ No CommentsTags:  ·  · 

Solo Queue: An Exercise in Serenity

Programming, Video Games

This weekend I committed to finishing a small Twine game I’ve been dabbling with intermittently for the last year. It may seem a little esoteric (and rather silly) if you’re unfamiliar with the game genre being parodied, but hopefully it’ll still convey the general idea.

You can play it directly in your browser by clicking the title below:

Solo Queue: An Exercise in Serenity

Solo Queue is inspired by Dan Bruno’s Time for some Fire Emblem and Alex Austin’s Bioshoot Infinite + 1. I was intrigued by the notion of abstracting a game’s core mechanics into Twine as a form of critique. I wanted to apply the same approach to the lords management game (a.k.a. MOBA) I play most regularly: League of Legends.

While I was fiddling with Twine, I was also working (and eventually had some success) at climbing the season 3 ranked ladder in solo queue. There is a certain inherent insanity in attempting teamwork with four complete strangers. To quote Reservoir Dogs:

Mr. Pink: Why can’t we pick our own colours?

Joe: No way, no way. Tried it once, doesn’t work. You got four guys all fighting over who’s gonna be Mr. Black, but they don’t know each other, so nobody wants to back down. No way. I pick. You’re Mr. Pink.

Succeeding in solo queue requires diplomacy, flexibility and ego management. Ultimately, it’s a lesson in serenity; you must accept that you are going to lose many games regardless of your personal performance or skill.

Solo Queue in Twine

As I’ve indicated previously, I had some troubles working with Twine. In fact, halfway through development I moved the passages to a plain text file and began compiling them directly with twee. I also wanted to avoid mixing JavaScript code with story content, so I stored the macros in separate files and wrote a few quick Perl scripts to append them together at build time. The workflow worked quite well once I’d set all that up; I especially enjoyed being able to easily import Leon Arnott’s excellent Twine macros.

It felt great to work on a hobby game again, though I’d like to attempt something with more systemic mechanics for my next side project. In the meantime, I hope you enjoy my preposterous little game, and to all the League players: best of luck in season 4!

→ 1 CommentTags:  ·  · 

Twine Troubles

Programming

Photo by Daniel Schwen

The interactive fiction platform Twine has been around for many years, but recently it’s been at the centre of the DIY game creating movement. Rise of the Videogame Zinesters heralds it as an accessible development tool for those without programming experience. New voices are joining the game-making world, and the variety of Twine games is truly remarkable: personal games, satirical games, Kafkaesque games, sexual games, and many more.

Inspired by the creativity of this new wave of game makers, I decided to work on a small Twine game as a side project. I read a few tutorials, downloaded the application, and began assembling a story. Unfortunately, I started encountering minor hindrances much sooner than expected. I was digging through forums and documentation to implement functionality that I thought would be trivial. Disheartened, I frequently had to resort to kludgy workarounds.

Here are my four biggest frustrations with Twine:

No Nested Logic

Twine has built-in syntax for linking passages, displaying text conditionally and getting/setting variables. However, the syntax does not allow any of these to be nested. You can’t display a variable inside a link or a conditional statement. You also can’t embed any html inside a link, which makes image links difficult.

// Can’t print a variable in a link
[[Hello there <<print $name>>|Say Hello]]

// Can’t conditionally print a variable
<<if $name eq "Bob">>Is <<print $husband>> feeling better?<<endif>>

// Can’t embed an image in a link
[[<html><img src=”foo.jpg” /></html>|Link]]

The workaround is to write your own html in these cases, instead of using the built-in Twine syntax. You can access the Twine variables and link to passages using JavaScript, though that has its own headaches (explained in detail below.)

Verbose Macros

Twine allows you to write custom JavaScript macros, which is great! The process for doing so, however, is a tad obfuscated and verbose. To make a macro: create a new passage, add the tag “script”, then write your logic in a function with the following template:

macros['randomnumber'] = {
    handler: function(place, macroName, params, parser) {
	insertText(place, Math.random());
    },
  };

That’s the bare minimum script for inserting a random number. Here’s a fancy version with all the bells and whistles:

try {
  version.extensions['randomnumber'] = { major:1, minor:0, revision:0 };
  macros['randomnumber'] = {
    handler: function(place, macroName, params, parser) {
	if (params[0] === undefined) params[0] = 0;
	if (params[1] === undefined) params[1] = 1;
	var n = Math.round(Math.random()*params[1] + params[0]);
	insertText(place, n);
    },
  };
} catch(e) {
  throwError(place,"randomnumber error: "+e.message); 
}

None of it is egregiously verbose, but boilerplate phrases like “handler function place macroName params parser” are daunting. Twine is a great tool for first-time game makers, it would be nice if writing macros was equally approachable.

I also wish it were possible to import script functions from external files. That would allow authors to share and reuse modular components. A library of common functions would be a boon to those without the technical knowledge to write their own JavaScript. Dan Cox has a clever macro for loading external JavaScript libraries, which I’d love to see integrated natively.

File Format

Twine is a graphical interface wrapper for a simple plaintext format (called twee). However, the application saves stories in a .tws file, which is just a Python pickle serialization. Since this format is not human readable, it discourages the use of source control. Why bother tracking your changes when you can’t understand the incremental differences?

Thankfully, there’s an easy built-in way to get around this. In the Twine menu, call File > Export Source Code to export your story to a plaintext twee file. You can even modify that file in a text editor and reimport it back into Twine (though you’ll lose some of your previous passage arrangement).

Weak Documentation

There is some documentation for both Twine and twee. The former covers the basics and the latter alphabetically lists available functions (assuming robust JavaScript knowledge); neither is terribly useful for learning to write macros. I found the answers to my questions scattered across the TweeCode google group, Porpentine’s resource compilation and Dan Cox’s macro tutorials. Here are a few useful tricks I had to figure out the hard way:

Firstly, if you want to link to a passage (named “foo”) from embedded html (e.g. for an image map) use <html><a href="#" onclick="javascript:state.display('foo', this); return false;"> foo </a></html>. (If you neglect to return false, it’ll work on Chrome but not Firefox.)

Secondly, if you set a variable in Twine syntax using <<set $foo = true>>, you can access it from within JavaScript macros with state.history[0].variables["foo"]. You can use this to get around some of the nested logic issues I mentioned earlier.

Finally, a minor idiosyncrasy: Twine does not allow links back to the “Start” passage. Many authors get around this limitation by making a new first passage and displaying it in “Start” with <<display ActualStart>>.

Despite my criticisms, I still think Twine is a valuable and important platform. Fixing certain small issues would simply improve what the tool already does well: provide a accessible way for everyone to make personally meaningful games. Twine is free and open source with a passionate community, so I’m certain it’ll continue to improve and grow.

→ 5 CommentsTags:  ·  · 

Mark of the Dishonored

Video Games

Mark of the Ninja + Dishonored

I’ve been feeling rather stealthy lately, playing through Dishonored and Mark of the Ninja over the last few weeks. Playing them back-to-back has contrasted them rather sharply in my mind, though neither title suffers for the comparison. Rather, I’d like to highlight how certain elements of Mark of the Ninja’s design align perfectly with how I like to play stealth games.

Since most stealth games allow for a great deal of player agency, there are many perfectly valid ways of playing them. Some move through the levels like a ghost, others prefer to murder everyone from the shadows. Some are willing to go loud if their stealth is broken, others hide and try again. My preferred approach is to play each scenario as flawlessly as I can. I like to ascertain a situation, determine a strategy, execute it, then figure out how I could have done better. Can I avoid alerting the guards? Use fewer resources? Turn the environment to my advantage? I treat it like a puzzle, playing it over and over to find the optimal path.

In theory, there are “try again” mechanics built into the stealth genre. Your character is weak, so the guards can kill you quickly. Alternately, you escape and wait for the alert to die down. Either way you get a chance to reevaluate your strategy. However, both of those options are time-consuming, and the delay makes it difficult to iterate on a plan. Once you sit through a death animation and loading screen you’ve already forgotten the specifics of your recent failure. I made a point to pick up Dishonored on PC, allowing me to use quicksave and quickload to narrow down my perfect approach.

I didn’t have to micromanage my saves in Mark of the Ninja. The checkpoints are generous and there’s no score penalty for death. When my plan went badly awry, the window for recovery was small; I either died or escaped within a few seconds. There’s no minute-long ambiguous alert state, just clear immediate success/fail feedback. You could say Mark of the Ninja is the Super Meat Boy of stealth games: you die a lot, but you’re already back in game before that has a chance be bothersome. Iterating on a plan isn’t a tedious process when you can immediately begin executing your next idea.

Mark of the Ninja

Another element that supports the “puzzle” approach to stealth is predictability. As Anthony pointed out, Mark of the Ninja’s clean 2D presentation and excellent UI make it an exceptionally deterministic game. You have the unlimited ability to freeze time and line up exactly where your ninja distractions are going to land. Vision cones and noise radii sharply visualize the limits of a guard’s awareness. Everything is a known quantity, making failure a fault of planning rather than execution. The ability to know the outcome of individual actions with certainty gives players the confidence to create complex plans.

When I feel comfortable with a stealth game’s mechanics, I often like to invent impromptu challenges for myself. Can I fit all the knocked-out guards into one closet? Can I reach that far ledge with a pile of physics objects? I’m always impressed when the game recognizes and encourages these actions. For instance, I grinned when Dishonored popped up an achievement for reaching the top of Kaldwin’s Bridge.

Mark of the Ninja takes this idea one step further by taunting you with challenges. A prompt appears when you enter a new area, with instructions like: “kill 3 gasmask guards while they are walking in poison gas”. It’s entirely optional and rather difficult to pull off, but who can resist the temptation to try! The fact that this challenge exists is also a hint to new players: here’s something fun you didn’t know you could do. Completing challenges helps reinforce the player’s knowledge of how certain game mechanics interact. Reifying the made-up challenges that experienced stealth gamers give themselves helps encourage an improvisational mindset in every player.

Mark of the Ninja is a spectacular game, one that makes stealth mechanics accessible and readable without reducing their complexity. Furthermore, it support the puzzle-like stealth experience that I love: figuring out a plan then executing it flawlessly. I can’t wait to see what Nels and the team at Klei come up with next.

Oh, and I completely agree with RPS: the ninja protagonist should be named Mark.

→ 1 CommentTags:  ·  · 

The Perpetual Testing Initiative

Video Games

Portal 2 Level Editor

This week saw the release of Valve’s new beginner-friendly level editor for Portal 2, dubbed the “Perpetual Testing Initiative”. Many have praised this new software for its accessibility, and have advocated it as an entry-point for first-time level designers. I had a chance to experiment with it a little myself, and I’d like to explore some of the specific principles Valve employed to create this remarkably approachable editor.

Booting up the editor for the first time gives you a simple rectangular testing chamber. The walls and floors can be dragged in any direction to expand the space or create connected chambers and corridors. Puzzle devices are dragged and dropped into the world from a tidy panel on the left side of the screen (very much like The Incredible Machine.) Right clicking these elements in the world exposes a small selection of options, and allows you to connect them to other devices. Simply moving the camera around the 3D space will likely be the most challenging interaction for a fledgling designer.

The editor is stylized like a blueprint: elements appear simpler than they do in-game, some devices (like the Aerial Faith Plate) project dashed path lines, and ceilings / backward-facing walls are automatically hidden from view. A working knowledge of Portal mechanics is assumed, as there are curiously no tool-tips to explain how the various devices function. Even I had to use trial-and-error to figure out how the Track Platform works, as the official Valve wiki is unfortunately sparse at the time of writing.

A great deal of editor’s simplicity derives from the fact that it’s not a generic tool designed to make levels, but rather a very specific tool to make test chambers. Test chambers in the Portal universe have a well-defined format. They are white, sterile, closed and grid-aligned rooms. They contain some permutation of the 32 devices. They necessarily have exactly one entrance, one exit and one observation room (which functions as the level’s main light source.) These fiction-appropriate constraints keep the editor simple by limiting the number of possible ingredients.

The devices themselves demonstrate a similar simplicity; both input devices (buttons, laser catchers) and output devices (laser emitters, piston platforms, etc.) maintain only binary states. Attaching several inputs to the same device will require them all to be active (logical AND), but there is no sanctioned way to achieve OR, NAND or XOR. Connections between devices are always visible to the player, as the editor automatically generates an in-game dotted line between them. Keeping the interaction between devices simple allows the editor to abstract away from any sort of complex scripting logic.

Fundamentally, the Portal 2 editor works so well because of the judicious use of physical constraints. In The Design of Everyday Things, Donald Norman describes how these types of limitations “constrain possible operations” such that “desired actions can be made obvious.” Since it’s almost impossible to do the wrong thing in this editor, the only possible actions are correct ones. Designers are thus free to experiment without fear of breaking the level in an esoteric way. The only clearly incorrect operation I’ve found is placing two devices in the same spot; the feedback for this error is clear and immediate.

In my few hours of experimentation I made a simple test chamber called “Ducks & Drakes”, which you can download and play by hitting subscribe in the Steam Workshop. You should also check out the Perpetual Testing Challenge over at the MapCore Forums.

Tags:  · 

© 2007-2014 Matthew Gallant, hosted by A Small Orange, powered by Wordpress, theme based on Basic.