| summaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'content/fate_v1/_index.md')
| -rw-r--r-- | content/fate_v1/_index.md | 187 |
1 files changed, 35 insertions, 152 deletions
diff --git a/content/fate_v1/_index.md b/content/fate_v1/_index.md index 29e595d..3f20dc4 100644 --- a/content/fate_v1/_index.md +++ b/content/fate_v1/_index.md @@ -9,155 +9,38 @@ 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. - -`text` corresponds to text with 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 `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. - +To write in Fate, simply open your favorite text editor and create a new file +that starts with the following line: +{{< fatecode >}}(fate_version 1){{< /fatecode >}} + +Before going any further into the documentation, you should familiarize yourself +with the [notations](/fate_v1/notations/). + +Fate files are composed of three types of constructs: +* [Computations](/fate_v1/computations/), operations that do not modify the + memory and return a value. +* [Instructions](/fate_v1/instructions/), constructs that can modify the memory + but do not return any values. +* [Declarations](/fate_v1/declarations/), special instructions that are + performed during compilation instead of during the execution. + +Other concepts in Fate include: +* [Variables](/fate_v1/declarations/variables/): named memory element. +* [Types](/fate_v1/declarations/types/): every memory element is assigned a + specific type. Fate uses static and strong typing, meaning that types are + determined at compilation time and typing +* [Procedures/Sequences](/fate_v1/declarations/sequences/): named list of + instructions, which can take parameters. +* [Lambda Functions](/fate_v1/computations/lambda_functions/): computations + which are not performed immediately but are instead stored for future use. +* [Addresses/Pointers](/fate_v1/computations/addresses/): value that + corresponds to a memory element (not to be confused with the value *of* that + memory element). +* Conditionals: selection of + [computations](/fate_v1/computations/conditionals/) or + [instructions](/fate_v1/instructions/conditionals/) depending on a + computation. +* [Loops](/fate_v1/instructions/loops/): repetition of instructions controlled + by computations. +* [Choices](/fate_v1/instructions/player_choices/): prompt the user to select an + option. |


