diff --git a/Gulpfile.coffee b/Gulpfile.coffee
index 6cae8a9..b452c44 100644
--- a/Gulpfile.coffee
+++ b/Gulpfile.coffee
@@ -86,6 +86,7 @@ gulp.task('serve', ['build'], () ->
gulp.watch(['./sass/*.scss'], ['sass']);
gulp.watch(['./img/*.png', './img/*.jpeg', './img/*.jpg'], ['img']);
gulp.watch(['./game/*.coffee'], ['coffee']);
+ gulp.watch(['./lib/*.coffee','./lib/*.js'], ['coffee']);
gulp.watch(['./build/css/main.css'], sassListener);
gulp.watch(
diff --git a/game/begin.coffee b/game/begin.coffee
index b810ac0..f11fc17 100644
--- a/game/begin.coffee
+++ b/game/begin.coffee
@@ -23,6 +23,15 @@ actlink = (content, ref) ->
textcycle = (content, ref) ->
return "#{content}"
+###
+This function clears the screen.
+The full backlog makes sense in dialogues but it's clunky when you exploring.
+So this is manual cls
+###
+cls = () ->
+ document.getElementById("intro").innerHTML = ""
+ document.getElementById("content").innerHTML = ""
+
# usage: writemd( system, "Text to write")
writemd = (system, text) ->
text = markdown(text)
diff --git a/game/story.coffee b/game/story.coffee
index e02bcd4..3e9a98e 100644
--- a/game/story.coffee
+++ b/game/story.coffee
@@ -1,19 +1,79 @@
# Your game goes here
-dialogue "Option 1", "start", "secretary", """
- No spoilers!
- """
+dialogue "Yes", "start", "question2", """
+ Good, because you'll have to read the sources. A lot.
+
+ Salet is *not* a library or a framework you can slap something on.
+ It's more a game you can hack into your game.
+ (Like Undum, yeah.)
-dialogue "Option 2", "start", "secretary", """
- No spoilers!
- """
+ I hope to change that in the future but for now it's a weird mix of CoffeeScript classes and Undum core Javascript functions.
+ And Undum is notorious for making some hardcoded calls to how your game should *look and feel*.
+ The point of Salet is to have some freedom to change the user interface however you like.
+ But you'll have to code it first.
-room "university-start",
- tags: ["secretary"]
- ways: ["supermarket"]
- optionText: "Leave the University"
+ For example, notice the lack of "Character" section?
+ The qualities and tools?
+ The functionality is still there but you'll have to style it yourself if you want it.
+
+ So, that's the bad news. The good news are just a click ahead of you.
+"""
+
+dialogue "No", "start", "question2", """
+ Okay, this is going to be tough but you'll have to pick up *something* to use this.
+
+ Salet is *not* a library or a framework you can slap something on.
+ It's more a game you can hack into your game. (Like Undum, yeah.)
+
+ There is no cool editor or clear instructions.
+ You'll have to copy the source code and edit the CoffeeScript files in the `game` folder.
+ Then *compile* them.
+
+ So, that's the bad news. The good news are just a click ahead of you.
+"""
+
+dialogue "Dialogue functions", "question2", "world", """
+ Let's start with a relatively small feature: dialogues.
+
+ Undum's arguably not the best thing for menu-style dialogues because while it gives the author a great dialogue engine,
+ he has to write a lot of code for a single reply.
+ So I did a shortcut function.
+
+ This is Undum's implicit choice, which you can use in you dialogues or floating modules:
+
+ dialogue "Title", "start_tag", "end_tag", "content", "code"
+
+ where:
+
+ * `title` is a text the player clicks on,
+ * `start_tag` is a tag for *this* room (no `#` or arrays),
+ * `end_tag` is a tag for the choices in this room (no `#` or arrays)
+ * `code` is a piece of Javascript that gets executed once the player clicks on a choice.
+
+ You still need to write a Situation for each reply, sorry.
+ But now you can do it faster!
+
+ Okay, with this aside, let me show you... The World.
+"""
+
+room "world",
+ tags: ["world"],
+ optionText: "Enter the world",
+ before: () ->
+ cls()
+ ways: ["university"]
+ content: """
+ ### Rhinestone Room
+
+ You're in a large room carved inside a giant milky rock mountain.
+ The floor and walls are littered with signs and signatures of the previous visitors.
+
+ A steep narrow #{textlink("well", "well")} proceeds upward.
+ """
+ writers:
+ well: "There is only one passage out. See the „Other rooms“ block popped up? Click it."
+
+room "university",
before: () ->
- document.getElementById("intro").innerHTML = ""
- document.getElementById("content").innerHTML = ""
undum.game.situations["supermarket"].destination()
"""
You leave the University.
diff --git a/html/index.html b/html/index.html
index e1b39f3..0dca9ab 100644
--- a/html/index.html
+++ b/html/index.html
@@ -23,7 +23,11 @@
-
Intro here.
+
Salet is an offspring of Undum and Raconteur.
+
The project is still a work-in-progress. This "game" will show you some of the new features.
+
It's supposed to be relatively painless for the author without sacrificing the reader's experience.
+ For example, the game still loads while you're reading this.
+
First of all, are you familiar with HTML and Coffeescript? As in, reading the real source code.
diff --git a/lib/dialogue.coffee b/lib/dialogue.coffee
index ae6c697..f585303 100644
--- a/lib/dialogue.coffee
+++ b/lib/dialogue.coffee
@@ -19,6 +19,7 @@ dialogue = (title, startTag, endTag, text, effect) ->
retval = room(randomid(), {
optionText: title
content: text
+ clear: false # backlog is useful in dialogues
choices: "#"+endTag
})
if typeof(startTag) == "string"
diff --git a/lib/room.coffee b/lib/room.coffee
index 7423cbd..5d46fd6 100644
--- a/lib/room.coffee
+++ b/lib/room.coffee
@@ -36,6 +36,7 @@ update_ways = (ways) ->
content = ""
distances = []
if ways
+ document.querySelector(".ways h2").style.display = "block"
for way in ways
if undum.game.situations[way]?
title = undum.game.situations[way].name
@@ -44,6 +45,8 @@ update_ways = (ways) ->
key: way
distance: undum.game.situations[way].distance
})
+ else
+ document.querySelector(".ways h2").style.display = "none"
document.getElementById("ways").innerHTML = content
min = Infinity
min_key = []
@@ -64,16 +67,38 @@ class SaletRoom extends RaconteurSituation
@objects = spec.objects
if spec.exit?
@exit = spec.exit
+ if spec.enter?
+ @enter = spec.enter
+ if spec.clear?
+ @clear = spec.clear
+ if spec.writers?
+ @writers = spec.writers
return this
objects: []
distance: Infinity # distance to the destination
+ clear: true # clear the screen on entering the room?
###
I call SaletRoom.exit every time the player exits to another room.
+ Unlike @after this gets called after the section is closed.
+ It's a styling difference.
###
exit: (character, system, to) ->
+ return true
+
###
- Undum calls Situation.enter every time a situation is entered, and
+ I call SaletRoom.enter every time the player enters this room but before the section is opened.
+ Unlike @before this gets called before the current section is opened.
+ It's a styling difference.
+
+ The upstream Undum version does not allow you to redefine @enter function easily but allows custom @exit one.
+ It was renamed as @entering to achieve API consistency.
+ ###
+ enter: (character, system, from) ->
+ return true
+
+ ###
+ Salet's Undum version calls Situation.entering every time a situation is entered, and
passes it three arguments; The character object, the system object,
and a string referencing the previous situation, or null if there is
none (ie, for the starting situation).
@@ -81,11 +106,17 @@ class SaletRoom extends RaconteurSituation
My version of `enter` splits the location description from the effects.
Also if f == this.name (we're in the same location) the `before` and `after` callbacks are ignored.
###
- enter: (character, system, f) ->
- #system.clearContent()
+ entering: (character, system, f) ->
+ if @clear
+ system.clearContent()
+
if f != @name and f?
@visited++
- undum.game.situations[f].exit(character, system, @name)
+ if undum.game.situations[f].exit?
+ undum.game.situations[f].exit(character, system, @name)
+
+ if @enter
+ @enter character, system, f
if not @extendSection
classes = if @classes then ' ' + @classes.join(' ') else ''
@@ -95,13 +126,17 @@ class SaletRoom extends RaconteurSituation
system.write("")
if f != @name and @before?
- print(@before.fcall(this, character, system, f))
+ content = @before.fcall(this, character, system, f)
+ if content
+ print(content)
if @look
@look character, system, f
if f != @name and @after?
- print(@after.fcall(this, character, system, f))
+ content = @after.fcall(this, character, system, f)
+ if content
+ print(content)
if not @extendSection
system.write("")
@@ -124,10 +159,6 @@ class SaletRoom extends RaconteurSituation
You could interpret this as an EXAMINE verb or USE one, it's your call.
###
act: (character, system, action) ->
- # default Raconteur action
- if (action.match(/^_(writer|replacer|inserter)_.+$/))
- return RaconteurSituation.prototype.act.call(this, character, system, f)
-
if (link = action.match(/^_act_(.+)$/)) #object action
for thing in @objects
if thing.name == link[1]
@@ -142,6 +173,9 @@ class SaletRoom extends RaconteurSituation
return print(thing.act.fcall(thing, character, system))
# the loop is done but no return came - match not found
console.error("Could not find #{link[1]} in current room.")
+
+ # default Raconteur action
+ return RaconteurSituation.prototype.act.call(this, character, system, action)
# Marks every room in the game with distance to this room
destination: () ->
diff --git a/lib/situation.coffee b/lib/situation.coffee
index 567fc89..88b1c63 100644
--- a/lib/situation.coffee
+++ b/lib/situation.coffee
@@ -29,7 +29,7 @@ String.prototype.fcall = () -> return this
#Adds the "fade" class to a htmlString.
String.prototype.fade = () ->
- return this.classList.add("fade")
+ return '
'+this+'
'
###
The prototype RaconteurSituation is the basic spec for situations
@@ -66,15 +66,15 @@ RaconteurSituation.prototype.act = (character, system, action) ->
responses = {
writer: (ref) ->
- content = @writers[ref].fcall(that, character, system, action)
+ content = that.writers[ref].fcall(that, character, system, action)
output = markdown(content).fade()
system.writeInto(output, '#current-situation')
replacer: (ref) ->
- content = @writers[ref].fcall(that, character, system, action)
+ content = that.writers[ref].fcall(that, character, system, action)
output = markdown(content).fade()
system.replaceWith(output, '#'+ref)
inserter: (ref) ->
- content = @writers[ref].fcall(that, character, system, action)
+ content = that.writers[ref].fcall(that, character, system, action)
output = markdown(content).fade()
system.writeInto(output, '#'+ref)
}
diff --git a/lib/undum.js b/lib/undum.js
index 29cd26b..ba86592 100644
--- a/lib/undum.js
+++ b/lib/undum.js
@@ -151,9 +151,8 @@ var assert = function(expression, message) {
var Situation = function(opts) {
if (opts) {
- if (opts.enter) this._enter = opts.enter;
+ if (opts.entering) this._enter = opts.entering;
if (opts.act) this._act = opts.act;
- if (opts.exit) this._exit = opts.exit;
// Options related to this situation being automatically
// selected and displayed in a list of options.
@@ -194,19 +193,14 @@ var Situation = function(opts) {
* may be null if this is the starting situation. Unlike the
* exit() method, this method cannot prevent the transition
* happening: its return value is ignored. */
-Situation.prototype.enter = function(character, system, from) {
- if (this._enter) this._enter(character, system, from);
+Situation.prototype.entering = function(character, system, from) {
+ if (this._entering) this._entering(character, system, from);
};
/* A function that takes action when we carry out some action in a
* situation that isn't intended to lead to a new situation. */
Situation.prototype.act = function(character, system, action) {
if (this._act) this._act(character, system, action);
};
-/* A function that takes action when we exit a situation. The last
- * parameter indicates the situation we are going to. */
-Situation.prototype.exit = function(character, system, to) {
- if (this._exit) this._exit(character, system, to);
-};
/* Determines whether this situation should be contained within a
* list of options generated automatically by the given
* situation. */
@@ -300,7 +294,7 @@ var SimpleSituation = function(content, opts) {
this.maxChoices = opts && opts.maxChoices;
};
SimpleSituation.inherits(Situation);
-SimpleSituation.prototype.enter = function(character, system, from) {
+SimpleSituation.prototype.entering = function(character, system, from) {
if (this.heading) {
if ($.isFunction(this.heading)) {
system.writeHeading(this.heading());
@@ -308,7 +302,7 @@ SimpleSituation.prototype.enter = function(character, system, from) {
system.writeHeading(this.heading);
}
}
- if (this._enter) this._enter(character, system, from);
+ if (this._entering) this._entering(character, system, from);
if (this.content) {
if ($.isFunction(this.content)) {
system.write(this.content());
@@ -1454,8 +1448,6 @@ var doTransitionTo = function(newSituationId) {
// We might not have an old situation if this is the start of
// the game.
if (oldSituation) {
- // Notify the exiting situation.
- oldSituation.exit(character, system, newSituationId);
if (game.exit) {
game.exit(character, system, oldSituationId, newSituationId);
}
@@ -1489,7 +1481,7 @@ var doTransitionTo = function(newSituationId) {
if (game.enter) {
game.enter(character, system, oldSituationId, newSituationId);
}
- newSituation.enter(character, system, oldSituationId);
+ newSituation.entering(character, system, oldSituationId);
// additional hook for when the situation text has already been printed
if (game.afterEnter) {