Interactive Story Engine
FRISE is a small, MPL 2.0 licensed, Javascript program that let's you write interactive fiction and games directly in HTML -- the format of the World Wide Web.
FRISE games are played in your browser. Games can be hosted on a web site, or can be downloaded and played offline. To play a downloaded game, you just click on the HTML file to launch your browser and start playing!
You write games in your favorite text editor. Choose-Your-Own-Adventure stories are written directly in conforming HTML, without the need to learn a specialized story format language.
More complicated interactions in stories, such as remembering state, are achieved using standard Javascript.
FRISE comes will a small number of useful functions to help you.
An Example Story
Below is the code for an example game. The comments explain the FRISE features being used.
<!doctype html>
<html lang="en">
<head>
<title>An Example Story</title>
<meta charset="UTF-8" >
<link rel="stylesheet" href="frise/css/game.css" >
</head>
<body onload="initGame();">
<x-game><!-- Tags beginning with x- are valid HTML, FRISE makes use a small
number of these. The x-game tag goes around the game code. -->
<x-object id="main-character"><!-- Games can have many object's for people,
things, etc., but must have a main-character-->
<x-position>start</x-position><!-- x-position is used to say the location
of an object. The game always presents
the location of the main character.
For other objects, position is optional -->
<x-name>Frise Guy</x-name><!-- name to use when object speaks -->
<x-icon>images/frise_guy.jpg</x-icon><!-- icon used if an object speaks -->
<x-smile>Muted</x-smile><!-- Feel free to make up x-tags for other
attributes of your objects -->
</x-object>
<x-location id="start"><!-- An x-location tag is used to define a location --
somewhere an object can be -->
<x-present><!-- x-present tags are used to describe a location when
the main-character is there -->
<h1>The Adventure Begins</h1><!-- Notice how we can use
vanilla HTML in our description -->
<img src="images/fork.jpg" alt="A left road and a right road separated by
a giant stainless steel fork -- Made in Dall-E" >
<p>It is a dark and stormy night... You reach a fork in the road.</p>
<x-speaker name="main-character">Whoa! That's a big fork!</x-speaker>
<!-- x-speaker tags can simplify drawing conversations-->
<ul>
<li><a href="#right">Go Right</a></li><!--To create links from one
location to another
url fragments are used. I.e,
#right to go to location right
-->
<li><a href="#change-smile;left">Go Left</a></li><!-- We can also use
fragments to specify actions to
do before going to a location -->
</ul>
</x-present>
<x-action id="change-smile">
obj('main-character').smile = "Brilliant";
/* obj(some_name) is the syntax to refer to the object some_name
loc(some_name) is the syntax to refer to a loc.
x-action tags; otherwise, contain straight Javascript
Notice in the above we used .smile to refer to the smile property
we had defined with the x-smile tags earlier.
*/
</x-action>
</x-location>
<x-location id="right">
<x-foo>bar</x-foo><!-- Feel free to make up x-tag attributes for
locations too -->
<x-present>
<h1>Victorious!</h1>
<p>You, ${obj('main-character').name},
flash a ${obj('main-character').smile} smile. You win!</p>
<!-- $ {some_expression} is the standard format for Javascript string
interpolation of variables and expressions. FRISE let's you use it in
HTML x-present sections -->
</x-present>
<x-present ck="loc('right').foo == 'bar'" ><!-- the check must be
true for the text below to be presented.-->
Somehow though it felt too easy.
</x-present>
<x-present>
<div><x-button href="#reset;start">Restart</x-button></div><!--
x-button's are another way to make links between locations-->
</x-present>
<x-action id="reset">
game.reset(); // game is the Javascript name for the current game
</x-action>
</x-location>
<x-location id="left">
<x-present>
<h1>The Left Path</h1>
<p>The left path at first seemed very sinister...</p>
</x-present>
<x-present ck="clickProceed('And then...')" ><!-- a link must be clicked
for the below to display -->
<p>And then you, <input data-for="main-character" name="name">,
had a moment of personal growth and
traversing it became easier.</p><!-- Using the data-for attribute
input tags can be bound to values of object properties.
In the case, above the name property of the main-character. -->
<p><a href="#right">Until...</a></p>
</x-present>
<x-default-action>
/*
Default Actions are run for any object or location that has them,
once per turn
*/
if (obj('main-character').position == 'left') {
loc('right').foo = "left";
}
</x-default-action>
</x-location>
</x-game>
<script src="frise/js/game.js" ></script>
</body>
</html>
FRISE has built-in support for a side navigation bar, handling game saving, and more. Details can be found in the
Documentation .