Thursday, May 17, 2012

Stylesheet organisation

About a year and a half ago I realised I needed to get a grip on how to organise my CSS.  I established a template, which I proceeded to change drastically with every new project.  I noticed recently that I've been reusing a version for the past few projects, with at the most only minor amendments to the general structure.  I also noticed how quickly I'm rolling out initial designs using this template.

I have finally reached the point where I figured out what I consistently reuse across projects, and finally have a stylesheet structure that makes such intuitive sense to me I can dart around and make changes with my eyes closed.  I find my stylesheets are much smaller, but even as they grow, I still know exactly where everything is.  I wish I had some statistics to quote about the amount of time spent scrolling through CSS looking for things.  I'm confident it is much reduced.

Some aspects of my workflow I developed through intuition; I made changes that felt right to me at the time, without really consulting anyone else's best practices.  Other things I picked up from here and there.  Every now and again I'd search for 'the right way' of doing this and find processes and systems that didn't gel with me (a primary example of this being the number of pre-built grid systems I tried and hated).  Eventually I would give up under the sheer number of contradicting points of view, but I probably picked up some subconscious inspiration on the way.

I hadn't thought much of this until Chris Eppstein talked about this at FOWD today.  A lot of the suggestions he demo'd are very similar to parts of my system (conceptually at least; he was discussing SASS and mine is raw CSS).  So I figured it's reached the point it is worth sharing.

First things first, I start with a basic Initializr stylesheet; a couple of minor tweaks, but then I largely accept the helper classes and IE fixes and hacks (no need to read this; it's just here for completeness):


/* ======================================================================
HTML5 Boilerplate CSS: h5bp.com/css
========================================================================== */

article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; }
audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
audio:not([controls]) { display: none; }
[hidden] { display: none; }

