summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'content/fate_v1/_index.md')
-rw-r--r--content/fate_v1/_index.md162
1 files changed, 162 insertions, 0 deletions
diff --git a/content/fate_v1/_index.md b/content/fate_v1/_index.md
new file mode 100644
index 0000000..8b90a7a
--- /dev/null
+++ b/content/fate_v1/_index.md
@@ -0,0 +1,162 @@
+---
+title: "Fate (Version 1)"
+menuTitle: "Fate"
+---
+
+When using Tonkadur, Fate is the language the author writes in. This language is
+meant to provide the writer with as many tools as possible, so that they do not
+feel constrained by the limitations of the language, nor find writing complex
+narratives tedious.
+
+## A few warnings first
+
+Fate uses strong typing. This is intended to make detection of mistakes easier,
+but may lead to some frustrations for authors only used to languages using
+dynamic typing.
+
+Fate does not have any special features for multi-seating/multi-player
+narratives. This is by design, as adding proper support for this would make the
+underlying language more complex, and thus would make it harder to create an
+interpreter for it. This is however something considered for an extension
+(see
+[this GitHub issue about it](https://github.com/nsensfel/tonkadur/issues/5)).
+
+You'll need to learn parentheses management, if you make anything complex. Fate
+uses a LISP inspired syntax, so parentheses are everywhere. The syntax gives you
+free reign over indentation, but so many parentheses does require at least some
+discipline in order to be readable.
+
+Fate is meant to be compiled. This does add an extra step to your existing
+process.
+
+Fate is very much a new language. There isn't many (any?) tools for it.
+
+If for some reason you want to perform memory allocation, there is no automatic
+garbage collection, so you will have to free whatever you allocate.
+
+In what may seem weird for narrative scripting, Fate does not feature string
+manipulation operations. Strings can be made into rich text, with complex
+attributes, but you will not be able to use things like regular expressions
+(or anything other than simple concatenation, really) with just the base
+language. This is because of these operations would need to be implemented
+directly by the interpreter anyway, and their use isn't actually common in
+a narrative description, which would make requiring support for them of
+any Tonkadur interpreter problematic.
+
+## Some nice features
+
+If you haven't closed the tab yet, here are some reasons why you *might* want
+to use Fate.
+
+It *is* a LISP inspired syntax. If that's what you like, you might even enjoy
+this take on it. There's no fiddling with indentation, no wondering what symbol
+does what. It's all about parentheses indicating something is performed on a
+list of other things. It's not a purely functional language, though. In fact,
+it's a mix of both declarative and imperative programming: sequences (or
+procedures) are imperative. Computations are functional. There are lambda
+functions, but they're strongly typed. Collections and structures can only be
+modified through specific instructions, so it's not quite really a LISP-like
+language.
+
+There are pointers. Oh, come on, it's a plus, *right?* This makes it a lot
+easier to refer to things. There's no pointer arithmetic, so you don't have to
+worry about the scary stuff. Also, this lets you allocate memory, which is
+useful when you want a unspecified amount of distinct instances of something.
+Want to describe a story where the player can push a button as many time as
+they choose, create a clone of a creature every time they do so, yet let them
+fight any of these creature as their distinct instance? Well, with memory
+allocation and pointers, it's easily done. Didn't you know? When writing a
+narrative, the RAM's the limit. So yeah, maybe don't forget to `free` the
+thousands of monster the player will no doubt create.
+
+You can do recursion. Wait! I *am* listing the nice features! Do people really
+not like recursion and pointers? Oh, well... Still, you can do recursions with
+both procedures and lambda functions. Not a fan of recursion? That's alright,
+you also have imperative loops: `for`, `while`, `do_while`, and even
+`for_each`.
+
+## The basics
+
+#### Procedures (or Sequences) and Instructions
+Procedures are lists of instructions and things to display. Instructions can be
+applied to values, but they themselves do not return any value. Any value not
+part of an instruction found in a procedure is displayed. Any value being part
+of an instruction is **not** displayed.
+
+One way to think about it is to consider procedures as being actually two types
+of things: sequences and procedures. A sequence is then a scene in the story,
+and a procedure is just a construct called upon to perform instructions.
+
+Procedures can take arguments. Values are passed by copy.
+
+Procedures can be called in two ways: a `call` or a `jump`. A `call` will
+perform the procedure before continuing with the current sequence of
+instructions. A `jump` will perform the procedure **instead of** the
+**current** sequence of instructions.
+
+Procedures can be called before their definition. The compiler will simply tell
+you if the definition ends up being incompatible or missing.
+
+#### Computations
+Computations are operations returning a value. Computations do not modify
+anything, they simply return the result of an operation.
+
+A special type of computation, called *lambda function*, allows the creation of
+a computation that will be performed only when called upon. Those can take
+parameters. What's the use of something as advanced in a narrative scripting
+language? It's convenient when you want to express something like a character's
+name who depends on what the player figured out. Sure, you *could* make each
+instance of the name feature a series of tests to find which value to use, or
+you could just use a lambda function and just put
+`(eval name_of_mysterious_character)` to get the right value.
+
+One last thing about lambda functions, which really are the only potentially
+complicated thing about computations: these *are* computations, so you can use
+them as such. They also cannot modify anything, as they only contain
+computations and not instructions.
+
+#### Declarations and First Level Instructions
+Declarations and First Level Instructions are a special type of instruction
+which can only be done from outside a procedure. This distinction means that,
+for example, you cannot define a procedure from within a procedure.
+
+#### Events
+Sometimes, you might need to communicate something to the interpreter which
+cannot be expressed in Fate. For example, you might want to say: "pause for 30
+seconds", or "play this music". This kind of thing has been considered to not
+be generic enough to mandate every interpreter supports it. Instead, events are
+used.
+
+Events are first declared, by being given a name and a list of types
+corresponding to the parameters they take. Then, the `(event ...)` instruction
+can be used to indicate that a certain event should occur. This will pause the
+execution, and make the interpreter react to the event before continuing.
+
+The effect of an event is purely the interpreter's responsibility. It cannot be
+described in Fate. Thus, you will need to refer to the interpreter you use to
+see what events are available.
+
+#### Types
+The basic `string`, `int`, `float`, and `bool` types are what one would expect.
+
+`rich_text` corresponds to text decorations, see the text effect sub-section.
+
+Two collection types are available: `(list [TYPE])` is a list of `[TYPE]`
+elements, and `(set [COMPARABLE])` is a set of `[COMPARABLE]` elements.
+
+`(ptr [TYPE])` is an address to a value of type `[TYPE]`.
+
+Structures can be defined. They may contain other structures, but cannot be
+recursive: only already defined types can be used. Pointers cannot be used to
+resolve this conundrum in this version of Fate, but it may be added in the next
+version (see [this GitHub
+issue](https://github.com/nsensfel/tonkadur/issues/6)).
+
+#### Player Choices
+Inputs from the players are limited to the `(player_choice ...)` instruction.
+It presents the player with `rich text` options to choose from, which execute
+an associated list of instructions if chosen.
+
+More complicated inputs, such as retrieving a `string` or an `int` from the
+player require the definition and use of events.
+