2014-10-02

syntax

The way I'd like to write games is simple. Write some text, then view it in a node map and repeat. The rewrite of Fate was mostly so that I could do just that.

The first thing I needed to do was formalize a syntax for writing that could handle the type of games I'd like to make. I started with tweecode as a base. Passages mark collections of text, and they look like they would with Twine.

:: Some Passage
Some text.
view raw 000 ex 1 hosted with ❤ by GitHub

Links between passages are done with familiar double brackets:

[[Another Passage]]
[[Any Passage|Passage B]]
view raw 000 ex 2 hosted with ❤ by GitHub

I didn't want to keep the Macro syntax: <<set $thing = 8>> , so I slimmed it down like this: set($thing = 8) but I kept the $ character prefix on variables as an act of habit.

One interesting feature I had to figure out how to represent are implicit links:

[[Another Passage|query($passage = 8)]]
view raw 000 ex 3 hosted with ❤ by GitHub

The query() part sets the value of 'passage' to 8 before executing a query to find the best passage to display. So to define passages that are queried:

:: Some Passage
criteria($passage == 8)
Some text.
view raw 000 ex 4 hosted with ❤ by GitHub

Basically the criteria() function binds the passage to it's arguments. To save a little writing I setup the ability to stack multiple passage responses under a single passage declaration.

:: Some Passage
criteria($passage == 8 && $onFire == 1)
Some text while the thing is on fire.
criteria($passage == 8)
Some text.
view raw 000 ex 5 hosted with ❤ by GitHub

Then there is the world system (although it's not really that amazing of a system). I opted for familiarity in the declaration of passages, nouns and verbs.

:: House [noun()]
This is a great house.
:: Room [noun(House)]
This a room in the house.
view raw 000 ex 6 hosted with ❤ by GitHub

The noun() call is done where tags would be in tweecode. Notice that the noun() function for 'Room' has 'House' as an argument. It basically sets up the default hierarchy of the two objects; the room is a child of the house. The body of these declarations are automatically mapped as descriptions that respond to an examine action.

Actions are declared in a similar way.

:: set on fire [verb(Room)]
You light the room on fire.
view raw 000 ex 7 hosted with ❤ by GitHub

Verbs that shouldn't always be available can use a require() function.

:: extinguish fire [verb(Room)]
require($roomIsOnFire == 1)
You try to extinguish the flames.
view raw 000 ex 8 hosted with ❤ by GitHub

require() was necessary in addition to criteria() since responses to verbs may need to be tied to criteria since they are essentially passages.

:: dance around fire [verb(Clown)]
require($player == Clown)
criteria($clownIsDrunk == true)
You dance carelessly around the fire.
criteria($clownIsDrunk == false)
You try your luck and dance around the fire.
view raw 000 ex 9 hosted with ❤ by GitHub

Moving objects around is done with a move() function

:: escape from house [noun(Clown)]
require($roomIsOnFire == 1)
move(Clown -> Outside)
The clown moves clumsily out of the burning house.
view raw 000 ex 10 hosted with ❤ by GitHub

I skipped a lot of functionality (print, display, if/else etc), but that is a quick look at the basics of how I'm writing Something in Fate.

No comments:

Post a Comment