html { height: 100%, font-size: 62.5%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
html, button, input, select, textarea { font-family: sans-serif; color: #222; }
body { height: 100%; margin: 0; padding: 0; font-size: 1em; }

::-moz-selection { background: #fe57a1; color: #fff; text-shadow: none; }
::selection { background: #fe57a1; color: #fff; text-shadow: none; }

a { color: #00e; }
a:visited { color: #551a8b; }
a:hover { color: #06e; }
a:focus { outline: thin dotted; }
a:hover, a:active { outline: 0; }

abbr[title] { border-bottom: 1px dotted; }
b, strong { font-weight: bold; }
blockquote { margin: 1em 40px; }
dfn { font-style: italic; }
hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
ins { background: #ff9; color: #000; text-decoration: none; }
mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
pre, code, kbd, samp { font-family: monospace, serif; _font-family: 'courier new', monospace; font-size: 1em; }
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
q { quotes: none; }
q:before, q:after { content: ""; content: none; }
small { font-size: 85%; }

sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sup { top: -0.5em; }
sub { bottom: -0.25em; }

ul, ol { margin: 1em 0; padding: 0 0 0 40px; }
dd { margin: 0 0 0 40px; }
nav ul, nav ol { list-style: none; list-style-image: none; margin: 0; padding: 0; }

img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }

svg:not(:root) { overflow: hidden; }

figure { margin: 0; }

form { margin: 0; }
fieldset { border: 0; margin: 0; padding: 0; }
label { cursor: pointer; }
legend { border: 0; *margin-left: -7px; padding: 0; white-space: normal; }
button, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; }
button, input { line-height: normal; }
button, input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; *overflow: visible; }
button[disabled], input[disabled] { cursor: default; }
input[type="checkbox"], input[type="radio"] { box-sizing: border-box; padding: 0; *width: 13px; *height: 13px; }
input[type="search"] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; }
input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
textarea { overflow: auto; vertical-align: top; resize: vertical; }
input:valid, textarea:valid {  }
input:invalid, textarea:invalid { background-color: #f0dddd; }

table { border-collapse: collapse; border-spacing: 0; }
td { vertical-align: top; }

.chromeframe { margin: 0.2em 0; background: #ccc; color: black; padding: 0.2em 0; }

/* ===============
    ALL: IE Fixes
   =============== */

.ie7 #title{ padding-top:20px; }

/*******************************************/
/*                                         */
/* My styles go here!                      */
/*                                         */
/*******************************************/

/* =============================================================================
   Non-Semantic Helper Classes
   ========================================================================== */

.ir { display: block; border: 0; text-indent: -999em; overflow: hidden; background-color: transparent; background-repeat: no-repeat; text-align: left; direction: ltr; *line-height: 0; }
.ir br { display: none; }
.hidden { display: none !important; visibility: hidden; }
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
.invisible { visibility: hidden; }
.clearfix:before, .clearfix:after { content: ""; display: table; }
.clearfix:after { clear: both; }
.clearfix { *zoom: 1; }

/* =============================================================================
   Print Styles
   ========================================================================== */
 
@media print {
  * { background: transparent !important; color: black !important; box-shadow:none !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; } /* Black prints faster: h5bp.com/s */
  a, a:visited { text-decoration: underline; }
  a[href]:after { content: " (" attr(href) ")"; }
  abbr[title]:after { content: " (" attr(title) ")"; }
  .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }  /* Don't show links for images, or javascript/internal links */
  pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
  thead { display: table-header-group; } /* h5bp.com/t */
  tr, img { page-break-inside: avoid; }
  img { max-width: 100% !important; }
  @page { margin: 0.5cm; }
  p, h2, h3 { orphans: 3; widows: 3; }
  h2, h3 { page-break-after: avoid; }
}

My template is inserted into the appropriate point of the Initializr stylesheet.  I divide into five sections:

/* 0 Accessibility */

/* 1 Typography */

/* 2 Colours & borders */

/* 3 Spacing & layout */

/* 4 Images & video */

I start each section with empty media query clauses for 480px and up, 768px and up, 1024px and up, and 1200px and up.  By the time a project is done each section will typically have from one to six media query breakpoints in it, according to requirements.

0. Accessibility

A staple of this so far is:

/** 
 0 Accessibility
**/
.no-css {
 /* This class hides stuff that needs to be around for screenreaders or users with no CSS, but not in normal circumstances */
 position: absolute; left: -1000px;
}

Which I chuck in when I use visuals to enhance some content, to hide an appropriately positioned textual equivalent.

There's probably more useful stuff that should be here. I'm working on it. (Suggestions welcome!).

1. Typography

Not a lot going on here. Some obvious placeholders, plus a couple of classes I found myself needing over and over, which should be self explanatory (.win and .fail are applied to success or error messages; usually a form submission is involved).

/**
 1 Typography
**/

h1 {}
h2 {}
h3 {}
h4 {}

p {}
a { text-decoration: inherit; }
a:hover { text-decoration: underline; }

.note {
  font-size: 1em;
  font-weight: bold;
  text-align: right;
}

.wee {
  font-size: 0.8em;
}

.win, .fail {}


In typography, I strictly only include font stuff like faces, sizes, alignment, decoration and enhancements like text-decoration, font-weight.

2. Colours and borders

Border styles go here because they need to be defined before the border colours are. Otherwise, just colours go here:

/* Borders */
  .win, .fail { border: 2px solid; }

/* Dark */
  .dark { color: #2d2d2d;}
  .dark-bg { background-color: #2d2d2d; }
  .darker{ color: #000; }
  .darker-bg { background-color: #000; }

/* Primary Color */
  .color1 { color: green; }
  .color1-bg { background-color: green; }
  .color1-border { border-color: green; }
  .color1-texture { }

/* Secondary Color */
  .color2 { color: yellow; }
  .color2-bg { background-color: yellow; }
  .color2-border { border-color: yellow; }
  .color2-texture { }
  
/* Tertiary Color */
  .color3 { color: red; }
  .color3-bg { background-color: red; }
  .color3-border { border-color: red; }
  .color3-texture { }

/* Light */
  .light { color: #ccc; }
  .light-bg { background-color: #ccc; }
  .lighter { color: #fff; }
  .lighter-bg { background-color: #fff; }

.note { color: silver; }

.win {
  background-color: #E6EFC2;
  color:#264409;
  border-color:#C6D880;
}

.fail {
  background:#FBE3E4;
  color:#8a1f11;
  border-color:#FBC2C4;
}

After border styles, I start with the colour scheme, creating classes for text colours, background colours and border colours. It's unusual to need to go beyond a tertiary colour, and typically I only have primary and secondary. This leaves me with classes I can apply to any elements in my html templates, making it really quick and easy to experiment with different colour combinations. The color*-texture classes come in handy when I have textured backgrounds that match the colour scheme, and would include the background image (a repeating square of noise texture for example) and a background-colour as a backup.

Most of the time I don't want to be applying classes to everything to add colour though. I list elements that I'm confident aren't going to change in the mark-up which need colours applying to them, for example:

/**
    2 Colours and borders
**/

/* Primary colour */
  .color1, body { color: green; }
  .color1-bg, nav, footer { background-color: green; }

/* Secondary Color */
  .color2, nav { color: yellow; }
  .color2-bg, body { background-color: yellow; }

/* ...etc... */

I'm a fan of using off-white and off-black, so these are what I originally picked for my .light and .dark classes, which are always handy to have. Sometimes pure black and white are necessary too though, so the .lighter and .darker classes were born.

You can see .note, .win and .fail show up here too.

This pretty much means this is as long as the colours section will ever get. I don't apply colours anywhere else in the stylesheet, and it helps to ensure I stick to a colour scheme and don't get carried away with exceptions. Obviously, this also makes it super easy to change the colour scheme uniformly in a couple of seconds.

3. Spacing and grid

As I already mentioned, I have poked around with some of the existing flexible grid frameworks but none of them grabbed me. They all seemed to have too much. The minimalist system I came up with has answered all of my needs so far, although I wouldn't claim it's suitable for _every_ project in the world. It's also subject to tweaks, depending on the project of the moment.

I stick with Initializr's .wrapper class, which is 100% width until the viewport reaches 1024px, when it snaps to 900px wide. This is my default because it's been the most frequently appropriate so far. I have an ongoing project at the moment where the target audience are largely gamers, so capitalising on the excessive screen real estate they'll probably have means I stripped out this restriction in favour of a full width multi-column layout when the device allows.

I haven't yet had a need to go above five columns for my grid. I express my class names like fractions, and start off with only the 1/2, 1/3 and 2/3 ones taking up the correct proportion of the screen, with the others defaulting to 100%. This then changes for wider-than-small viewports, as you can see.

There are a few navigation list related things in there that I often find myself duplicating across projects (like a default centre-aligned stacked menu which progresses to a floating horizontal version). I pad my a elements (as opposed to their containing li elements) to enlarge the touch area for links. Plus some nth-child stuff for three column layouts, for keeping consistent row heights when the column heights are different.

/** 
 3 Spacing & Grid
**/

.wrapper {
 width: 100%;
}

/* Grid */
.w1of2 { width: 50%; float: left; }
.w1of3 { width: 33%; float: left; }
.w2of3 { width: 66%; float; left; }
.w1of1, .w1of4, .w1of5,
.w3of4, .w2of5, .w3of5, .w4of5 {
 width: 100%;
}

.inner {
 padding: 1em;
}

nav {
 max-width: 100%;
}

nav a {
 display: block;
 padding: 0.8em;
}

.inline { display: inline; }

.win, .fail {
  padding: 0.2em;
  display: block;
}


/* 3.1  */
 @media screen and (min-width: 479px){
  
  nav li { float: left; }
 }

/* 3.2  */
 @media screen and (min-width: 768px){
  .w1of2 { width: 50%; float: left; }
  .w1of3 { width: 33%; float: left; }
  .w1of4 { width: 25%; float: left; }
  .w1of5 { width: 20%; float: left; }
  .w2of3 { width: 66%; float: left; }
  .w3of4 { width: 75%; float: left; }
  .w2of5 { width: 40%; float: left; }
  .w3of5 { width: 60%; float: left; }
  .w4of5 { width: 80%; float: left; }

  .w1of3:nth-child(odd) { clear: none; }
  .w1of3:nth-child(3n-2) { clear: both; }
 }

/* 3.3  */
 @media screen and (min-width: 1024px){
  .wrapper {
   width: 900px;
   margin-left: auto; margin-right: auto;
  }
 }

Everything that goes in this section is to do with spacing: padding, margins, positioning, floating, wrapping... et cetera.

4. Images and video

Most projects call for tweaks to images that may or may not fit into the other sections of the stylesheet. Nonetheless, my brain copes better with I group them all together. Flexible YouTube video embed lives here too.

/** 
 4.0 Images and video
**/

.vid-holder {
 position: relative;
 padding-bottom: 56.25%;
 padding-top: 30px;
 height: 0;
 overflow: hidden;
}

.vid-holder iframe,  
.vid-holder object,  
.vid-holder embed {
 position: absolute;
 top: 0;
 left: 0;
 width: 100%;
 height: 100%;
}

/* Full width images on bigger than small screens are dumb. Reset this. */
@media screen and (max-width: 478px){
  .w1of1 img, .w1of2 img, .w1of3 img, .w1of4 img, .w1of5 img,
  .w2of3 img, .w3of4 img, .w2of5 img, .w3of5 img, .w4of5 img {
    width: 100%;
  }
}

And that's what I start all projects with. Here is it all assembled, with a few of the classes throw into the mark-up so you can see what's going on. If (when) I end up doing another major update, I shall probably write about it again.

Sunday, May 13, 2012

[ICP] UI for IF


This is the first in an upcoming series of posts about my final project for my MSc by Research.  For those who don't know, my programme is Interdisciplinary Creative Practices, or ICP for short, and my main focuses so far have been on Interactive Fiction (IF) and the Web.  My final project needs a log book.  Traditionally such a thing would be compiled by me at the last minute based on notes scattered around my workspace, emails to myself and entries on Google Calendar and Tasks.  It's high time I got a grip on my organisation and did this properly, so blog posts tagged "icpLog" will help me keep a proper track of ongoing thoughts and progress.

For my final project, I endeavour to create in a "location-aware Interactive Fiction engine".  If at this stage you don't know what IF is, read this nice description by Emily Short.

Historically IF is programmed using one of several specialist languages along with specialist software packages.  The one I am most familiar with is Inform 7, a brilliantly simple but incredibly powerful natural language.. language.. which is perfect for non-programmers who want to create IF.  I haven't actually made anything myself with Inform yet (I plan to, in the name of research), but I have read a lot of source code and tutorials.

Similarly, IF is traditionally played/read on a user's computer, in their local environment.  The open source JavaScript IF interpreter, Parchment, brings playing IF to the Web; much more flexible and shareable, and enabling of many possibilities.

One such use of Parchment can be seen in Playfic, which appeared around March this year.  Playfic offers a fully in-browser Inform development environment for authors, similar to the Inform software the experienced would be used to running on their own machine.  And of course, an online read/play interface for the IF consumers.

This interface affords the user the chance to share their work-in-progress with the IF community.  The source code for all of the games can be viewed, making it really easy for newcomers to learn how to get started, and for anyone to figure out how a particularly creative experience or interesting quirk has been achieved.

One of the aims of my project when I laid out my ideas last October was to lower the entry barrier for prospective new IF authors.  Having spent several years weaving in and out of technical and non-technical environments or groups of people, it's plain to see that even Inform might be daunting to some.  Whilst it appears like uber high-level natural language to us programmers, for a writer, things like verbose if statements, oddly structured sentences and repetition of logic that would be inferred by a human from just a few words, can be pretty alien.

In other words, the programmer in me looks at Inform source code and sees prose; no complex syntax to remember, and logical and basic programming concepts.  The writer in me doesn't see prose; she sees awkwardly formed statements and struggles with maintaining the fluidity of a story whilst attempting interlace it with conditions and behaviours of things.

I'm sure if they work together, they can figure something out.

But more importantly, I'm sure my creatively split personality can offer some useful insights when it comes to designing my own online interface for IF authoring.

During a few weeks in April this year, I built the first iteration of Palimpsest, as my project is so named, around the requirements of some folk from the University of Edinburgh's English Literature department.  Concentrating on the 'location-aware' part and ignoring the 'Interactive Fiction' part, the current alpha allows the author to input bodies of texts and allocate them areas on a map.  The user, upon starting a particular 'experience' on their smart mobile device, could wander around a particular area and have these texts dynamically pushed to them, to read in the surroundings intended by the creator.  English Lit. are using this to deliver historical and contemporary literary works written or set in Edinburgh, as part of the celebration of 250 years of Edinburgh literature.  There's more work to be done for them before it meets all of their specifications, and it'll be premièred during the summer.  I built it on Google AppEngine with Python and jQuery and at the time of writing anyone can sign in and create an 'experience' for their own city, at http://palimpsest.rhiaro.co.uk.

It's time for the project to branch, as I must turn my attention to the IF side.  I will be pondering the source code of Nick Montfort's Curveship for inspiration about processing user input (one of my initial ideas was to adapt Curveship itself to add the location-aware aspect and a Web interface, but the complex narrative stuff that Curveship does goes waaay beyond my needs, and I think that would end up being more complicated than starting from scratch).

I will also be filling my flat with paper sketches of user interfaces for the authoring of Palimpsest works.  I need ways to model characters (playable and non-playable), locations and connections between locations (shouldn't be too hard, as this will be based on the real world), objects and their properties, and interactions with objects and characters.  I have so far concluded that I need a system of actions and consequences; I should be able to apply this to everything.  Most importantly, I need to a user to be able to input this information as if they were writing a story.  Obviously there will still be some differences; it may be a disjointed story, spread across a series of input fields.  But there won't be any degree of programming syntax, or unnatural prose.  The system needs to do that work, and help the author to put the right information in the right places to allow this.  For the programmatically-inclined, we could perhaps consider the writing of a traditional story (novel, etc.) as procedural writing, and the writing of a Palimpsest interactive piece as object-oriented writing.  Maybe.  We'll see how that analogy holds up as the project progresses.

In terms of functionality, all that I'm really changing compared to regular IF is stripping out the directional commands - north, south, east, west, and alternatives - and replacing them with physical movement.  The system will know where the rooms in a particular story are on a world map, and the wonderful HTML5 geolocation API will know where the player is (once they've given permission for Palimpsest to track their device).  I've already done this.  It works.  There are varying degrees of accuracy.  If you're in a building, you're looking at between fifty and two hundred metres of accuracy, depending on your device.  Outside, I had it accurate to three metres, and the average was five to ten.

Now all I need to do is... everything else.  The idea of building an IF engine from scratch is pretty daunting, especially given the huge complexity of actions people can squeeze out of languages like Inform.  Palimpsest will have nowhere near these capabilities, not at this stage, and I need to remember not to get hung up on that.  I'll probably leave out scoring, and whilst saving progress is a must, 'undo' won't be a priority.  With Inform you can create random events and complex algorithm-based behaviours of objects and characters.  That's not going to happen for Palimpsest this round.  I also can't shake the nagging inferiority I feel thinking about the usefulness of the Inform development environment in letting you visualise paths through your narrative to check for bugs and dead ends.  My subconscious will be working hard on a solution to that, but I can't hope too hard for it to be an outcome of this stage of the project.  Based on the actions-consequences idea, it would probably be feasible to generate a flow chart of some kind to help an author fish out paths through the narrative that don't work.

As anticipated, writing this post has helped my brain spin into ideas mode.  Likely before the day is out, I will post again with some doodles and diagrams and a more solid idea of how to make this UI work.

Comments, questions and suggestions welcome.

Thursday, December 15, 2011

Interdisciplinary Memories

tl;dr - My MSc group made an art installation. Me? Art? Shocking, right. I've formed some new ideas and opinions, and had lots of fun in the meantime. Photos coming soon.

This semester I have been one fifth of the brains behind the ICP Group Project. Our brief was essentially to make something between us by December. There's quite a lot of scope there. The fact that we're working out of the College of Art probably also leant a few assumptions to what the final outcome should be.

When we started this adventure, I was still coming to terms with the notion that not everything needed a distinct purpose to be a valid contribution to society. What I mean is, whilst I understood the concept of art in principle, I still couldn't quite align the idea of art for art's sake with my view of the world. During the seminars, research and discussions of the past few months, things like the value of play; the possibilities opened by beginning research without a clear goal; the emergence of new ideas by unfocussed exploration; have all started to round out an initially biased view of the area in which I am now studying.

Don't get me wrong. I'm still not going to look at an unadorned mirror on a wall, labelled 'Untitled', and nod my head and make thoughtful noises about the meaning of identity. Some 'art' is just plain silly.

But I'm willing to take a little more time to think about the methods and thought processes that went into creating something, and what might be the end result in addition to the physical outcome. It's likely that I'll still be more of a fan of art that was created to raise awareness, to provoke thought, or to explore innovative uses of new media or technology. But art that was created 'just because' will get more of a chance in my books now than it might have done three or four months ago.

Being part of this kind of creative process no doubt influenced my altered perspective. We started the semester as five strangers: Katherine, literature; Tina, video editing and broadcast; Agnese, musical theory and graphic design; Liz, sociology and prettyful artsy things; and myself, that new fangled Interweb nonesense, and writing. We have grown into unit, mish-mashed our skills, learnt a whole lot from each other, and been fed extensively by Liz. It has been noted on a number of occasions how well we all gelled from the start. Thus the 'group' part of the group project produced no problems at all. That just leaves the 'project' part...

So at the start, when notions of an 'installation' or 'performance' were thrown around, I was almost horrified. The open nature of the project left us so much scope, we could pool our skills to do something truly useful or revolutionary. I didn't want to just 'make art'. My head was still in the computing world where the goal is always to make something that people will use, or that will be informative, or influential; that will reach people.

I wasn't completely close-minded, obviously. I went with the flow, as I am wont to do. And in doing so, I learnt much.

It was swiftly decided that 'memory' would be a suitable topic to explore for the group project. We start taking photos of our group meetings in case we could incorporate a super-meta aspect but we forgot quite quickly to keep this up.

Our goal became an installation, which was exhibited at Inspace on the 13th of December. Photos coming soon! This consisted of four boxes, metaphors for memory, and a wall hanging, each intended to explore a different aspect of the elusive theme. We ended up with Woven Memories (Liz's beautiful wall hanging), Spatial Memories (Katherine look at historical memory stores), Digital Memories (guess who), Tidal Memories (Tina's view on the insubstantial nature of memory) and Fluid Memories (Agnese's investigation of social nostalgia). Upon opening each the four boxes, projections trigger onto surrounding walls, enveloping the visitor in the work.

Although I had an idea of wanting to use social media as part of the project, it was Katherine's idea of physical records of memory (memory spaces) that particularly inspired my approach; this prompted me to think of how in the present day a subset of this is virtual memory spaces. An initial idea was to join Katherine on one of her photo taking expeditions around Glasgow and whilst she took photos of physical memory spaces, I would check-in to them using Foursquare, creating a connection between the historical physical and the contemporary virtual. Other commitments meant I was unable to go to Glasgow on the date planned, unfortunately, and this idea wasn't pursued.

Having decided that we would each dedicate something physical to the aspect we had chosen to consider, I sourced a box, RAM and old maps and was pleased to entrust the decoration to Liz who is far more proficient at making things pretty than me. (I absolutely loved the outcome).

Tina and I applied our technical abilities to learning the basics of Max/MSP and how to use Arduino boards. I am particularly pleased about our decision to make the installation interactive; I learnt a lot and a door that I didn't previously know the location of has now been opened to me. The use of Arduino stuff is something I will definitely investigate further in the not-too-distant future.

I knew not to be too prescriptive from the outset, as what I was building would evolve as I discovered things I could and couldn't do. I dropped Foursquare for the final outcome because the output wasn't that interesting, and concentrated instead on Flickr and Twitter. I went through several iterations using different methods to try to get around various limitations of the Google Maps API. Eventually I settled on the jQuery plugin GMap3; although I still hit a few stumbling blocks at the last minute that I had to botch around because of time pressure (using an AppleScript to refresh the page was not the most elegant of solutions, but the JavaScript just wouldn't work. It didn't make sense, I swear. It did, however, introduce me to AppleScript for the first time, and the power that lays behind that...).

The aesthetics of the thing could have done with a bit more work, but the amount of time I had to spend getting the script to technically work meant I was left with much less time and energy to focus on the appearance than I would have liked.

Last minute problems with hardware meant that we had to lose the interactive element of my box (mine was the last one we were due to wire up). This is in part what encouraged the change of location of my projection, however, and I think it was far more effective beamed on the floor than it would have been projected onto a wall. Plus, having it triggered and hidden by the opening and closing of a box seems unnecessary, and perhaps counter intuitive in hindsight, as during the exhibition people would watch the activity on the map for extended periods of time.

I enjoyed working on a project where artistic intention was more important than code quality, and a final outcome was not strictly defined. This gave me flexibility to explore and work outside of the scope of computer science boundaries that I'm used to. Though obviously creative thinking and outside-of-the-box solutions are highly encouraged in software development fields, there is certainly an underlying rigidity or 'way of doing things' that is absent when applying such technology in an artistic context. And if I do end up back in the 'official' computing world, I'm certain that the kinds of experiences I gain during ICP will massively enhance my skillset as a creative developer.

You can check out what I projected here. This has only been tested in Chrome - I cannot be held responsible for irregularities that may occur using other browsers :)

It's worth noting that there are some truly wonderful people who gave up their time, resources, advice and patience to help us out during the project. Couldn't have done it without them!

Et, voila:

Remember When..?

I'll link some more photos asap...

Monday, October 31, 2011

Nanowrimo: Pre-madness

I've never sat up and counted down to the first of November before.

In 2007 I used Nanowrimo as an opportunity to kick myself into writing some more of a novel I started many years ago (reaching 35k new words by the end of the month) and in 2008 I took part in earnest, came up with a totally fresh idea the night before and hit the fifty thousand, two hundred and twenty ninth word of Milo's World before midnight on the 30th. It was, quite simply, the best feeling.

In both 2009 and 2010, my degree objected strongly, and I didn't even try.

This year, I know what being too busy to take part feels like, and I know what missing out feels like. But I also know what taking part feels like, and I know what winning feels like.

This year, I'm writing an old idea in a new way. A short story from around 2007 sparked novel scribblings in 2009, which got left to fester. Looking at these scribblings with eyes two years older, I plan to take the core concept and solidify it into something readable.

That's the theory, at least.

I'm terribly excited about creating some new lives. Then destroying one of those lives, and watching the effects cascade.

I'm mostly nervous because I've never written anything set truly in this universe before. Fifty percent of Milo's World was, and that fifty percent was from the point of view of a child with an enormously vivid imagination, so that doesn't really count.

A good chunk of Currently Untitled will be set inside the main character's head; a head which is subject to the physics and realities of this universe regardless of how much her mind tries rebel against them.

Her name is Harriet, by the way, and her little daughter is Rosy. I'll probably tweet about them as real people, because for the next 30 days, they might as well be. Rosy's dad is called Zeke, and Harriet's inconsequential boyfriend's name is Paul, as far as I know. I'm also aware of the existence of Patrice, a panda with an eye patch, and Arthur, a tiny penguin.

I'll probably post some extracts here. But I can't post daily progress, because of various linearity issues that I may or may not elaborate on in time.

But now, I'm going to stare at the counter on the front page of the Nanowrimo site, and try to figure out that first line...

Saturday, October 29, 2011

Spells wear out

One of the first lessons Turald learned during his time at Castle Qythe was that spells wear out. They weaken, they lose their power, the more they are used. They were all taught this, he and his classmates, probably in their very first week of study. But few eight year olds take this kind of wisdom to heart. Most are keen to crack on with casting, and nobody thought to question why some of their oldest tutors never demonstrated even the simplest of enchantments.

For as long as he could remember, Turald had loved to explore dark places. He loved to see what was out of sight; to make known the unknown. When he was fifteen, he discovered a whole section of the castle's cellars that had been lost for centuries. To the delight of his wizened mentors, the expanse he found was filled with age-old liquor which had been promptly and enthusiastically excavated. It was from then that his freedom had been unofficially granted to roam and explore the castle grounds as extensively as he saw fit. Recognising his gift for discovery, Turald's studymaster, the ancient but sprightly Professor Chalmak, quietly overlooked Turald's disregard for out-of-hours and restricted-area rules that were strictly imposed upon the other students.

In a broom cupboard, Turald once found a mousehole that lead two hundred metres north and seventy four years into the past. One of the seniors had been able to use this to make peace with a long-dead, estranged father who had been in that classroom, all those years ago.

In the shadowy corner of the library marked 'secret', Turald had found the headmaster's daughter, missing for over forty years.

In a tunnel that he had found through crawling into a large oak chest, Turald uncovered a delicate glass vial containing the last breath of the first philosopher.

When Turald realised that his elders thought him special for his findings, he began to keep a diary of them. Through his diary entries, he noticed patterns in his actions. Or rather, repetitions. The shedding of light was the key. Illumination was all he needed to do to bring something once hidden out into the open. His ability to conjure just the right incandescence became his greatest gift. Thus, he practised with vigour.

Caves, caverns, abandoned ruins: Turald devoured their secrets, consumed their stories. He exhausted the castle grounds, graduated from the Qythe Academy, and ventured forth into the Olde Lande, searching without hesitation for doors to throw open. Eyes aglow with his own special kind of vision, he absorbed the mysteries of a world in shadow.

But spells wear out.

He recalled this first in a forest, under a bristling canopy so thick that the blackened foliage groping at his legs had long since found ways to sustain itself that did not rely on the land's pale sun. He could see the trinkets that had been stowed away by blind magpies in treetrunk nests; the hoards of stolen food secreted into the undergrowth by milky-eyed squirrels. And then, he couldn't.

The flicker in his vision was fleeting, but enough to panic Turald, just for a moment. Enough to make that first ever lesson come rushing back. Still young, still adventurous, Turald shook his concern aside.

Deeper in the forest, he found a well; a man-made hole into the earth, darker even than woods entombing it.

Why had man built such a thing so far into the shade? Turald could not resist.

He descended, uncovering a concealed tunnel with his brilliant sight. Time having vacated entirely, Turald followed the route that stretched before him. No magic nor mystery, nor hidden treasure presented itself, and the rhythm of his steps lulled him into a trance. He walked blind for many hours before he realised he was doing so.

A droplet of water striking the tip of his nose roused him enough for him to realise he saw nothing. Turald stopped. The sudden lack of motion was jarring, dizzying. Turald sat. Water seeped into the hem of his robes, and he sat. Years of advice, words of warning, from teachers, mentors, elders, echoed through his mind.

Spells wear out.

Spells lose their power. Lose their potency. Lose their meaning.

Save the important spells for when you need them the most. Best to leave this world with a spell in your heart, than to leave it because your spells have run out.

Turald's light had run out, so he sat.

Thursday, October 06, 2011

Interactive-Bliction: > Investigate door.

> Investigate door.

Your eyes are drawn again to the marks on the small door, and you squint, taking a tentative step forward. A small cloud of powder rises around your foot, and a floorboard creaks. The creak is low, and to you, sounds welcoming. Like the house is inviting you in.

Encouraged by this, you continue. You have to watch out for the things cluttering the floor, and step carefully around an upturned plastic chair. That obviously wasn't part of the original décor, and despite the heavy coating of dust, you assume it must have been left by the documentary crew. Your foot clacks against something heavy.

> Look at floor.

The dust makes everything the same dark grey, but there are distinct shapes that you can see. Several small plastic chairs are visible, laying on their sides or with their legs pointing into the air. A standing lamp with a wide shade has fallen over at the foot of the stairs, to your left. There's a knee-hight rectangular box against a wall to your right, with what looks like a padlock hanging from the front, and beside it lie pieces of a large and once-ornate vase. At your feet is something long and narrow, and a glimmer of metal peeks through the dust. When your foot made contact, it felt pretty solid. You kick it again to roll it over, and dust peels away to reveal a brassy candlestick holder.

> Take candlestick holder.

You pick up the object, about half the length of your forearm. The metal is cool, but surprisingly not cold. Feeling like you need a souvenir, you tuck it into your coat pocket, and continue to pick your way across the hall.

> Inventory.

In your coat pockets you have the candlestick holder, half a bar of Dairy Milk, and the keys to your flat. In your trouser pocket is your mobile phone, which is turned off so your friends won't disturb you, and some change.

> Investigate door.

The small door is in front of you, and to your left is the sturdy looking bannister that runs up the side of the staircase. You could touch the bannister and the wall to your right at the same time, if you stretched out your arms. It's harder to see because you're no longer in direct line of the light from the entrance (which you left open), but you lean to inspect the front of the door. Cobweb trails curl around your finger tips as you run your hand down the dark wood. You can feel carvings on the surface, and blow and swipe at the dusty layer until the patterns are no longer so obscured.

You suppress a splutter at the thick and itchy air you're breathing. Some of the shapes carved into the door feel like cogs, but there's something else as well. Something winding, with a shape more organic. You only wish you could see all of the details.

Your wandering hand finds a wooden protrusion at waist height, and you try to turn the handle. It moves stiffly, but the door itself doesn't budge. Carefully, you lean your shoulder against it and push harder, but to no avail.

> _


[What do you do next? Comment!]

Wednesday, October 05, 2011

Fiction: The Hero of Monarar

[February 2009]

“Ours is but a small existence. We are but simple people. On this planet of ours, superheroes were but stories. Until today. We are gathered here to give thanks to the new Hero of Monarar, the almighty Ora. No-one knows from whence he came or where he goes. No-one knows how it comes that he moves so fast, predicts events with such precision. No-one knows why he has no tail, why his skin is dark, why his ears are sideways on his head. But it is to him we owe our utmost gratitude. It is he who freed us – who will continue to free us – from those that seek to imprison and enslave.

“We must support him as he travels our planet, rescuing villages, saving families.

“Here is to Ora the tailless, Ora the Hero of Monarar!”

The applause was deafening.



“Why didn’t I take the gloves?” Ora mumbled to himself. The rock was grazing his palms as he scrambled up the near-vertical cliff face.

“Because you’re a moron,” replied his subconscious. “Oh, I won’t need gloves. It’s not like I’ll be going anywhere cold, or, or doing any climbing. Moron.”

“Shuddup,” Ora spat. “Either shuddup or get out of my head and help, why dontcha? Huh?”

“Hows about you keep climbing, how about that? Oh, watch out.”

The blast of a laser smacked into the rock an arm’s reach above his head, and Ora ducked in time to dodge the heap of dislodged stone that tumbled down onto him.

“Oh some sixth sense you are. Warn me about a laser blast that’s already hit the rock. Nice work.”

“I warned you! It didn’t hit you, did it?”

“Waste of good coin you were. ‘Revolutionise your life’ my rear end. Just a pity you don’t come with a mute function,” Ora continued to grumble as he climbed. His subconscious reluctantly helped guide his limbs, warning him before he put his weight on unsteady outcrops, or grasped at stones that were not well attached to the surface, and occasionally to hesitate in time to avoid the lasers of those that were targeting him.



In the village, children were crying for their mothers. Mothers they could see, but not reach. A wall of men with guns divided the room into three sections; one for the mothers, one for the boys and one for the girls.

The men had once been fathers, husbands, sons, but now were faceless, armoured robots, unrecognizable to the ones they had once loved. They were hardly men at all.



Two days ago, Millsy and her brother had been collecting berries on the outskirts of the village. Her brother had paused for a rest, falling asleep by a bush beneath the warm, afternoon sun, and Millsy had wandered off alone, in search of adventure.

As she skipped further and further from the village boundaries, her mother’s words had begun to echo through her mind.

“Stay together when you’re out now. When you’re on the edge of the village, always keep one eye on the horizon. Keep a lookout, and if you see them coming, you run back and warn us all so we can get ourselves hidden, you understand?”

No-one had bothered to explain to Millsy exactly who them was, but she had caught enough glimpses of the news over the past few weeks that she knew that village after village on her tiny planet were disappearing off the map.

Her brother said it was invaders from outer space, and that had scared her until he had pulled her tail and run away, giggling “no such thing! No such thing! Millsy believes in aliens, there’s no such thing!”

And so despite her mother’s warnings, Millsy wandered away from the village, encouraged by her childish confidence that there were no alien invaders, and so nothing could be coming that was a danger.

When she saw the lights on the horizon, she stopped to watch. Darting, flashing beams. Bright colours, sparkling, glimmering, dashing through the sky and across the ground. Her neck craned farther and farther back as she watched those in the sky. Soon they were above her and surrounding her. There were straight flashes, like lightning; curling spirals of colour; pulsating circles and tiny pinpricks in the sky.

They overtook her, and Millsy spun around at once, chasing them back towards the village, not wanting to miss out on the display.



“You still haven’t justified why I paid so much for you,”

“Duck – incoming, eleven o’clock. Because I’m the best. There are no other warning systems like a sixth sense.”

“So far you’ve just been an annoyance.”

“Oh, and all those laser blasts, you could have dodged without my help?”

“I wouldn’t be here at all if it wasn’t for you. I’d still be enjoying myself on the Fourth Moon of Rasta.”

“You’re blaming me for your insatiable need to try new, mind-altering technologies? It’s my fault that you got me installed in the first place? And where… Not that one, it’s loose. And where did you get me installed, again?”

Ora mumbled.

“What was that? A back alley in Rasta’s infamous Flea Market? I’m certain you only have yourself to blame if I’m not what you expected.”

Ora growled. “Look, are we nearly at the top yet?”

“Not too far now.”

Then the device attached to his belt began to beep slowly, and Ora smiled. “Right you are.”

The beeps became more high pitched and more frequent as he continued to ascend. The relief was enormous when he could finally see the top of the cliff.



Millsy was whimpering alongside the others. She could see her mother across the room, but her brother was not to be found, and this upset her more.

A small arm snaked around her shoulders. Her best friend, Lella.

“Don’t cry Mills. You believe in the Hero of Monarar, don’t you? You know he will come to rescue us. He’ll set us free and put the men right again, just like he did in the other villages. It was on the news, my Mummy said. You’ll see.”



“How many more do I need?”

“Just one.”

“Really?”

“Yes, really. But what am I, your secretary? You shouldn’t rely on me to know these things for you, I’m an extra sense not more memory.”

“Well you might have to start learning to be memory, it’s a damn sight more useful than whatever else you do, and I’ve already gone over the maximum safe number of extra memory installations I can have.”

Ora heaved himself the last few inches of the climb and rolled over the ground at the top, breathing heavily.

“Move a foot to the left.”

He obeyed at once, rolling out of the way of yet another laser blast.

“Haven’t they given up yet,” he grumbled.

“Apparently not,” replied his mind. “Maybe you should find some shelter while you work out where the next device is.”

He pulled out his frantically beeping scanner. “Whatever, it can’t be far.”

Ora stood up, trusting his sixth sense to warn him of any more incoming lasers, and scanned the landscape. He could see buildings in the distance.

“Looks like they’ve got a fireworks show or something going on over there like at the last place. For a backward developing planet, they sure are celebrating a lot.”

“You should run,” suggested his subconscious, and Ora complied.



“Of all the planets to crash on, I not only hit a backward one, but a backward one that keep their nuclear cells inside yooge great fireworks machines.”

“Did it occur to you that the cells might be powering the fireworks machines?”

Ora was lying flat on his belly beneath what appeared to be a carpenters workbench. The workshop had apparently been cleared out – equipment heaped carelessly against the walls – to make room for the enormous multi-faceted machine in the centre. It was shooting out streak after streak of light in every direction. The beams rebounded off walls and furniture until they escaped through windows, or through the increasing number of holes in the walls.

The machine was slightly translucent, and Ora could see the power source he needed behind a series of hinged flaps leading to the heart of the thing.

“Here we go again.”

“You shouldn’t steal.”

There was a pause.

“Sorry,” said his subconscious. “Still a bit of official programming in me. I’ll work on it.”

Ora rolled his eyes and began to creep forwards. He had ordered a fully stripped down version of the sixth sense; it was all very well programming morals into mindware, but it didn’t half screw them up in conflicting situations.

A number of the women leapt to their feet, squealing and crying as the not-men moved to surround the small huddle of boys. The terrified lads were ushered to stand and guided slowly out of the room. The mothers wailed, pushing against the unmoving wall of men as they tried to reach their children. The boys themselves were silent, too terrified even to cry, panicked eyes staring back for one last time at their mothers and sisters before they were lead across a courtyard to the carpenters workshop.



“There are people coming.”

Ora froze. He had got through two of the compartment doors – there were just two more layers between his hand and the nuclear cell. His fingers brushed the third door, searching for the minuscule lock.

“I can do this. I can’t stop now.”

“It’s too late for you to hide now. But they won’t see you from the doorway. Just hurry.”



The first boy was pushed in front of the machine. He stood there, trembling, staring up at the dark, hulking construction. It was spewing sheets of light from every surface. Ora could roughly make the lad out through the semi-transparent innards of the machine. Nothing else seemed to be happening as Ora scrabbled frantically with the third lock, breaking it, reaching further in to move on to the fourth.

The boy flinched as a rebounding streak of light hit him in the chest. Ora did not see the child crumple to the ground, or begin to twitch as plates of armour appeared from nowhere, sliding themselves over the small limbs. The boy became upright as the armour covered him. He was standing by the time a helmet grew over his head. Then he walked stiffly, as if controlled by strings, to join the ranks of the other not-men.

The next terrified child was pushed into position.

Ora had missed the entire transformation, squinting upwards with his tongue sticking out as he worked the fourth and final lock.

The lock broke, the door swung in, and he pushed his arm further into the machine, straining to wrap his fingers around the cell.

The second boy, hands over his mouth as he awaited his fate, caught sight of movement through the machine. He saw the hand in the centre, followed the arm back to a face wrought with concentration.

His eyes widened. “Ora, Hero of Monarar,” he breathed. The stories were true. The legendary hero was here, was going to save him, as he had saved so many others. The lad watched in awe as Ora’s hand closed around the heart of the lightning beast, and wrenched it directly from its body. The beast shuddered and died, spitting out a final few shards of light as it did so. The not-men crumpled to the floor, armour plates dissolving into nothing as they retransformed.

The boy cried in relief and turned to the others to tell them what he had seen – who he had seen.



“Leggit!” Shouted Ora’s both conscious and subconscious simultaneously, and the hero bolted out of the workshop, back in the direction of his ship.