Vertigo has a completely new syntax

Vertigo is a language for interactive fiction I am developing which was inspired by Dialog.

Previously the syntax was very similar to Dialog, however I wanted to see what things might be like without all the parentheses, which ended up changing the syntax drastically, but I’m quite happy with the results.

Below is the Cloak of Darkness game ported to the new syntax. It cannot be played yet, since Vertigo has no standard library, but I expect it won’t change much from here.

BTW, the repository for Vertigo is here: Andrew Apted / vertigo · GitLab

story title:  { Cloak of Darkness }
story author: { Andrew Apted }
story noun:   { A port of Roger Firth's reference game }

enable scoring
maximum score is 2

import "std.lib"

============================================================================

introduction:
      { Hurrying through the rainswept November night, you're glad
        to see the bright lights of the Opera House. It's surprising
        that there aren't more people about but, hey, what do you
        expect in a cheap demo game...?
      }

============================================================================

room #Foyer:
      { You are standing in a spacious hall, splendidly decorated
        in red and gold, with glittering chandeliers overhead. The
        entrance from the street is to the north, and there are
        doorways south and west.
      }

describe this briefly:
      { Foyer of the Opera House }

prevent [leave this north]:
      { You've only just arrived, and besides, the weather outside
        seems to be getting worse.
      }

this goes @west  to #Cloakroom
this goes @south to #Bar

============================================================================

room #Cloakroom:
      { The walls of this small room were clearly once lined with hooks,
        though now only one remains. The exit is a door to the east.
      }

      notice #hook

describe this briefly:
      { Cloakroom }

this goes @east to #Foyer

============================================================================

scenery #hook:
      for all $Obj is on this:
            collect $Obj -> $List
      end

      { It's just a small brass hook,
        [if $List = []] screwed to the wall.
        [else] with [a $List] hanging on it.
        [end]
      }

this is in #Cloakroom
this is a supporter
this is called: { small brass hook }
this is also called: { peg }

hook point is not awarded

instead of [hang $Obj]:
      try [put $Obj on #hook]

============================================================================

room #Bar:
      { The bar, much rougher than you'd have guessed after the
        opulence of the foyer to the north, is completely empty.
        There seems to be some sort of message scrawled in the
        sawdust on the floor.
      }

      notice #message

describe this briefly:
      { Foyer Bar }

this goes @north to #Foyer

this is dark:
      #cloak is in this or #cloak is with #player

instead of [look down]:
      when the current room is this
      try [examine #message]

============================================================================

scenery #message:
      if message has been trampled:
            { The message has been carelessly trampled, making it
              difficult to read. You can just distinguish the words...
              <p>
              <b>*** You have lost ***</b>
            }
      else:
            increase score by 1
            { The message, neatly marked in the sawdust, reads...
              <p>
              <b>*** You have won ***</b>
            }
      end
      game over

this is called: { scrawled message }
this is also called: { floor sawdust }
this is in #Bar

message has not been trampled
have not warned

instead of [read this]:
      try [examine this]

prevent $Action:
      the current room is #Bar
      player can not see
      $Action is not a command

      == check whether the verb is allowed or not
      $Action = [$Verb | $]
      $Verb is not one of [go leave enter look inventory]

      if have not warned:
            { In the dark? You could easily disturb something. }
            have warned now
      else:
            { Blundering around in the dark isn't a good idea! }
            message has been trampled now
      end

============================================================================

item #cloak:
      { A handsome cloak, of velvet trimmed with satin, and slightly
        splattered with raindrops. Its blackness is so deep that it
        almost seems to suck light from the room.
      }

this is called: { velvet cloak }
this is also called: { dark black satin }
this is with #player
this is wearable
this is worn

prevent [drop this]:
      don't drop cloak outside cloakroom

prevent [put this $ $]:
      don't drop cloak outside cloakroom

don't drop cloak outside cloakroom:
      when the current room is not #Cloakroom
      { This isn't the best place to leave a smart cloak lying around. }

perform [put this on #hook]:
      when hook point is not awarded

      hook point is awarded now
      increase score by 1

      == fall back to the default behaviour
      fail

I’d want to play with this a bit to get a feel for how it works out in practice, but I think you’re really leveraging the ability to use multi-word identifiers to produce readable code!

By the way, one of the things that bugs me about Dialog is that, because the first matching rule in the source code is always tried first, you have to write all the exceptions (special handling, etc) before the general rules. I think it’s much more readable to be able to define the general framework to start with and then to code exceptions for specific situations. Would you consider switching the order in Vertigo?

Hmmm… I tend to think that the general way of visiting rules in the same order they appear in the source code is more intuitive than going backwards (from last to first).

Inform 7/10 seems to solve this by understanding the generic-ness of rules, and trying the most specific ones first. But I don’t think it would be feasible to try to replicate that in Vertigo.

But it’s something I’ll definitely think more about…

The usual trick, which Inform uses, is to order rules by how complex the condition is. Most AND conditional clauses first, fewest last. “Check jumping” is a zero; “check jumping in the Volcano” is a 1; “check jumping in the Shower if the player has socks and shower is on” is a 3.

This isn’t perfect. There’s going to be a lot of ties, so you probably fall back to source-code order for those. But it gets the simple cases right – you check exceptions before general rules.