Relative Fiction

A tool for creating dynamic stories relative to a reader's place, time and location (via the Foursquare API), weather (OpenWeatherMap) and more (custom feeds for recent news stories etc). Write stories that feel like they're taking place where the reader is, science fiction with dates and information that don't age and lots more.

Free and open source. Originally built in May 2015. Rebuilt in May 2017. Below are basic instructions, visit the GitHub repository for more (and to ask questions, report bugs, submit requests). Head over to the write page to give it a go yourself.

An example

Throughout this page you can tap the Localise buttons to see what a translation of the text would look like where you are. Then hit Reset to go back to the raw text.

I love {{dayofweek}}s. It was around {{hour12}}{{ampm}} on a {{dayofweek}} when I first saw its outlines. I was sitting in {{park}} and looking out at the sky. It was a {{weather}} day much like this one. Wings. Clearly a pair of wings. Floating somewhere towards {{supermarket street}} as if going about their everyday business. This month is even more special. It happened in {{monthofyear}}. So I walk over to {{park}} and look out. But there's never anything anymore...

How it works

A writer writes a story and at certain points, replaces static words like days of the week and place names with special placeholders or variables.

Alongside variables, writers can put in logic to show text if some statements are true and some other text if they are not.

{{#more (hour24) 12}} It was a {{weather}} {{dayofweek}} afternoon. Georgina was tired. {{else}} It was a {{weather}} {{dayofweek}} morning. Georgina was hungry. {{/more}}

Once a reader starts reading a story and agrees to share their location (longitude and latitude picked up through their web browser), all relevant data is collected and swapped out to make a story that is unique to that reader but still keeps the original essense of the story.

Data for places is pulled in from Foursquare, a wonderful place-based social network and directory. Data for weather and sunset and sunrise times is brought in from the kind people who run OpenWeatherMap.

Types of variable


To put a place in your story, a zoo or japanese restaurant for example, first look up the name of the category of place on this list of place categories from Foursquare to make sure it's available.

Next, enclose the name of the category in double curly brackets.

We went out for a few drinks at {{nightclub}} and somehow ended up naked and shivering in the waters of the {{river}}
You can add a space and a number like {{park 2}} {{park 1}} in order to fetch multiple parks and refer to them. The locations will get swapped out by the location of that category nearest to the reader.

Other information about places

You might want to use other information about a place, like the street it's on or how far away it is from the reader.

He lived on {{park street}}. I never liked that part of town after what happened to Emily.
Putting the word "street" after the pipe will get translated to the street the venue is on. Parts of street names containing numbers are stripped out (11,33b...). If there's no street set it defaults to "some street".
She arranged to meet me at {{zoo}}. For some reason she never wanted to see me more than {{zoo distance}} meters from an animal park.
Distance in meters from a reader's location to a place. Useful for conditionals like if you want to find out how far someone is from the sea.
I love coming back to the smell of {{park city}}. It reminds me of that night in {{chinese-restaurant}} all those years ago.
The city or town the venue is in. Defaults to "some city" if the venue doesn't have one set.

Other variables

It's not just places you can swap into text, here are some other variables you can use.

It was {{dayofweek}}. She always came round on {{dayofweek}}s. Yesterday would have been better. {{dayofweek minus 1 day}}s were always better than {{dayofweek}}s.
The day of the week. Monday, Tuesday... etc. You can add and substract from times and dates.
{{hour12}}{{ampm}}. If only I had set my alarm to {{hour12 minus 2 hours}}:{{minutes add 30 minutes}}{{ampm minus 1 hour}}. It may have saved my life. The dial read {{hour24}}:{{minutes}} and it was over.

It was {{monthofyear}}. Five years after they caught the fish. I still have the newspaper cuttings from {{monthofyear}} {{dayofmonthsuffix}}, {{year minus 5 years}}.

{{longitude}},{{latitude}} said the screen. This was the right place. It's what it said on the paper. But my instinct told me {{country}} wasn't even the right part of the world.
Longitude and latitude for those who need it. Also a country code.
It was a {{weather}} day like this one when my ears stopped working. Humidity was at {{humidity}}%, it was {{temperature}} degrees celcius and the wind speed was {{windspeed}} m/s.
The reader's current weather. This can return one of the following values: stormy, rainy, snowy, clear, cloudy, calm, windy, scorching, freezing. You can re-write them using conditionals. Windspeed, humidity and temperature may also be useful.
It could only happen exactly at sunset. {{sunsethour24}} hundred hours. That was {{hourstosunset}} hours away.

It could only happen exactly at sunrise. {{sunrisehour12}}o'clock. That was {{hourstosunrise}} hours away.
Sunrise and sunset times are useful for conditionals to get day and night values.

External feeds

Relative Fiction supports XML feeds (RSS extra) and JSON feeds for you to customise your story. This is super powerful.

Getting the contents of a website

Use the url tag to print the contents of a url you pass in. This is a bit useless on its own but you can use it in contains queries (see conditionals below) like:

{{#contains (url "") "goat"}}The Wikipedia front page had goats on it.{{else}}There were no goats on the Wikipedia front page.{{/contains}}

Processing XML and JSON feeds

The xml and json tags are block tags so they come in opening and closing pairs. That's because they return lots of data rather than just one thing. Anything possible in the Handlebars template library (see the Handlebars docs) is possible within the block so you can do conditionals and more based on anything in the fetched data. The following example gets the 1st top news story from the UK edition of BBC news.

I turned on the TV at {{hour12}}:{{minutes}}{{ampm}}. The news read "{{#xml (url "")}}{{channel.item.[0].title}}{{/xml}}".


This bit is slightly more complex so head over to the documentation on GitHub. You have {{#more}}, {{#less}}, {{#equals}}, {{#not}}, {{#or}} and {{#and}} to play with.

{{#more (hour24) 12}} It was a {{weather}} {{dayofweek}} afternoon. Georgina was tired. {{else}} It was a {{weather}} {{dayofweek}} morning. Georgina was hungry. {{/more}}