summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2021-12-02 22:24:21 +0100
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2021-12-02 22:24:21 +0100
commit0a32a8eeb98d5f3507edf5e303ae655f4b923c74 (patch)
tree772d1793d7d1cdd323d598d144e1624699abcf36 /content/learn
parent0d2736d22ced1f9bf566192f8604f869e0f5c6b9 (diff)
Updating the documentation to match changes in Fate.
Diffstat (limited to 'content/learn')
-rw-r--r--content/learn/01.start/_index.md4
-rw-r--r--content/learn/02.choices/_index.md29
-rw-r--r--content/learn/03.variables/default.md73
-rw-r--r--content/learn/04.sequences/default.md94
-rw-r--r--content/learn/05.files/default.md41
-rw-r--r--content/learn/06.pointers/default.md56
-rw-r--r--content/learn/07.structures/default.md76
-rw-r--r--content/learn/08.collections/default.md224
-rw-r--r--content/learn/09.lambdas/default.md183
-rw-r--r--content/learn/10.conditions/default.md332
-rw-r--r--content/learn/11.loops/default.md457
11 files changed, 1038 insertions, 531 deletions
diff --git a/content/learn/01.start/_index.md b/content/learn/01.start/_index.md
index 1741772..a3a4225 100644
--- a/content/learn/01.start/_index.md
+++ b/content/learn/01.start/_index.md
@@ -23,7 +23,7 @@ image.
As you contemplate your own pointless description, your gaze leaves
what turns out to be an already empty glass in your hand and finds the
barman.
-(end)
+(end!)
{{< /fatecode >}}
This is a very minimal story in Fate. Let's look at what is it made of:
@@ -36,7 +36,7 @@ This is a very minimal story in Fate. Let's look at what is it made of:
makes indentation have no effect on the output text. Furthermore such
characters preceding text are ignored.
* `(newline)` inserts a newline in the output.
-* `(end)` signals the end of the story. It needs to be there.
+* `(end!)` signals the end of the story. It needs to be there.
With this, you know how to make a static, purely textual story in Fate. Our poor
protagonist needs a refill, so we need to introduce
diff --git a/content/learn/02.choices/_index.md b/content/learn/02.choices/_index.md
index a5ba4d7..b61ce94 100644
--- a/content/learn/02.choices/_index.md
+++ b/content/learn/02.choices/_index.md
@@ -32,39 +32,34 @@ As you contemplate your own pointless description, your gaze leaves
what turns out to be an already empty glass in your hand and finds the
barman.
-(player_choice
- (
- ( Ask the barman for a refill )
- Staring straight at the barman, you raise your glass and
- proclaim:
+(player_choice!
+ (option ( Ask the barman for a refill )
+ Staring straight at the barman, you raise your glass and proclaim:
(newline)
"This soon-to-be world savior needs more booze!"
)
- (
- ( Fall asleep )
- Deciding to break away from the expected storyline, you promptly
- fall asleep.
+ (option ( Fall asleep )
+ Deciding to break away from the expected storyline, you promptly fall
+ asleep.
)
- (
- ( Resolve whether P=NP )
- Sadly, the output for this choice would require some concepts
- that haven't been introduced yet, so let's never mention it
- again.
+ (option ( Resolve whether P=NP )
+ Sadly, the output for this choice would require some concepts that
+ haven't been introduced yet, so let's never mention it again.
)
)
-(end)
+(end!)
{{< /fatecode >}}
In this version, the player is able to interact with the story: once
-`player_choice` is reached, the output stops and the player is presented with
+`player_choice!` is reached, the output stops and the player is presented with
options. Here, three choices are available. A choice is made of a label and a
list of instructions. The label is the text which is displayed to player (for
example `Fall asleep`). The list of instructions is what will be performed if
that choice is selected. Putting text where instructions are expected simply
outputs the text. In fact, all the content of the previous step was
instructions. Once a choice has been made and the instructions have been
-performed, the story continues past the `player_choice` construct.
+performed, the story continues past the `player_choice!` construct.
But something critical is missing. Indeed, how can you get a refill without
money? Just how much money does our hero have? Will it be enough to quench that
diff --git a/content/learn/03.variables/default.md b/content/learn/03.variables/default.md
index 3d0e962..d7fbc48 100644
--- a/content/learn/03.variables/default.md
+++ b/content/learn/03.variables/default.md
@@ -21,69 +21,64 @@ appropriate.
{{< fatecode >}}(fate_version 1)
(local int hero_money)
-(local int price_of_booze)
+(local int price_of_booze 12)
-(set hero_money 42)
-(set price_of_booze 12)
+(set! hero_money 42)
-Once upon a time, starting a story with these words wasn't considered
-a cliche. Starting in a tavern might also not be seen as very
-original. Having the main character be an street orphan, raised by
-some mysterious sage all to end up as a mercenary with an uncommonly
-strong sense of honor probably isn't going to lead to any praises for
-novelty either. Maybe you should drink to that.
+Once upon a time, starting a story with these words wasn't considered a cliche.
+Starting in a tavern might also not be seen as very original. Having the main
+character be an street orphan, raised by some mysterious sage all to end up as
+a mercenary with an uncommonly strong sense of honor probably isn't going to
+lead to any praises for novelty either. Maybe you should drink to that.
(newline)
-Or maybe you shouldn't. This isn't your first mug. Not your second
-either. Drinking to forget that you are a stereotypical hero isn't
-going to solve anything. Worse, the alcoholic trait is part of the
-image.
+Or maybe you shouldn't. This isn't your first mug. Not your second either.
+Drinking to forget that you are a stereotypical hero isn't going to solve
+anything. Worse, the alcoholic trait is part of the image.
(newline)
-As you contemplate your own pointless description, your gaze leaves
-what turns out to be an already empty glass in your hand and finds the
-barman.
+As you contemplate your own pointless description, your gaze leaves what turns
+out to be an already empty glass in your hand and finds the barman.
-(player_choice
- (
- ( Ask the barman for a refill )
- Staring straight at the barman, you raise your glass and
- proclaim:
+(player_choice!
+ (option ( Ask the barman for a refill )
+ Staring straight at the barman, you raise your glass and proclaim:
(newline)
"This soon-to-be world savior needs more booze!"
(newline)
- The barman's lack of reaction is disappointing, but seeing the
- beer being poured does help improve the mood.
+ The barman's lack of reaction is disappointing, but seeing the beer being
+ poured does improve your mood.
(newline)
Satisfied, you hand the barman (var price_of_booze) copper coins.
- (set hero_money
- (- (var hero_money) (var price_of_booze))
- )
+ (set! hero_money (- hero_money price_of_booze))
)
- (
- ( Fall asleep )
- Deciding to break away from the expected storyline, you promptly
- fall asleep.
+ (option ( Fall asleep )
+ Deciding to break away from the expected storyline, you promptly fall
+ asleep.
(newline)
...
(newline)
- Upon waking up, your hard-trained reflexes inform you that
- someone stole all your money.
- (set hero_money 0)
+ Upon waking up, your hard-trained reflexes inform you that someone stole
+ all your money.
+ (set! hero_money 0)
)
)
-(end)
+(end!)
{{< /fatecode >}}
* `(local int hero_money)` declares an `int` variable with the name
- `hero_money`.
-* `(set hero_money 42)` sets the value of the `hero_money` variable to 42.
+ `hero_money`. This variable takes the default value for its type.
+* `(local int price_of_booze 12)` declares an `int` variable with the name
+ `price_of_booze`. This variable takes the value `12`.
+* `(set! hero_money 42)` sets the value of the `hero_money` variable to 42.
* `(var price_of_booze)` returns the current value of the `price_of_booze`
variable.
-* `(- (var hero_money) (var price_of_booze))` returns the result of subtracting
+* `(- hero_money price_of_booze)` returns the result of subtracting
the value of `price_of_booze` to the value of `hero_money`. All operators
- use a prefixed form.
+ use a prefixed form. Because there is no ambiguity about `hero_money` and
+ `price_of_booze` being strings, it is not necessary to write
+ `(- (var hero_money) (var price_of_booze))`.
-`local`, `set`, `player_choice`, and `end`, are instructions. Instructions do
+`local`, `set!`, `player_choice!`, and `end!`, are instructions. Instructions do
not return any value. Thus, they do not add to the printed text.
Having to continue the story from within the `player_choice` structure is going
diff --git a/content/learn/04.sequences/default.md b/content/learn/04.sequences/default.md
index 8b56ee7..874b14b 100644
--- a/content/learn/04.sequences/default.md
+++ b/content/learn/04.sequences/default.md
@@ -4,7 +4,7 @@ title: "Introducing Sequences"
weight: 4
---
In [the previous step](/learn/variables), we introduced variables. The story is
-starting to have branches, but writing them from within a `player_choice`
+starting to have branches, but writing them from within a `player_choice!`
construct is awkward. To resolve this, *sequences* are introduced.
Sequences are named lists of instructions. They do *not* have to be defined
@@ -31,94 +31,86 @@ Sequences can take parameters.
{{< fatecode >}}(fate_version 1)
-(global int hero_money)
+(global int hero_money 42)
-(set hero_money 42)
-
-Once upon a time, starting a story with these words wasn't considered
-a cliche. Starting in a tavern might also not be seen as very
-original. Having the main character be an street orphan, raised by
-some mysterious sage all to end up as a mercenary with an uncommonly
-strong sense of honor probably isn't going to lead to any praises for
-novelty either. Maybe you should drink to that.
+Once upon a time, starting a story with these words wasn't considered a cliche.
+Starting in a tavern might also not be seen as very original. Having the main
+character be an street orphan, raised by some mysterious sage all to end up as
+a mercenary with an uncommonly strong sense of honor probably isn't going to
+lead to any praises for novelty either. Maybe you should drink to that.
(newline)
-Or maybe you shouldn't. This isn't your first mug. Not your second
-either. Drinking to forget that you are a stereotypical hero isn't
-going to solve anything. Worse, the alcoholic trait is part of the
-image.
+Or maybe you shouldn't. This isn't your first mug. Not your second either.
+Drinking to forget that you are a stereotypical hero isn't going to solve
+anything. Worse, the alcoholic trait is part of the image.
(newline)
-As you contemplate your own pointless description, your gaze leaves
-what turns out to be an already empty glass in your hand and finds the
-barman.
-
-(player_choice
- (
- ( Ask the barman for a refill )
- (visit get_a_refill)
+As you contemplate your own pointless description, your gaze leaves what turns
+out to be an already empty glass in your hand and finds the barman.
+
+(player_choice!
+ (option ( Ask the barman for a refill )
+ (visit! get_a_refill)
)
- (
- ( Fall asleep )
- (jump_to fall_asleep)
+ (option ( Fall asleep )
+ (jump_to! fall_asleep)
)
)
(define_sequence pay ( (int cost) )
- (set hero_money
- (- (var hero_money) (var cost))
- )
+ (set! hero_money (- hero_money cost))
)
(define_sequence get_a_refill ()
(local int price_of_booze)
- (set price_of_booze 12)
+ (set! price_of_booze 12)
Staring straight at the barman, you raise your glass and proclaim:
(newline)
"This soon-to-be world savior needs more booze!"
(newline)
- The barman's lack of reaction is disappointing, but seeing the beer
- being poured does help improve the mood.
+ The barman's lack of reaction is disappointing, but seeing the beer being
+ poured does improve your mood.
(newline)
Satisfied, you hand the barman (var price_of_booze) copper coins.
- (visit pay (var price_of_booze))
+ (visit! pay price_of_booze)
)
(define_sequence fall_asleep ()
- Deciding to break away from the expected storyline, you promptly
- fall asleep.
+ Deciding to break away from the expected storyline, you promptly fall
+ asleep.
(newline)
...
(newline)
- Upon waking up, your hard-trained reflexes inform you that someone
- stole all your money.
- (set hero_money 0)
+ Upon waking up, your hard-trained reflexes inform you that someone stole all
+ your money.
+ (set! hero_money 0)
(newline)
- This set-back was more than you could take. You give up on this
- barely coherent story.
- (end)
+ This set-back was more than you could handle. You give up on this barely
+ coherent story.
+ (end!)
)
-(end)
+(end!)
{{< /fatecode >}}
-* `(visit get_a_refill)` makes a visit to the sequence `get_a_refill`. Since
+* `(visit! get_a_refill)` makes a visit to the sequence `get_a_refill`. Since
that sequence does not take parameters, none need to be provided.
-* `(jump_to fall_asleep)` stops the execution of the main instruction list and
+* `(jump_to! fall_asleep)` stops the execution of the main instruction list and
proceeds to using the sequence `fall_asleep` instead. Here again, no
arguments are expected by `fall_asleep`. Notice how the `fall_asleep` sequence
- ends with `(end)`: since there is no return from it, the original `(end)`
+ ends with `(end!)`: since there is no return from it, the original `(end!)`
would not be reached and thus a new one is required to end the story.
-* `(visit pay (var price_of_booze))` makes a visit to the `pay` sequence, which
- does require a parameter.
-* `(global int hero_money)` has replaced `(local int hero_money)`, because that
- variable needs to be accessible from within the sequences.
+* `(visit! pay price_of_booze)` makes a visit to the `pay` sequence, and the
+ compiler infers that `price_of_booze` is a variable whose value should be
+ passed as parameter. `(visit! pay (var price_of_booze))` would make that explicit.
+* `(global int hero_money 42)` has replaced `(local int hero_money)`, because
+ that variable needs to be accessible from within the sequences.
* `(local int price_of_booze)` has been moved to the `get_a_refill` sequence,
as there is no reason to have it be defined across the whole story.
* The `pay` sequence cannot directly access the `price_of_booze` variable, as
it is `local` and from another sequence, hence the use of a parameter to
communicate the correct amount.
-With this, the `player_choice` have become much more readable. However, the file
-itself is starting to become hard to read. The solution is then to [split the
-content into multiple files](/learn/files).
+With this, the `player_choice!` have become much more readable. However, the
+file itself is starting to become hard to read. The solution is then to [split
+the content into multiple files](/learn/files).
diff --git a/content/learn/05.files/default.md b/content/learn/05.files/default.md
index 06b6436..0829db1 100644
--- a/content/learn/05.files/default.md
+++ b/content/learn/05.files/default.md
@@ -15,9 +15,7 @@ but only if that file has not already been explored.
{{< fatecode >}}(fate_version 1)
-(global int hero_money)
-
-(set hero_money 42)
+(global int hero_money 42)
{{< /fatecode >}}
* Create a new file, `actions.fate`, with the following content:
@@ -27,10 +25,9 @@ but only if that file has not already been explored.
(require data.fate)
(define_sequence pay ( (int cost) )
- (set hero_money
- (- (var hero_money) (var cost))
- )
+ (set! hero_money (- hero_money cost))
)
+
{{< /fatecode >}}
* Create a new file, `get_a_refill.fate`, with the following content:
@@ -42,17 +39,17 @@ but only if that file has not already been explored.
(define_sequence get_a_refill ()
(local int price_of_booze)
- (set price_of_booze 12)
+ (set! price_of_booze 12)
Staring straight at the barman, you raise your glass and proclaim:
(newline)
"This soon-to-be world savior needs more booze!"
(newline)
The barman's lack of reaction is disappointing, but seeing the beer being
- poured does help improve the mood.
+ poured does improve your mood.
(newline)
Satisfied, you hand the barman (var price_of_booze) copper coins.
- (visit pay (var price_of_booze))
+ (visit! pay price_of_booze)
)
{{< /fatecode >}}
@@ -69,11 +66,11 @@ but only if that file has not already been explored.
(newline)
Upon waking up, your hard-trained reflexes inform you that someone stole all
your money.
- (set hero_money 0)
+ (set! hero_money 0)
(newline)
- This set-back was more than you could take. You give up on this barely
+ This set-back was more than you could handle. You give up on this barely
coherent story.
- (end)
+ (end!)
)
{{< /fatecode >}}
@@ -81,6 +78,9 @@ but only if that file has not already been explored.
{{< fatecode >}}(fate_version 1)
+(require get_a_refill.fate)
+(require falling_asleep.fate)
+
Once upon a time, starting a story with these words wasn't considered a cliche.
Starting in a tavern might also not be seen as very original. Having the main
character be an street orphan, raised by some mysterious sage all to end up as
@@ -94,21 +94,16 @@ anything. Worse, the alcoholic trait is part of the image.
As you contemplate your own pointless description, your gaze leaves what turns
out to be an already empty glass in your hand and finds the barman.
-(player_choice
- (
- ( Ask the barman for a refill )
- (visit get_a_refill)
+(player_choice!
+ (option ( Ask the barman for a refill )
+ (visit! get_a_refill)
)
- (
- ( Fall asleep )
- (jump_to fall_asleep)
+ (option ( Fall asleep )
+ (jump_to! fall_asleep)
)
)
-(require get_a_refill.fate)
-(require falling_asleep.fate)
-
-(end)
+(end!)
{{< /fatecode >}}
With this, the story is much more easy to follow. Let's continue by looking
diff --git a/content/learn/06.pointers/default.md b/content/learn/06.pointers/default.md
index 8432b3e..82a5733 100644
--- a/content/learn/06.pointers/default.md
+++ b/content/learn/06.pointers/default.md
@@ -24,11 +24,10 @@ Given a pointer `p`, the variable being pointed to can be referred to using
**data.fate:**
{{< fatecode >}}(fate_version 1)
-(global int hero_money)
+(global int hero_money 42)
(global string hero_name)
-
-(set hero_money 42)
{{< /fatecode >}}
+
**get_a_refill.fate:**
{{< fatecode >}}(fate_version 1)
@@ -41,11 +40,8 @@ Given a pointer `p`, the variable being pointed to can be referred to using
(int decrease)
)
Great! The price of booze just lowered from (at price_pointer)
- (set (at price_pointer)
- (-
- (at price_pointer)
- (var decrease)
- )
+ (set! (at price_pointer)
+ (- (at price_pointer) decrease)
)
to (at price_pointer)!
)
@@ -53,25 +49,24 @@ Given a pointer `p`, the variable being pointed to can be referred to using
(define_sequence get_a_refill ()
(local int price_of_booze)
- (set price_of_booze 12)
+ (set! price_of_booze 12)
Staring straight at the barman, you raise your glass and proclaim:
(newline)
"This soon-to-be world savior needs more booze!"
(newline)
The barman's lack of reaction is disappointing, but seeing the beer being
- poured does help improve the mood.
+ poured does improve your mood.
(newline)
Satisfied, you hand the barman (var price_of_booze) copper coins.
- (visit pay (var price_of_booze))
- (newline)
+ (visit! pay price_of_booze)
The barman sighs, then asks:
- (prompt_string (ptr hero_name) 2 64 What is your name, then, hero?)
+ (prompt_string! (ptr hero_name) 2 64 What is your name, then, hero?)
(var hero_name)?
(newline)
The barman looks surprised.
(newline)
- (visit lower_price_of_booze (ptr price_of_booze) 4)
+ (visit! lower_price_of_booze (ptr price_of_booze) 4)
(newline)
"I have heard of you, (var hero_name)," the barman exclaims, "I have a quest
for you!"
@@ -85,7 +80,7 @@ Given a pointer `p`, the variable being pointed to can be referred to using
)
{{< /fatecode >}}
-* `(prompt_string (ptr hero_name) 2 64 What is your name, then, hero?)` prompts
+* `(prompt_string! (ptr hero_name) 2 64 What is your name, then, hero?)` prompts
the player with `What is your name, then, hero?` and expects a string input
with a size between `2` and `64` characters. This input is stored at `(ptr
hero_name)`, which means that `hero_name` takes that value.
@@ -106,10 +101,9 @@ sheet, so [let's create one](/learn/structures).
(require data.fate)
(define_sequence pay ( (int cost) )
- (set hero_money
- (- (var hero_money) (var cost))
- )
+ (set! hero_money (- hero_money cost))
)
+
{{< /fatecode >}}
**falling_asleep.fate:**
@@ -125,17 +119,20 @@ sheet, so [let's create one](/learn/structures).
(newline)
Upon waking up, your hard-trained reflexes inform you that someone stole all
your money.
- (set hero_money 0)
+ (set! hero_money 0)
(newline)
- This set-back was more than you could take. You give up on this barely
+ This set-back was more than you could handle. You give up on this barely
coherent story.
- (end)
+ (end!)
)
{{< /fatecode >}}
**main.fate:**
{{< fatecode >}}(fate_version 1)
+(require get_a_refill.fate)
+(require falling_asleep.fate)
+
Once upon a time, starting a story with these words wasn't considered a cliche.
Starting in a tavern might also not be seen as very original. Having the main
character be an street orphan, raised by some mysterious sage all to end up as
@@ -149,19 +146,14 @@ anything. Worse, the alcoholic trait is part of the image.
As you contemplate your own pointless description, your gaze leaves what turns
out to be an already empty glass in your hand and finds the barman.
-(player_choice
- (
- ( Ask the barman for a refill )
- (visit get_a_refill)
+(player_choice!
+ (option ( Ask the barman for a refill )
+ (visit! get_a_refill)
)
- (
- ( Fall asleep )
- (jump_to fall_asleep)
+ (option ( Fall asleep )
+ (jump_to! fall_asleep)
)
)
-(require get_a_refill.fate)
-(require falling_asleep.fate)
-
-(end)
+(end!)
{{< /fatecode >}}
diff --git a/content/learn/07.structures/default.md b/content/learn/07.structures/default.md
index 8e2dede..fa6f17e 100644
--- a/content/learn/07.structures/default.md
+++ b/content/learn/07.structures/default.md
@@ -17,47 +17,52 @@ Fields of a structure can be accessed in two ways: using the
If `struct_ptr` is a pointer to a structure, `struct_ptr.field_name` will also
work.
-To set the value of a structure's fields, one can use the `set` instruction or,
+To set the value of a structure's fields, one can use the `set!` instruction or,
to set multiple fields at once, the `set_fields!` one. Note that omitting the
`!` at the end of `set_fields` is also valid Fate, but performs a computation
instead of a instruction: the structure is not modified, but a copy with the
modifications performed is returned.
+The name of user-defined types are expected to start with `#`. This ensures
+backward compatibility if a type with a similar name is introduced in a future
+(non-major) version of Fate. A warning will be raised during compilation if this
+convention is not upheld.
+
**data.fate:**
{{< fatecode >}}(fate_version 1)
-(declare_structure weapon
+(declare_structure #weapon
(text name)
(int attack)
(int precision)
)
-(declare_structure armor
+(declare_structure #armor
(text name)
(int defense)
)
-(declare_structure character
+(declare_structure #character
(string name)
(int money)
- (weapon weapon)
- (armor armor)
+ (#weapon weapon)
+ (#armor armor)
)
-(global character hero)
+(global #character hero)
-(set_fields! hero.weapon
+(struct:set_fields! hero.weapon
(name (text "Legendary" sword))
(attack 3)
(precision 50)
)
-(set_fields! hero.armor
+(struct:set_fields! hero.armor
(name (text "Refined" attire))
(defense 1)
)
-(set hero.money 42)
+(set! hero.money 42)
{{< /fatecode >}}
* `(text "Refined" attire)` generates a `text` value containing a textual
@@ -87,11 +92,8 @@ collection is available at the smithy](/learn/collections).
(int decrease)
)
Great! The price of booze just lowered from (at price_pointer)
- (set (at price_pointer)
- (-
- (at price_pointer)
- (var decrease)
- )
+ (set! (at price_pointer)
+ (- (at price_pointer) decrease)
)
to (at price_pointer)!
)
@@ -99,25 +101,24 @@ collection is available at the smithy](/learn/collections).
(define_sequence get_a_refill ()
(local int price_of_booze)
- (set price_of_booze 12)
+ (set! price_of_booze 12)
Staring straight at the barman, you raise your glass and proclaim:
(newline)
"This soon-to-be world savior needs more booze!"
(newline)
The barman's lack of reaction is disappointing, but seeing the beer being
- poured does help improve the mood.
+ poured does improve your mood.
(newline)
Satisfied, you hand the barman (var price_of_booze) copper coins.
- (visit pay (var price_of_booze))
- (newline)
+ (visit! pay price_of_booze)
The barman sighs, then asks:
- (prompt_string (ptr hero.name) 2 64 What is your name, then, hero?)
+ (prompt_string! (ptr hero.name) 2 64 What is your name, then, hero?)
(var hero.name)?
(newline)
The barman looks surprised.
(newline)
- (visit lower_price_of_booze (ptr price_of_booze) 4)
+ (visit! lower_price_of_booze (ptr price_of_booze) 4)
(newline)
"I have heard of you, (var hero.name)," the barman exclaims, "I have a quest
for you!"
@@ -137,14 +138,12 @@ collection is available at the smithy](/learn/collections).
(require data.fate)
(define_sequence pay ( (int cost) )
- (set hero_money
- (- (var hero.money) (var cost))
- )
+ (set! hero.money (- hero.money cost))
)
+
{{< /fatecode >}}
**falling_asleep.fate:**
-
{{< fatecode >}}(fate_version 1)
(require data.fate)
@@ -157,17 +156,21 @@ collection is available at the smithy](/learn/collections).
(newline)
Upon waking up, your hard-trained reflexes inform you that someone stole all
your money.
- (set hero.money 0)
+ (set! hero.money 0)
(newline)
- This set-back was more than you could take. You give up on this barely
+ This set-back was more than you could handle. You give up on this barely
coherent story.
- (end)
+ (end!)
)
{{< /fatecode >}}
**main.fate:**
{{< fatecode >}}(fate_version 1)
+(require get_a_refill.fate)
+(require falling_asleep.fate)
+
+
Once upon a time, starting a story with these words wasn't considered a cliche.
Starting in a tavern might also not be seen as very original. Having the main
character be an street orphan, raised by some mysterious sage all to end up as
@@ -181,19 +184,14 @@ anything. Worse, the alcoholic trait is part of the image.
As you contemplate your own pointless description, your gaze leaves what turns
out to be an already empty glass in your hand and finds the barman.
-(player_choice
- (
- ( Ask the barman for a refill )
- (visit get_a_refill)
+(player_choice!
+ (option ( Ask the barman for a refill )
+ (visit! get_a_refill)
)
- (
- ( Fall asleep )
- (jump_to fall_asleep)
+ (option ( Fall asleep )
+ (jump_to! fall_asleep)
)
)
-(require get_a_refill.fate)
-(require falling_asleep.fate)
-
-(end)
+k(end!)
{{< /fatecode >}}
diff --git a/content/learn/08.collections/default.md b/content/learn/08.collections/default.md
index 34310f3..57463e0 100644
--- a/content/learn/08.collections/default.md
+++ b/content/learn/08.collections/default.md
@@ -24,12 +24,12 @@ Let's add a new file, `smithy_inventory.fate`:
(require data.fate)
-(global (list (cons weapon int)) smithy_weapons)
-(global (list (cons weapon int)) smithy_armors)
+(global (list (cons #weapon int)) smithy_weapons)
+(global (list (cons #armor int)) smithy_armors)
-(add!
+(list:add!
(cons
- (set_fields (default weapon)
+ (struct:set_fields (default #weapon)
(name (text An Iron Rod))
(attack 10)
(precision 70)
@@ -38,9 +38,9 @@ Let's add a new file, `smithy_inventory.fate`:
)
smithy_weapons
)
-(add!
+(list:add!
(cons
- (set_fields (default weapon)
+ (struct:set_fields (default #weapon)
(name (text A Magnificient Brick))
(attack 6)
(precision 90)
@@ -50,19 +50,16 @@ Let's add a new file, `smithy_inventory.fate`:
smithy_weapons
)
-(add!
+(list:add!
(cons
- (set_fields (default armor)
+ (struct:set_fields (default #armor)
(name (text A raincoat?!))
(defense 7)
)
160
)
- smithy_armors
-)
-(add!
(cons
- (set_fields (default armor)
+ (struct:set_fields (default #armor)
(name (text A nice cape))
(defense 3)
)
@@ -75,8 +72,9 @@ Let's add a new file, `smithy_inventory.fate`:
We'll also need the actual smithy scene, so let's put in another file,
`smithy.fate`.
-**NOTE:** Don't worry if it looks awful at the moment, the next chapters are
-going to introduce a lot of things to make it *much*, *much* easier to write.
+**IMPORTANT NOTE:** Don't worry if it looks awful at the moment, the next
+chapters are going to introduce a lot of things to make it *much*, *much*
+easier to write.
**smithy.fate:**
{{< fatecode >}}(fate_version 1)
@@ -93,17 +91,14 @@ going to introduce a lot of things to make it *much*, *much* easier to write.
You have (var hero.money) coins.
(newline)
What will you look at?
- (player_choice
- (
- ( Let's see the weapons )
- (jump_to see_weapons)
+ (player_choice!
+ (option ( Let's see the weapons )
+ (jump_to! see_weapons)
)
- (
- ( Let's see the armors )
- (jump_to see_armors)
+ (option ( Let's see the armors )
+ (jump_to! see_armors)
)
- (
- ( Nothing, let's go back to the bar )
+ (option ( Nothing, let's go back to the bar )
)
)
)
@@ -114,29 +109,26 @@ going to introduce a lot of things to make it *much*, *much* easier to write.
(local text weapon_a_label)
(local text weapon_b_label)
- (visit get_weapon_label
- (access smithy_weapons 0)
+ (visit! get_weapon_label
+ (list:access 0 smithy_weapons)
(ptr weapon_a_label)
)
- (visit get_weapon_label
- (access smithy_weapons 1)
+ (visit! get_weapon_label
+ smithy_weapons.1
(ptr weapon_b_label)
)
- (player_choice
- (
- ( (var weapon_a_label) )
- (visit buy_weapon (access smithy_weapons 0))
- (jump_to visit_smithy)
+ (player_choice!
+ (option ( (var weapon_a_label) )
+ (visit! buy_weapon smithy_weapons.0)
+ (jump_to! visit_smithy)
)
- (
- ( (var weapon_a_label) )
- (visit buy_weapon (access smithy_weapons 1))
- (jump_to visit_smithy)
+ (option ( (var weapon_b_label) )
+ (visit! buy_weapon (list:access 1 smithy_weapons))
+ (jump_to! visit_smithy)
)
- (
- ( Nevermind )
- (jump_to visit_smithy)
+ (option ( Nevermind )
+ (jump_to! visit_smithy)
)
)
)
@@ -147,29 +139,26 @@ going to introduce a lot of things to make it *much*, *much* easier to write.
(local text armor_a_label)
(local text armor_b_label)
- (visit get_armor_label
- (access smithy_armors 0)
+ (visit! get_armor_label
+ smithy_armors.0
(ptr armor_a_label)
)
- (visit get_armor_label
- (access smithy_armors 1)
+ (visit! get_armor_label
+ smithy_armors.1
(ptr armor_b_label)
)
- (player_choice
- (
- ( (var armor_a_label) )
- (visit buy_armor (access smithy_armors 0))
- (jump_to visit_smithy)
+ (player_choice!
+ (option ( (var armor_a_label) )
+ (visit! buy_armor smithy_armors.0)
+ (jump_to! visit_smithy)
)
- (
- ( (var armor_a_label) )
- (visit buy_armor (access smithy_armors 1))
- (jump_to visit_smithy)
+ (option ( (var armor_b_label) )
+ (visit! buy_armor smithy_armors.1)
+ (jump_to! visit_smithy)
)
- (
- ( Nevermind )
- (jump_to visit_smithy)
+ (option ( Nevermind )
+ (jump_to! visit_smithy)
)
)
)
@@ -177,19 +166,19 @@ going to introduce a lot of things to make it *much*, *much* easier to write.
;; A terrible way to get labels
(define_sequence get_weapon_label
(
- ((cons weapon int) weapon_offer)
+ ((cons #weapon int) weapon_offer)
((ptr text) label)
)
- (local weapon weapon)
+ (local #weapon weapon)
(local int price)
- (set weapon (car weapon_offer))
- (set price (cdr weapon_offer))
+ (set! weapon (car weapon_offer))
+ (set! price (cdr weapon_offer))
- (set (at label)
- (
- Buy "(var weapon.name)" \(attack: (var weapon.attack),
- precision: (var weapon.precision)\) for (var price) coins.
+ (set! (at label)
+ (text
+ Buy "(var weapon.name)" (lp)attack: (var weapon.attack),
+ precision: (var weapon.precision)(rp) for (var price) coins.
)
)
)
@@ -197,90 +186,98 @@ going to introduce a lot of things to make it *much*, *much* easier to write.
;; A terrible way to get labels
(define_sequence get_armor_label
(
- ((cons armor int) armor_offer)
+ ((cons #armor int) armor_offer)
((ptr text) label)
)
- (local armor armor)
+ (local #armor armor)
(local int price)
- (set armor (car armor_offer))
- (set price (cdr armor_offer))
+ (set! armor (car armor_offer))
+ (set! price (cdr armor_offer))
- (set (at label)
- (
- Buy "(var armor.name)" \(defense: (var armor.defense)\),
+ (set! (at label)
+ (text
+ Buy "(var armor.name)" (lp)defense: (var armor.defense)(rp),
for (var price) coins.
)
)
)
-(define_sequence buy_weapon ( ((cons weapon int) weapon) )
+(define_sequence buy_weapon ( ((cons #weapon int) weapon) )
;; We can't even deny a sell yet...
- (set hero.weapon (car weapon))
+ (set! hero.weapon (car weapon))
Equipped (var hero.weapon.name).
(newline)
)
-(define_sequence buy_armor ( ((cons armor int) armor) )
+(define_sequence buy_armor ( ((cons #armor int) armor) )
;; We can't even deny a sell yet...
- (set hero.armor (car armor))
+ (set! hero.armor (car armor))
Equipped (var hero.armor.name).
(newline)
)
{{< /fatecode >}}
+Now, add `(require smithy.fate)` at the start of the **get_a_refill.fate**
+file, then add `(visit! visit_smithy)` at the end of the `get_a_refill`
+sequence, so that our hero indeed goes to visit this great shop.
+
* `(list (cons weapon int))` indicates a list of `weapon` and `int` pairs.
-* `(add! something smithy_weapons)` adds `something` to the `smithy_weapons`
- collection. Without the `!`, this would be a computation returning a copy of
- `smithy_weapons` with the added weapon, but no modification of the
- `smithy_weapons` collection itself would occur.
+* `(list:add! something smithy_weapons)` adds `something` to the
+ `smithy_weapons` collection. Without the `!`, this would be a computation
+ returning a copy of `smithy_weapons` with the added weapon, but no
+ modification of the `smithy_weapons` collection itself would occur. You can
+ have multiple `something` to add to the same list in the same `list:add` call.
+* `(list:access 0 my_list)` gets you the first element of `my_list`. If the
+ index is a constant, it is preferable to write `my_list.0` instead.
* `(cons something something_else)` creates a pair with these two elements.
* `(car weapon_offer)` returns the first element of the `weapon_offer` pair.
* `(cdr weapon_offer)` returns the second element of the `weapon_offer` pair.
+
Overall, the `smithy.fate` file is a mess. Let's start cleaning it up. We'll
use loops, conditionals, and lambda functions to make it much cleaner. Let's
start with the least expected one: [lambda functions](/learn/lambdas).
----
-## Unchanged Files
+## (Mostly) Unchanged Files
**data.fate:**
{{< fatecode >}}(fate_version 1)
-(declare_structure weapon
+(declare_structure #weapon
(text name)
(int attack)
(int precision)
)
-(declare_structure armor
+(declare_structure #armor
(text name)
(int defense)
)
-(declare_structure character
+(declare_structure #character
(string name)
(int money)
- (weapon weapon)
- (armor armor)
+ (#weapon weapon)
+ (#armor armor)
)
-(global character hero)
+(global #character hero)
-(set_fields! hero.weapon
+(struct:set_fields! hero.weapon
(name (text "Legendary" sword))
(attack 3)
(precision 50)
)
-(set_fields! hero.armor
+(struct:set_fields! hero.armor
(name (text "Refined" attire))
(defense 1)
)
-(set hero.money 42)
+(set! hero.money 42)
{{< /fatecode >}}
**get_a_refill.fate:**
@@ -288,6 +285,7 @@ start with the least expected one: [lambda functions](/learn/lambdas).
(require data.fate)
(require actions.fate)
+(require smithy.fate)
(define_sequence lower_price_of_booze
(
@@ -295,11 +293,8 @@ start with the least expected one: [lambda functions](/learn/lambdas).
(int decrease)
)
Great! The price of booze just lowered from (at price_pointer)
- (set (at price_pointer)
- (-
- (at price_pointer)
- (var decrease)
- )
+ (set! (at price_pointer)
+ (- (at price_pointer) decrease)
)
to (at price_pointer)!
)
@@ -307,25 +302,24 @@ start with the least expected one: [lambda functions](/learn/lambdas).
(define_sequence get_a_refill ()
(local int price_of_booze)
- (set price_of_booze 12)
+ (set! price_of_booze 12)
Staring straight at the barman, you raise your glass and proclaim:
(newline)
"This soon-to-be world savior needs more booze!"
(newline)
The barman's lack of reaction is disappointing, but seeing the beer being
- poured does help improve the mood.
+ poured does improve your mood.
(newline)
Satisfied, you hand the barman (var price_of_booze) copper coins.
- (visit pay (var price_of_booze))
- (newline)
+ (visit! pay price_of_booze)
The barman sighs, then asks:
- (prompt_string (ptr hero.name) 2 64 What is your name, then, hero?)
+ (prompt_string! (ptr hero.name) 2 64 What is your name, then, hero?)
(var hero.name)?
(newline)
The barman looks surprised.
(newline)
- (visit lower_price_of_booze (ptr price_of_booze) 4)
+ (visit! lower_price_of_booze (ptr price_of_booze) 4)
(newline)
"I have heard of you, (var hero.name)," the barman exclaims, "I have a quest
for you!"
@@ -336,6 +330,7 @@ start with the least expected one: [lambda functions](/learn/lambdas).
(newline)
"Take this pre-payment and head to the smithy."
(newline)
+ (visit! visit_smithy)
)
{{< /fatecode >}}
@@ -345,10 +340,9 @@ start with the least expected one: [lambda functions](/learn/lambdas).
(require data.fate)
(define_sequence pay ( (int cost) )
- (set hero_money
- (- (var hero.money) (var cost))
- )
+ (set! hero.money (- hero.money cost))
)
+
{{< /fatecode >}}
**falling_asleep.fate:**
@@ -364,17 +358,20 @@ start with the least expected one: [lambda functions](/learn/lambdas).
(newline)
Upon waking up, your hard-trained reflexes inform you that someone stole all
your money.
- (set hero.money 0)
+ (set! hero.money 0)
(newline)
- This set-back was more than you could take. You give up on this barely
+ This set-back was more than you could handle. You give up on this barely
coherent story.
- (end)
+ (end!)
)
{{< /fatecode >}}
**main.fate:**
{{< fatecode >}}(fate_version 1)
+(require get_a_refill.fate)
+(require falling_asleep.fate)
+
Once upon a time, starting a story with these words wasn't considered a cliche.
Starting in a tavern might also not be seen as very original. Having the main
character be an street orphan, raised by some mysterious sage all to end up as
@@ -388,19 +385,14 @@ anything. Worse, the alcoholic trait is part of the image.
As you contemplate your own pointless description, your gaze leaves what turns
out to be an already empty glass in your hand and finds the barman.
-(player_choice
- (
- ( Ask the barman for a refill )
- (visit get_a_refill)
+(player_choice!
+ (option ( Ask the barman for a refill )
+ (visit! get_a_refill)
)
- (
- ( Fall asleep )
- (jump_to fall_asleep)
+ (option ( Fall asleep )
+ (jump_to! fall_asleep)
)
)
-(require get_a_refill.fate)
-(require falling_asleep.fate)
-
-(end)
+(end!)
{{< /fatecode >}}
diff --git a/content/learn/09.lambdas/default.md b/content/learn/09.lambdas/default.md
index 91d5660..8119639 100644
--- a/content/learn/09.lambdas/default.md
+++ b/content/learn/09.lambdas/default.md
@@ -17,35 +17,36 @@ memory by itself, nor can it contain any instructions.
(require smithy_inventory.fate)
-(global (lambda text ((cons weapon int))) get_weapon_offer_label)
-(global (lambda text ((cons armor int))) get_armor_offer_label)
+;; Maybe it would be better to put this in a different file, but oh well...
+(global (lambda text ((cons #weapon int))) get_weapon_offer_label)
+(global (lambda text ((cons #armor int))) get_armor_offer_label)
-(set get_weapon_offer_label
+(set! get_weapon_offer_label
(lambda
- ( ((cons weapon int) offer) )
+ ( ((cons #weapon int) offer) )
(let
(
(weapon (car offer))
(price (cdr offer))
)
(text
- Buy "(var weapon.name)" \(attack: (var weapon.attack),
- precision: (var weapon.precision)\) for (var price) coins.
+ Buy "(var weapon.name)" (lp)attack: (var weapon.attack),
+ precision: (var weapon.precision)(rp) for (var price) coins.
)
)
)
)
-(set get_armor_offer_label
+(set! get_armor_offer_label
(lambda
- ( ((cons armor int) offer) )
+ ( ((cons #armor int) offer) )
(let
(
(armor (car offer))
(price (cdr offer))
)
(text
- Buy "(var armor.name)" \(defense: (var armor.defense)\),
+ Buy "(var armor.name)" (lp)defense: (var armor.defense)(rp),
for (var price) coins.
)
)
@@ -62,71 +63,64 @@ memory by itself, nor can it contain any instructions.
You have (var hero.money) coins.
(newline)
What will you look at?
- (player_choice
- (
- ( Let's see the weapons )
- (jump_to see_weapons)
+ (player_choice!
+ (option ( Let's see the weapons )
+ (jump_to! see_weapons)
)
- (
- ( Let's see the armors )
- (jump_to see_armors)
+ (option ( Let's see the armors )
+ (jump_to! see_armors)
)
- (
- ( Nothing, let's go back to the bar )
+ (option ( Nothing, let's go back to the bar )
)
)
)
(define_sequence see_weapons ()
- ;; Still can be improved.
- (player_choice
- (
- ( (eval get_weapon_offer_label (access smithy_weapons 0)) )
- (visit buy_weapon (access smithy_weapons 0))
- (jump_to visit_smithy)
+ ;; We'll improve it further once we get to loops.
+
+ (player_choice!
+ (option ( (eval get_weapon_offer_label smithy_weapons.0) )
+ (visit! buy_weapon smithy_weapons.0)
+ (jump_to! visit_smithy)
)
- (
- ( (eval get_weapon_offer_label (access smithy_weapons 1)) )
- (visit buy_weapon (access smithy_weapons 1))
- (jump_to visit_smithy)
+ (option ( (eval get_weapon_offer_label smithy_weapons.1) )
+ (visit! buy_weapon smithy_weapons.1)
+ (jump_to! visit_smithy)
)
- (
- ( Nevermind )
- (jump_to visit_smithy)
+ (option ( Nevermind )
+ (jump_to! visit_smithy)
)
)
)
(define_sequence see_armors ()
- ;; Still can be improved.
- (player_choice
- (
- ( (eval get_armor_offer_label (access smithy_armors 0)) )
- (visit buy_armor (access smithy_armors 0))
- (jump_to visit_smithy)
+ ;; We'll improve it further once we get to loops.
+
+ (player_choice!
+ (option ( (eval get_armor_offer_label smithy_armors.0) )
+ (visit! buy_armor smithy_armors.0)
+ (jump_to! visit_smithy)
)
- (
- ( (eval get_armor_offer_label (access smithy_armors 1)) )
- (visit buy_armor (access smithy_armors 1))
- (jump_to visit_smithy)
+ (option ( (eval get_armor_offer_label smithy_armors.1) )
+ (visit! buy_armor smithy_armors.1)
+ (jump_to! visit_smithy)
)
- (
- ( Nevermind )
- (jump_to visit_smithy)
+ (option ( Nevermind )
+ (jump_to! visit_smithy)
)
)
)
-(define_sequence buy_weapon ( ((cons weapon int) weapon) )
- ;; We can't even deny a sell yet...
- (set hero.weapon (car weapon))
+(define_sequence buy_weapon ( ((cons #weapon int) weapon) )
+ ;; We still can't even deny a sell...
+ (set! hero.weapon (car weapon))
Equipped (var hero.weapon.name).
(newline)
)
-(define_sequence buy_armor ( ((cons armor int) armor) )
- ;; We can't even deny a sell yet...
- (set hero.armor (car armor))
+(define_sequence buy_armor ( ((cons #armor int) armor) )
+ ;; We still can't even deny a sell...
+ (set! hero.armor (car armor))
Equipped (var hero.armor.name).
(newline)
)
@@ -154,38 +148,38 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
**data.fate:**
{{< fatecode >}}(fate_version 1)
-(declare_structure weapon
+(declare_structure #weapon
(text name)
(int attack)
(int precision)
)
-(declare_structure armor
+(declare_structure #armor
(text name)
(int defense)
)
-(declare_structure character
+(declare_structure #character
(string name)
(int money)
- (weapon weapon)
- (armor armor)
+ (#weapon weapon)
+ (#armor armor)
)
-(global character hero)
+(global #character hero)
-(set_fields! hero.weapon
+(struct:set_fields! hero.weapon
(name (text "Legendary" sword))
(attack 3)
(precision 50)
)
-(set_fields! hero.armor
+(struct:set_fields! hero.armor
(name (text "Refined" attire))
(defense 1)
)
-(set hero.money 42)
+(set! hero.money 42)
{{< /fatecode >}}
**get_a_refill.fate:**
@@ -193,6 +187,7 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(require data.fate)
(require actions.fate)
+(require smithy.fate)
(define_sequence lower_price_of_booze
(
@@ -200,11 +195,8 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(int decrease)
)
Great! The price of booze just lowered from (at price_pointer)
- (set (at price_pointer)
- (-
- (at price_pointer)
- (var decrease)
- )
+ (set! (at price_pointer)
+ (- (at price_pointer) decrease)
)
to (at price_pointer)!
)
@@ -212,25 +204,24 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(define_sequence get_a_refill ()
(local int price_of_booze)
- (set price_of_booze 12)
+ (set! price_of_booze 12)
Staring straight at the barman, you raise your glass and proclaim:
(newline)
"This soon-to-be world savior needs more booze!"
(newline)
The barman's lack of reaction is disappointing, but seeing the beer being
- poured does help improve the mood.
+ poured does improve your mood.
(newline)
Satisfied, you hand the barman (var price_of_booze) copper coins.
- (visit pay (var price_of_booze))
- (newline)
+ (visit! pay price_of_booze)
The barman sighs, then asks:
- (prompt_string (ptr hero.name) 2 64 What is your name, then, hero?)
+ (prompt_string! (ptr hero.name) 2 64 What is your name, then, hero?)
(var hero.name)?
(newline)
The barman looks surprised.
(newline)
- (visit lower_price_of_booze (ptr price_of_booze) 4)
+ (visit! lower_price_of_booze (ptr price_of_booze) 4)
(newline)
"I have heard of you, (var hero.name)," the barman exclaims, "I have a quest
for you!"
@@ -241,6 +232,7 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(newline)
"Take this pre-payment and head to the smithy."
(newline)
+ (visit! visit_smithy)
)
{{< /fatecode >}}
@@ -250,9 +242,7 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(require data.fate)
(define_sequence pay ( (int cost) )
- (set hero_money
- (- (var hero.money) (var cost))
- )
+ (set! hero.money (- hero.money cost))
)
{{< /fatecode >}}
@@ -269,17 +259,20 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(newline)
Upon waking up, your hard-trained reflexes inform you that someone stole all
your money.
- (set hero.money 0)
+ (set! hero.money 0)
(newline)
- This set-back was more than you could take. You give up on this barely
+ This set-back was more than you could handle. You give up on this barely
coherent story.
- (end)
+ (end!)
)
{{< /fatecode >}}
**main.fate:**
{{< fatecode >}}(fate_version 1)
+(require get_a_refill.fate)
+(require falling_asleep.fate)
+
Once upon a time, starting a story with these words wasn't considered a cliche.
Starting in a tavern might also not be seen as very original. Having the main
character be an street orphan, raised by some mysterious sage all to end up as
@@ -293,21 +286,16 @@ anything. Worse, the alcoholic trait is part of the image.
As you contemplate your own pointless description, your gaze leaves what turns
out to be an already empty glass in your hand and finds the barman.
-(player_choice
- (
- ( Ask the barman for a refill )
- (visit get_a_refill)
+(player_choice!
+ (option ( Ask the barman for a refill )
+ (visit! get_a_refill)
)
- (
- ( Fall asleep )
- (jump_to fall_asleep)
+ (option ( Fall asleep )
+ (jump_to! fall_asleep)
)
)
-(require get_a_refill.fate)
-(require falling_asleep.fate)
-
-(end)
+(end!)
{{< /fatecode >}}
**smithy_inventory.fate:**
@@ -315,12 +303,12 @@ out to be an already empty glass in your hand and finds the barman.
(require data.fate)
-(global (list (cons weapon int)) smithy_weapons)
-(global (list (cons weapon int)) smithy_armors)
+(global (list (cons #weapon int)) smithy_weapons)
+(global (list (cons #armor int)) smithy_armors)
-(add!
+(list:add!
(cons
- (set_fields (default weapon)
+ (struct:set_fields (default #weapon)
(name (text An Iron Rod))
(attack 10)
(precision 70)
@@ -329,9 +317,9 @@ out to be an already empty glass in your hand and finds the barman.
)
smithy_weapons
)
-(add!
+(list:add!
(cons
- (set_fields (default weapon)
+ (struct:set_fields (default #weapon)
(name (text A Magnificient Brick))
(attack 6)
(precision 90)
@@ -341,19 +329,16 @@ out to be an already empty glass in your hand and finds the barman.
smithy_weapons
)
-(add!
+(list:add!
(cons
- (set_fields (default armor)
+ (struct:set_fields (default #armor)
(name (text A raincoat?!))
(defense 7)
)
160
)
- smithy_armors
-)
-(add!
(cons
- (set_fields (default armor)
+ (struct:set_fields (default #armor)
(name (text A nice cape))
(defense 3)
)
diff --git a/content/learn/10.conditions/default.md b/content/learn/10.conditions/default.md
index 0b449b4..9125a14 100644
--- a/content/learn/10.conditions/default.md
+++ b/content/learn/10.conditions/default.md
@@ -23,155 +23,150 @@ can be used both as instruction and computation. `if` is only for instructions.
* `if` is only for instructions, and applies its content only if the condition
is verified.
-All of these can be used within a `player_choice` to control what options are
+All of these can be used within a `player_choice!` to control what options are
available.
+Let's start our changes by checking if this is the player's first visit to the
+smithy, as there is no need to give a detailed description of the place if it
+is not. We can also use conditions to check if the player is able to purchase
+items:
+
**smithy.fate:**
{{< fatecode >}}(fate_version 1)
(require smithy_inventory.fate)
-(global (lambda text ((cons weapon int))) get_weapon_offer_label)
-(global (lambda text ((cons armor int))) get_armor_offer_label)
+;; Maybe it would be better to put this in a different file, but oh well...
+(global (lambda text ((cons #weapon int))) get_weapon_offer_label)
+(global (lambda text ((cons #armor int))) get_armor_offer_label)
-(set get_weapon_offer_label
+(set! get_weapon_offer_label
(lambda
- ( ((cons weapon int) offer) )
+ ( ((cons #weapon int) offer) )
(let
(
(weapon (car offer))
(price (cdr offer))
)
(text
- Buy "(var weapon.name)" \(attack: (var weapon.attack),
- precision: (var weapon.precision)\) for (var price) coins.
+ Buy "(var weapon.name)" (lp)attack: (var weapon.attack),
+ precision: (var weapon.precision)(rp) for (var price) coins.
)
)
)
)
-(set get_armor_offer_label
+(set! get_armor_offer_label
(lambda
- ( ((cons armor int) offer) )
+ ( ((cons #armor int) offer) )
(let
(
(armor (car offer))
(price (cdr offer))
)
(text
- Buy "(var armor.name)" \(defense: (var armor.defense)\),
+ Buy "(var armor.name)" (lp)defense: (var armor.defense)(rp),
for (var price) coins.
)
)
)
)
-(global bool has_visited_smithy)
-
-(set has_visited_smithy (false))
+(global bool has_visited_smithy (false))
(define_sequence visit_smithy ()
- (if (not (var has_visited_smithy))
+ (if (not has_visited_smithy)
As you approach the smithy, you notice that no one's there. All the wares
are out for selling. It's almost as if this story didn't need more
examples of lengthy dialogues.
(newline)
- (set has_visited_smithy (true))
+ (set! has_visited_smithy (true))
)
You have (var hero.money) coins.
(newline)
What will you look at?
- (player_choice
- (
- ( Let's see the weapons )
- (jump_to see_weapons)
+ (player_choice!
+ (option ( Let's see the weapons )
+ (jump_to! see_weapons)
)
- (
- ( Let's see the armors )
- (jump_to see_armors)
+ (option ( Let's see the armors )
+ (jump_to! see_armors)
)
- (
- ( Nothing, let's go back to the bar )
+ (option ( Nothing, let's go back to the bar )
)
)
)
(define_sequence see_weapons ()
- ;; Still can be improved.
- (player_choice
- (
- ( (eval get_weapon_offer_label (access smithy_weapons 0)) )
- (visit buy_weapon (access smithy_weapons 0))
- (jump_to visit_smithy)
+ ;; We'll improve it further once we get to loops.
+
+ (player_choice!
+ (option ( (eval get_weapon_offer_label smithy_weapons.0) )
+ (visit! buy_weapon smithy_weapons.0)
+ (jump_to! visit_smithy)
)
- (
- ( (eval get_weapon_offer_label (access smithy_weapons 1)) )
- (visit buy_weapon (access smithy_weapons 1))
- (jump_to visit_smithy)
+ (option ( (eval get_weapon_offer_label smithy_weapons.1) )
+ (visit! buy_weapon smithy_weapons.1)
+ (jump_to! visit_smithy)
)
- (
- ( Nevermind )
- (jump_to visit_smithy)
+ (option ( Nevermind )
+ (jump_to! visit_smithy)
)
)
)
(define_sequence see_armors ()
- ;; Still can be improved.
- (player_choice
- (
- ( (eval get_armor_offer_label (access smithy_armors 0)) )
- (visit buy_armor (access smithy_armors 0))
- (jump_to visit_smithy)
+ ;; We'll improve it further once we get to loops.
+
+ (player_choice!
+ (option ( (eval get_armor_offer_label smithy_armors.0) )
+ (visit! buy_armor smithy_armors.0)
+ (jump_to! visit_smithy)
)
- (
- ( (eval get_armor_offer_label (access smithy_armors 1)) )
- (visit buy_armor (access smithy_armors 1))
- (jump_to visit_smithy)
+ (option ( (eval get_armor_offer_label smithy_armors.1) )
+ (visit! buy_armor smithy_armors.1)
+ (jump_to! visit_smithy)
)
- (
- ( Nevermind )
- (jump_to visit_smithy)
+ (option ( Nevermind )
+ (jump_to! visit_smithy)
)
)
)
-(define_sequence buy_weapon ( ((cons weapon int) weapon) )
- ;; We can't even deny a sell yet...
+(define_sequence buy_weapon ( ((cons #weapon int) weapon) )
(local int money_after)
- (set money_after (- (var hero.money) (cdr weapon)))
+ (set! money_after (- hero.money (cdr weapon)))
- (if_else (< (var money_after) 0)
+ (if_else (< money_after 0)
(
You can't afford that.
(newline)
- You would need (abs (var money_after)) more coins.
+ You would need (abs money_after) more coins.
)
(
- (set hero.weapon (car weapon))
- (set hero.money (var money_after))
+ (set! hero.weapon (car weapon))
+ (set! hero.money money_after)
Equipped (var hero.weapon.name).
)
)
(newline)
)
-(define_sequence buy_armor ( ((cons armor int) armor) )
- ;; We can't even deny a sell yet...
+(define_sequence buy_armor ( ((cons #armor int) armor) )
(local int money_after)
- (set money_after (- (var hero.money) (cdr armor)))
+ (set! money_after (- hero.money (cdr armor)))
- (if_else (< (var money_after) 0)
+ (if_else (< money_after 0)
(
You can't afford that.
(newline)
- You would need (abs (var money_after)) more coins.
+ You would need (abs money_after) more coins.
)
(
- (set hero.armor (car armor))
- (set hero.money (var money_after))
+ (set! hero.armor (car armor))
+ (set! hero.money money_after)
Equipped (var hero.armor.name).
)
)
@@ -179,9 +174,126 @@ available.
)
{{< /fatecode >}}
+To showcase a use of `cond`, we'll add some checks that tell the player how well
+they did:
+
+**main.fate:**
+{{< fatecode >}}(fate_version 1)
+
+(require get_a_refill.fate)
+(require falling_asleep.fate)
+
+Once upon a time, starting a story with these words wasn't considered a cliche.
+Starting in a tavern might also not be seen as very original. Having the main
+character be an street orphan, raised by some mysterious sage all to end up as
+a mercenary with an uncommonly strong sense of honor probably isn't going to
+lead to any praises for novelty either. Maybe you should drink to that.
+(newline)
+Or maybe you shouldn't. This isn't your first mug. Not your second either.
+Drinking to forget that you are a stereotypical hero isn't going to solve
+anything. Worse, the alcoholic trait is part of the image.
+(newline)
+As you contemplate your own pointless description, your gaze leaves what turns
+out to be an already empty glass in your hand and finds the barman.
+
+(player_choice!
+ (option ( Ask the barman for a refill )
+ (visit! get_a_refill)
+ )
+ (option ( Fall asleep )
+ (jump_to! fall_asleep)
+ )
+)
+
+;; Let's analyze how well the player did
+(cond
+ ((> hero.weapon.attack 7)
+ Your feel ready to strike down any challenge.
+ )
+ ((>= hero.armor.defense 7)
+ Your feel invincible.
+ )
+ ((>= hero.money 50)
+ You feel good about having spent your coins sparingly.
+ )
+ ((true)
+ You feel like you wasted your evening.
+ )
+)
+(end!)
+{{< /fatecode >}}
+
+Lastly, we can have an example of `switch` by having the barman react to certain
+hero names. Note that `The barman looks surprised` corresponds to the default
+branch of that switch.
+
+**get_a_refill.fate:**
+{{< fatecode >}}(fate_version 1)
+
+(require data.fate)
+(require actions.fate)
+(require smithy.fate)
+
+(define_sequence lower_price_of_booze
+ (
+ ((ptr int) price_pointer)
+ (int decrease)
+ )
+ Great! The price of booze just lowered from (at price_pointer)
+ (set! (at price_pointer)
+ (- (at price_pointer) decrease)
+ )
+ to (at price_pointer)!
+)
+
+(define_sequence get_a_refill ()
+ (local int price_of_booze)
+
+ (set! price_of_booze 12)
+
+ Staring straight at the barman, you raise your glass and proclaim:
+ (newline)
+ "This soon-to-be world savior needs more booze!"
+ (newline)
+ The barman's lack of reaction is disappointing, but seeing the beer being
+ poured does improve your mood.
+ (newline)
+ Satisfied, you hand the barman (var price_of_booze) copper coins.
+ (visit! pay price_of_booze)
+ The barman sighs, then asks:
+ (prompt_string! (ptr hero.name) 2 64 What is your name, then, hero?)
+ "(var hero.name)?"
+ (newline)
+ (switch hero.name
+ (Fred
+ You brace for the inevitable mockery.
+ )
+ (Link
+ You show the back of your hand to the barman.
+ )
+ ((string Lancelot of Camelot)
+ You place halves of a coconut shell on the bar.
+ )
+ The barman looks surprised.
+ )
+ (newline)
+ (visit! lower_price_of_booze (ptr price_of_booze) 4)
+ (newline)
+ "I have heard of you, (var hero.name)," the barman exclaims, "I have a quest
+ for you!"
+ (newline)
+ It's your turn to sigh.
+ (newline)
+ The barman hands you a bag, and says:
+ (newline)
+ "Take this pre-payment and head to the smithy."
+ (newline)
+ (visit! visit_smithy)
+)
+{{< /fatecode >}}
This was a first step toward cleaning up `smithy.fate`. Next, we'll use
-[conditions](/learn/conditions) to improve things further.
+[loops](/learn/loops) to improve things further.
----
@@ -190,38 +302,39 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
**data.fate:**
{{< fatecode >}}(fate_version 1)
-(declare_structure weapon
+(declare_structure #weapon
(text name)
(int attack)
(int precision)
)
-(declare_structure armor
+(declare_structure #armor
(text name)
(int defense)
)
-(declare_structure character
+(declare_structure #character
(string name)
(int money)
- (weapon weapon)
- (armor armor)
+ (#weapon weapon)
+ (#armor armor)
)
-(global character hero)
+(global #character hero)
-(set_fields! hero.weapon
+(struct:set_fields! hero.weapon
(name (text "Legendary" sword))
(attack 3)
(precision 50)
)
-(set_fields! hero.armor
+(struct:set_fields! hero.armor
(name (text "Refined" attire))
(defense 1)
)
-(set hero.money 42)
+(set! hero.money 200)
+
{{< /fatecode >}}
**get_a_refill.fate:**
@@ -229,6 +342,7 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(require data.fate)
(require actions.fate)
+(require smithy.fate)
(define_sequence lower_price_of_booze
(
@@ -236,11 +350,8 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(int decrease)
)
Great! The price of booze just lowered from (at price_pointer)
- (set (at price_pointer)
- (-
- (at price_pointer)
- (var decrease)
- )
+ (set! (at price_pointer)
+ (- (at price_pointer) decrease)
)
to (at price_pointer)!
)
@@ -248,25 +359,24 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(define_sequence get_a_refill ()
(local int price_of_booze)
- (set price_of_booze 12)
+ (set! price_of_booze 12)
Staring straight at the barman, you raise your glass and proclaim:
(newline)
"This soon-to-be world savior needs more booze!"
(newline)
The barman's lack of reaction is disappointing, but seeing the beer being
- poured does help improve the mood.
+ poured does improve your mood.
(newline)
Satisfied, you hand the barman (var price_of_booze) copper coins.
- (visit pay (var price_of_booze))
- (newline)
+ (visit! pay price_of_booze)
The barman sighs, then asks:
- (prompt_string (ptr hero.name) 2 64 What is your name, then, hero?)
+ (prompt_string! (ptr hero.name) 2 64 What is your name, then, hero?)
(var hero.name)?
(newline)
The barman looks surprised.
(newline)
- (visit lower_price_of_booze (ptr price_of_booze) 4)
+ (visit! lower_price_of_booze (ptr price_of_booze) 4)
(newline)
"I have heard of you, (var hero.name)," the barman exclaims, "I have a quest
for you!"
@@ -277,7 +387,9 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(newline)
"Take this pre-payment and head to the smithy."
(newline)
+ (visit! visit_smithy)
)
+
{{< /fatecode >}}
**actions.fate:**
@@ -286,9 +398,7 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(require data.fate)
(define_sequence pay ( (int cost) )
- (set hero_money
- (- (var hero.money) (var cost))
- )
+ (set! hero.money (- hero.money cost))
)
{{< /fatecode >}}
@@ -305,17 +415,20 @@ This was a first step toward cleaning up `smithy.fate`. Next, we'll use
(newline)
Upon waking up, your hard-trained reflexes inform you that someone stole all
your money.
- (set hero.money 0)
+ (set! hero.money 0)
(newline)
- This set-back was more than you could take. You give up on this barely
+ This set-back was more than you could handle. You give up on this barely
coherent story.
- (end)
+ (end!)
)
{{< /fatecode >}}
**main.fate:**
{{< fatecode >}}(fate_version 1)
+(require get_a_refill.fate)
+(require falling_asleep.fate)
+
Once upon a time, starting a story with these words wasn't considered a cliche.
Starting in a tavern might also not be seen as very original. Having the main
character be an street orphan, raised by some mysterious sage all to end up as
@@ -329,21 +442,17 @@ anything. Worse, the alcoholic trait is part of the image.
As you contemplate your own pointless description, your gaze leaves what turns
out to be an already empty glass in your hand and finds the barman.
-(player_choice
- (
- ( Ask the barman for a refill )
- (visit get_a_refill)
+(player_choice!
+ (option ( Ask the barman for a refill )
+ (visit! get_a_refill)
)
- (
- ( Fall asleep )
- (jump_to fall_asleep)
+ (option ( Fall asleep )
+ (jump_to! fall_asleep)
)
)
-(require get_a_refill.fate)
-(require falling_asleep.fate)
+(end!)
-(end)
{{< /fatecode >}}
**smithy_inventory.fate:**
@@ -351,12 +460,12 @@ out to be an already empty glass in your hand and finds the barman.
(require data.fate)
-(global (list (cons weapon int)) smithy_weapons)
-(global (list (cons weapon int)) smithy_armors)
+(global (list (cons #weapon int)) smithy_weapons)
+(global (list (cons #armor int)) smithy_armors)
-(add!
+(list:add!
(cons
- (set_fields (default weapon)
+ (struct:set_fields (default #weapon)
(name (text An Iron Rod))
(attack 10)
(precision 70)
@@ -365,9 +474,9 @@ out to be an already empty glass in your hand and finds the barman.
)
smithy_weapons
)
-(add!
+(list:add!
(cons
- (set_fields (default weapon)
+ (struct:set_fields (default #weapon)
(name (text A Magnificient Brick))
(attack 6)
(precision 90)
@@ -377,19 +486,16 @@ out to be an already empty glass in your hand and finds the barman.
smithy_weapons
)
-(add!
+(list:add!
(cons
- (set_fields (default armor)
+ (struct:set_fields (default #armor)
(name (text A raincoat?!))
(defense 7)
)
160
)
- smithy_armors
-)
-(add!
(cons
- (set_fields (default armor)
+ (struct:set_fields (default #armor)
(name (text A nice cape))
(defense 3)
)
diff --git a/content/learn/11.loops/default.md b/content/learn/11.loops/default.md
new file mode 100644
index 0000000..26aa949
--- /dev/null
+++ b/content/learn/11.loops/default.md
@@ -0,0 +1,457 @@
+---
+menuTitle: Loops
+title: "Doing Things Over and Over"
+weight: 11
+---
+[The previous step](/learn/conditions) introduced conditions, making it
+possible to change the flow of execution according to the value of variables.
+In this step, we look at loops, which will make instructions be executed a
+certain number time depending on a condition, or just for each element of a
+collection.
+
+Fate offers the following loop constructs:
+* `while`, to execute instructions if and as many time as a condition is
+ verified.
+* `do_while`, to execute instructions at least once, then as many time as a
+ condition is verified.
+* `for`, a loop that has pre-instructions, a condition to verify before each
+ execution of the main body, the main body of instructions itself, then
+ post-instructions, which are executed before checking the condition.
+* `for_each`, a loop that executes for each member of a collection.
+
+The `for_each` loops can also be used within a `player_choice!` to control what
+options are available.
+
+Let's change how armors and weapons are displayed to the player:
+
+**smithy.fate:**
+{{< fatecode >}}(fate_version 1)
+(require smithy_inventory.fate)
+
+;; Maybe it would be better to put this in a different file, but oh well...
+(global (lambda text ((cons #weapon int))) get_weapon_offer_label)
+(global (lambda text ((cons #armor int))) get_armor_offer_label)
+
+(set! get_weapon_offer_label
+ (lambda
+ ( ((cons #weapon int) offer) )
+ (let
+ (
+ (weapon (car offer))
+ (price (cdr offer))
+ )
+ (text
+ Buy "(var weapon.name)" (lp)attack: (var weapon.attack),
+ precision: (var weapon.precision)(rp) for (var price) coins.
+ )
+ )
+ )
+)
+
+(set! get_armor_offer_label
+ (lambda
+ ( ((cons #armor int) offer) )
+ (let
+ (
+ (armor (car offer))
+ (price (cdr offer))
+ )
+ (text
+ Buy "(var armor.name)" (lp)defense: (var armor.defense)(rp),
+ for (var price) coins.
+ )
+ )
+ )
+)
+
+(global bool has_visited_smithy (false))
+
+(define_sequence visit_smithy ()
+ (if (not has_visited_smithy)
+ As you approach the smithy, you notice that no one's there. All the wares
+ are out for selling. It's almost as if this story didn't need more
+ examples of lengthy dialogues.
+ (newline)
+ (set! has_visited_smithy (true))
+ )
+ You have (var hero.money) coins.
+ (newline)
+ What will you look at?
+ (player_choice!
+ (option ( Let's see the weapons )
+ (jump_to! see_weapons)
+ )
+ (option ( Let's see the armors )
+ (jump_to! see_armors)
+ )
+ (option ( Nothing, let's go back to the bar )
+ )
+ )
+)
+
+(define_sequence see_weapons ()
+ (player_choice!
+ (foreach smithy_weapons weapon
+ (option ( (eval get_weapon_offer_label weapon) )
+ (visit! buy_weapon weapon)
+ )
+ )
+ (option ( Nevermind ) )
+ )
+ (jump_to! visit_smithy)
+)
+
+(define_sequence see_armors ()
+ ;; Not as good as a for_each in this case, but let's use a for to show how
+ ;; it can be done.
+
+ (player_choice!
+ (for
+ ( (i 0) )
+ (< i (list:size smithy_armors))
+ ( (i (+ i 1)) )
+
+ (option ( (eval get_armor_offer_label (list:access i smithy_armors)) )
+ (visit! buy_armor (list:access i smithy_armors))
+ )
+ )
+ (option ( Nevermind ) )
+ )
+ (jump_to! visit_smithy)
+)
+
+(define_sequence buy_weapon ( ((cons #weapon int) weapon) )
+ (local int money_after)
+
+ (set! money_after (- hero.money (cdr weapon)))
+
+ (if_else (< money_after 0)
+ (
+ You can't afford that.
+ (newline)
+ You would need (abs money_after) more coins.
+ )
+ (
+ (set! hero.weapon (car weapon))
+ (set! hero.money money_after)
+ Equipped (var hero.weapon.name).
+ )
+ )
+ (newline)
+)
+
+(define_sequence buy_armor ( ((cons #armor int) armor) )
+ (local int money_after)
+
+ (set! money_after (- hero.money (cdr armor)))
+
+ (if_else (< money_after 0)
+ (
+ You can't afford that.
+ (newline)
+ You would need (abs money_after) more coins.
+ )
+ (
+ (set! hero.armor (car armor))
+ (set! hero.money money_after)
+ Equipped (var hero.armor.name).
+ )
+ )
+ (newline)
+)
+{{< /fatecode >}}
+
+Let's also look at a loop not within a `player_choice!` construct. We'll have
+the player try to count sheeps:
+
+**falling_asleep.fate:**
+{{< fatecode >}}(fate_version 1)
+(require data.fate)
+
+(global (list string) affirmative_messages)
+
+(list:add!
+ Indeed.
+ (string Sounds about right.)
+ Yes.
+ Agreed.
+ (string That's correct.)
+ True.
+ Undoubtedly.
+ Certainly.
+ (string Without a doubt.)
+ Correct.
+ Affirmative.
+ affirmative_messages
+)
+
+(global (lambda string ()) get_affirmative_message
+ (lambda ()
+ (list:access
+ (rand 0 (- (list:size affirmative_messages) 1))
+ affirmative_messages
+ )
+ )
+)
+
+(define_sequence count_sheeps ()
+ (local int sheeps 0)
+
+ You start imagining some pasture with no sheeps.
+
+ (while (< sheeps 100)
+ (local int player_guess)
+ (local int new_sheeps (rand 1 20))
+
+ (if_else (= new_sheeps 1)
+ ( A single sheep appears. )
+ ( (var new_sheeps) sheeps appear. )
+ )
+
+ (set! sheeps (+ sheeps new_sheeps))
+
+ (prompt_integer! (ptr player_guess) 0 120 How many sheeps are there now?)
+
+ (if_else (= sheeps player_guess)
+ (eval get_affirmative_message)
+ (
+ No. It was (var sheeps), you're pretty sure. The doubt wakes you up.
+ (newline)
+ (break!)
+ )
+ )
+ (newline)
+ )
+)
+
+(define_sequence fall_asleep ()
+ Deciding to break away from the expected storyline, you attempt to fall
+ asleep. It's not easy, though. Maybe counting sheeps would help?
+
+ (visit! count_sheeps)
+ (newline)
+ Upon waking up, your hard-trained reflexes inform you that someone stole all
+ your money.
+ (set! hero.money 0)
+ (newline)
+ This set-back was more than you could handle. You give up on this barely
+ coherent story.
+ (end!)
+)
+{{< /fatecode >}}
+
+[The next step of this tutorial](/learn/going_deeper) goes deeper into all the
+concepts that were already explored.
+
+----
+
+## Unchanged Files
+
+**data.fate:**
+{{< fatecode >}}(fate_version 1)
+
+(declare_structure #weapon
+ (text name)
+ (int attack)
+ (int precision)
+)
+
+(declare_structure #armor
+ (text name)
+ (int defense)
+)
+
+(declare_structure #character
+ (string name)
+ (int money)
+ (#weapon weapon)
+ (#armor armor)
+)
+
+(global #character hero)
+
+(struct:set_fields! hero.weapon
+ (name (text "Legendary" sword))
+ (attack 3)
+ (precision 50)
+)
+
+(struct:set_fields! hero.armor
+ (name (text "Refined" attire))
+ (defense 1)
+)
+
+(set! hero.money 200)
+
+{{< /fatecode >}}
+
+**get_a_refill.fate:**
+{{< fatecode >}}(fate_version 1)
+
+(require data.fate)
+(require actions.fate)
+(require smithy.fate)
+
+(define_sequence lower_price_of_booze
+ (
+ ((ptr int) price_pointer)
+ (int decrease)
+ )
+ Great! The price of booze just lowered from (at price_pointer)
+ (set! (at price_pointer)
+ (- (at price_pointer) decrease)
+ )
+ to (at price_pointer)!
+)
+
+(define_sequence get_a_refill ()
+ (local int price_of_booze)
+
+ (set! price_of_booze 12)
+
+ Staring straight at the barman, you raise your glass and proclaim:
+ (newline)
+ "This soon-to-be world savior needs more booze!"
+ (newline)
+ The barman's lack of reaction is disappointing, but seeing the beer being
+ poured does improve your mood.
+ (newline)
+ Satisfied, you hand the barman (var price_of_booze) copper coins.
+ (visit! pay price_of_booze)
+ The barman sighs, then asks:
+ (prompt_string! (ptr hero.name) 2 64 What is your name, then, hero?)
+ "(var hero.name)?"
+ (newline)
+ (switch hero.name
+ (Fred
+ You brace for the inevitable mockery.
+ )
+ (Link
+ You show the back of your hand to the barman.
+ )
+ ((string Lancelot of Camelot)
+ You place halves of a coconut shell on the bar.
+ )
+ The barman looks surprised.
+ )
+ (newline)
+ (visit! lower_price_of_booze (ptr price_of_booze) 4)
+ (newline)
+ "I have heard of you, (var hero.name)," the barman exclaims, "I have a quest
+ for you!"
+ (newline)
+ It's your turn to sigh.
+ (newline)
+ The barman hands you a bag, and says:
+ (newline)
+ "Take this pre-payment and head to the smithy."
+ (newline)
+ (visit! visit_smithy)
+)
+{{< /fatecode >}}
+
+**actions.fate:**
+{{< fatecode >}}(fate_version 1)
+
+(require data.fate)
+
+(define_sequence pay ( (int cost) )
+ (set! hero.money (- hero.money cost))
+)
+{{< /fatecode >}}
+
+**main.fate:**
+{{< fatecode >}}(fate_version 1)
+
+(require get_a_refill.fate)
+(require falling_asleep.fate)
+
+Once upon a time, starting a story with these words wasn't considered a cliche.
+Starting in a tavern might also not be seen as very original. Having the main
+character be an street orphan, raised by some mysterious sage all to end up as
+a mercenary with an uncommonly strong sense of honor probably isn't going to
+lead to any praises for novelty either. Maybe you should drink to that.
+(newline)
+Or maybe you shouldn't. This isn't your first mug. Not your second either.
+Drinking to forget that you are a stereotypical hero isn't going to solve
+anything. Worse, the alcoholic trait is part of the image.
+(newline)
+As you contemplate your own pointless description, your gaze leaves what turns
+out to be an already empty glass in your hand and finds the barman.
+
+(player_choice!
+ (option ( Ask the barman for a refill )
+ (visit! get_a_refill)
+ )
+ (option ( Fall asleep )
+ (jump_to! fall_asleep)
+ )
+)
+
+;; Let's analyze how well the player did
+(cond
+ ((> hero.weapon.attack 7)
+ Your feel ready to strike down any challenge.
+ )
+ ((>= hero.armor.defense 7)
+ Your feel invincible.
+ )
+ ((>= hero.money 50)
+ You feel good about having spent your coins sparingly.
+ )
+ ((true)
+ You feel like you wasted your evening.
+ )
+)
+(end!)
+{{< /fatecode >}}
+
+**smithy_inventory.fate:**
+{{< fatecode >}}(fate_version 1)
+
+(require data.fate)
+
+(global (list (cons #weapon int)) smithy_weapons)
+(global (list (cons #armor int)) smithy_armors)
+
+(list:add!
+ (cons
+ (struct:set_fields (default #weapon)
+ (name (text An Iron Rod))
+ (attack 10)
+ (precision 70)
+ )
+ 176
+ )
+ smithy_weapons
+)
+(list:add!
+ (cons
+ (struct:set_fields (default #weapon)
+ (name (text A Magnificient Brick))
+ (attack 6)
+ (precision 90)
+ )
+ 110
+ )
+ smithy_weapons
+)
+
+(list:add!
+ (cons
+ (struct:set_fields (default #armor)
+ (name (text A raincoat?!))
+ (defense 7)
+ )
+ 160
+ )
+ (cons
+ (struct:set_fields (default #armor)
+ (name (text A nice cape))
+ (defense 3)
+ )
+ 50
+ )
+ smithy_armors
+)
+{{< /fatecode >}}