1
0
Fork 0
mirror of https://github.com/Reuh/anselme.git synced 2025-10-27 16:49:31 +00:00

[doc] update doc, tutorial first draft

This commit is contained in:
Étienne Fildadut 2024-06-02 22:53:36 +02:00
parent 9e01be548c
commit a5bbe0eeb0
6 changed files with 330 additions and 27 deletions

View file

@ -29,7 +29,7 @@
-- Some variables are defined into the script/`fn` scope. They are all stored from persistent storage, using the script name as part of their persistent key: -- Some variables are defined into the script/`fn` scope. They are all stored from persistent storage, using the script name as part of their persistent key:
-- --
-- * `current checkpoint` is the currently set checkpoint (an anchor); -- * `current checkpoint` is the currently set checkpoint (an anchor);
-- * `reached` is a table of *{ #anchor = number, ... } which associates to an anchor the number of times it was reached (see `check` and `checkpoint`); -- * `reached` is a table of `*{ #anchor = number, ... }` which associates to an anchor the number of times it was reached (see `check` and `checkpoint`);
-- * `run` is the number of times the script was successfully called. -- * `run` is the number of times the script was successfully called.
-- --
-- As well as functions defined in the script scope: -- As well as functions defined in the script scope:

View file

@ -56,31 +56,31 @@ Anselme expects that `require("anselme.module")` will try loading both `anselme/
Global version string. Follow semver. Global version string. Follow semver.
_defined at line 57 of [anselme/init.lua](../anselme/init.lua):_ `version = "2.0.0-beta2",` _defined at line 58 of [anselme/init.lua](../anselme/init.lua):_ `version = "2.0.0-beta2",`
### .versions ### .versions
Table containing per-category version numbers. Incremented by one for any change that may break compatibility. Table containing per-category version numbers. Incremented by one for any change that may break compatibility.
_defined at line 60 of [anselme/init.lua](../anselme/init.lua):_ `versions = {` _defined at line 61 of [anselme/init.lua](../anselme/init.lua):_ `versions = {`
#### .language #### .language
Version number for language and standard library changes. Version number for language and standard library changes.
_defined at line 62 of [anselme/init.lua](../anselme/init.lua):_ `language = 30,` _defined at line 63 of [anselme/init.lua](../anselme/init.lua):_ `language = 30,`
#### .save #### .save
Version number for save/AST format changes. Version number for save/AST format changes.
_defined at line 64 of [anselme/init.lua](../anselme/init.lua):_ `save = 7,` _defined at line 65 of [anselme/init.lua](../anselme/init.lua):_ `save = 7,`
#### .api #### .api
Version number for Lua API changes. Version number for Lua API changes.
_defined at line 66 of [anselme/init.lua](../anselme/init.lua):_ `api = 10` _defined at line 67 of [anselme/init.lua](../anselme/init.lua):_ `api = 10`
### .parse (code, source) ### .parse (code, source)
@ -94,20 +94,35 @@ local ast = anselme.parse("1 + 2", "test")
ast:eval(state) ast:eval(state)
``` ```
_defined at line 78 of [anselme/init.lua](../anselme/init.lua):_ `parse = function(code, source)` _defined at line 79 of [anselme/init.lua](../anselme/init.lua):_ `parse = function(code, source)`
### .parse_file (path) ### .parse_file (path)
Same as `:parse`, but read the code from a file. Same as `:parse`, but reads the code from a file.
`source` will be set as the file path. `source` will be set as the file path.
_defined at line 83 of [anselme/init.lua](../anselme/init.lua):_ `parse_file = function(path)` _defined at line 84 of [anselme/init.lua](../anselme/init.lua):_ `parse_file = function(path)`
### .generate_translation_template (code, source)
Generates and return Anselme code (as a string) that can be used as a base for a translation file.
This will include every translatable element found in this code.
`source` is an optional string; it will be used as the code source name in translation contexts.
_defined at line 93 of [anselme/init.lua](../anselme/init.lua):_ `generate_translation_template = function(code, source)`
### .generate_translation_template_file (path)
Same as `:generate_translation_template`, but reads the code from a file.
`source` will be set as the file path.
_defined at line 98 of [anselme/init.lua](../anselme/init.lua):_ `generate_translation_template_file = function(path)`
### .new () ### .new ()
Return a new [State](#state). Return a new [State](#state).
_defined at line 90 of [anselme/init.lua](../anselme/init.lua):_ `new = function()` _defined at line 102 of [anselme/init.lua](../anselme/init.lua):_ `new = function()`
# State # State
@ -296,4 +311,4 @@ Otherwise, each Node has its own module file defined in the [ast/](../ast) direc
--- ---
_file generated at 2024-06-01T12:26:47Z_ _file generated at 2024-06-02T20:52:37Z_

View file

@ -1070,7 +1070,7 @@ Creates and returns a new script.
Some variables are defined into the script/`fn` scope. They are all stored from persistent storage, using the script name as part of their persistent key: Some variables are defined into the script/`fn` scope. They are all stored from persistent storage, using the script name as part of their persistent key:
* `current checkpoint` is the currently set checkpoint (an anchor); * `current checkpoint` is the currently set checkpoint (an anchor);
* `reached` is a table of *{ #anchor = number, ... } which associates to an anchor the number of times it was reached (see `check` and `checkpoint`); * `reached` is a table of `*{ #anchor = number, ... }` which associates to an anchor the number of times it was reached (see `check` and `checkpoint`);
* `run` is the number of times the script was successfully called. * `run` is the number of times the script was successfully called.
As well as functions defined in the script scope: As well as functions defined in the script scope:
@ -1336,4 +1336,4 @@ _defined at line 14 of [anselme/stdlib/wrap.lua](../anselme/stdlib/wrap.lua):_ `
--- ---
_file generated at 2024-06-01T12:26:47Z_ _file generated at 2024-06-02T20:52:37Z_

View file

@ -1,43 +1,336 @@
TODO should mostly be commented code examples instead of long winded explanations Anselme is a dynamically typed scripting language intended to be embedded in game engines, focusing on making writing complex branching dialogues and interactions easier.
It is implemented in pure Lua and should be easily usable in any environment with the ability to run Lua 5.4, 5.3 or LuaJIT code.
This document will gives code examples and terse explanations of the most common patterns in Anselme, with links for more detailled descriptions from the [language reference](language.md).
This document does not attempt to explain basic programming concepts. If you haven't touched any other programming language before, good luck <3.
# Base syntax # Base syntax
_For more detailled information on this, look at the [language reference](language.md)._
Each line can contain an expression, and each expression return a value.
```
print("hello")
12+5
```
A line can be followed by an indented block (called an "attached block"). The indented block is stored in a variable `_` that run the block when retrieved.
If an expression is expected but the end-of-the-line is reached, a `_` is implicitely assumed.
```
12+
5
// this is the same as
12+_
5
```
## Multiline expressions
String, tuple literals, struct literals and parentheses ignore the one expression per line rule and can span several lines.
```
"hello i would like a
hot dog please"
[12
+5]
{12
+5}
(12
+5)
```
## Comments
_For more detailled information on this, look at [comments](language.md#comments)._
```
// line comment
/* multiline
comment */
12 + // inline comment // 5
```
## Calling functions
_For more detailled information on this, look at [calling callables](language.md#calling-callables)._
```
// with no arguments
function!
// with arguments
function(12, "yes")
// is the same as
12!function("yes")
```
# Running Anselme scripts # Running Anselme scripts
## Script runner ## Script runner
To quickly test scripts, the test runner can be used to run individual anselme files using the `interactive` command.
`lua test/run.lua interactive script.ans`
## Implementing in your game ## Implementing in your game
To see how to integrate Anselme into your game, look at the [Lua API documentation](api.md).
# Writing text # Writing text
For more information, look at: events _For more detailled information on this, look at [events](language.md#events)._
## Text ## Text
_For more detailled information on this, look at [text](language.md#texts)._
Text values represent dialogs to be shown in the game.
```
// define a variable with a text value
:var = | Text |
// send the text to the game by calling it
var!
// the text is automatically called
| Hello world! |
// the closing | can be omitted on end-of-expression
| Hello world!
```
## Choices ## Choices
_For more detailled information on this, look at [choices](language.md#choices)._
Choices represent a choice to be shown in the game.
```
| What do you want?
*| An ice cream
| An ice cream coming up!
*| A bunch of sausages, NOW.
sausage emergency function!
```
## Tags ## Tags
# Variables _For more detailled information on this, look at [tags](language.md#tags)._
For more information, look at: types Tags can be used to add metatdata to text and choices sent to the game.
```
speaker: "Hero" #
| I AM THE HERO, BOW DOWN BEFORE ME
| IF YOU DON'T I'M GONNA HIT YOU WITH {color:"red" #| LOVE}!1!!1
```
# Variables
## Defining variables ## Defining variables
_For more detailled information on this, look at [variables](language.md#variables), [scoping rules](language.md#scoping-rules)._
```
:var = 42 // definition
var = 12 // assignment
var += 2 // compound assignment
if(true)
// other is not accessible from outside the scope where it was defined
:other = 12
// exported variables (with a @) are available in the whole file
:@exported = 56
other // error
exported // 56
```
## Common types
_For more detailled information on this, look at [types](language.md#types-and-literals), [scoping rules](language.md#scoping-rules)._
```
:string = "strings"
:number = 42
:boolean = true
:nil = ()
:tuple = [1,2,3]
:list = *[1,2,3]
:struct = {name: "link", favorite food: "cheesecakes"}
:table = *{name: "link", favorite food: "cheesecakes"}
```
## Functions ## Functions
For more information, look at: calling, dispatch, value checking _For more detailled information on this, look at [calling callables](language.md#calling-callables), [functions](language.md#functions), [dynamic dispatch](language.md#dynamic-dispatch), [value checking](language.md#value-checking)._
```
:$some function
print("i take no arguments")
some function!
// functions can be overloaded
:$some function(x, y, and even some with default values="also this default one")
print("i take way too many arguments, like {x}, {y} and {and stuff}")
some function("foo", "bar")
// conditions ("value checking") can be put on parameters
:$some function(x::is number)
10+x
some function(2)
// assignment to a function are regular function calls with an assignement parameter
:$some function(x) = v
x + v
some function(12) = 42
// anonymous functions / function literals
:some function = $(x::is string) print(x)
```
# Conditionals # Conditionals
_For more detailled information on this, look at [control flow](standard_library.md#control-flow)._
## If ## If
```
if(3 > 5)
print("not called")
else if(1 > 5)
print("not called")
else!
print("called")
```
## While ## While
```
:i = 0
while(i < 5)
i += 1
if(i == 4)
break!
```
## For ## For
```
for(:x, range(10))
print(x)
```
# Persistence # Persistence
_For more detailled information on this, look at [persistence](standard_library.md#persistence-helpers), [alias variables](#api.md#alias-variables)._
Variables that needs to be saved and loaded alongside the game's save files can be stored in persistent storage.
```
// name in save is "money", with a default value of 0
:&money => "money"!persist(0)
money += 10000
```
The persistent storage can then be obtained as a serialized string using the [saving & loading Lua API methods](api.md#saving-and-loading-persistent-variables).
# Scripts # Scripts
_For more detailled information on this, look at [scripts](standard_library.md#scripts)._
Scripts are functions enhanced with features to allow dialog resuming and tracking.
```
// create a script which use the name "presentation" in save files
:presentation = "presentation"!script
| Hi I'm Max, the Hero.
// only calls presentation if it has never been run before
if(presentation.run == 0)
presentation!
```
## Checkpoints ## Checkpoints
When a checkpoint is reached in a script, if the script if called again, it will be restarted from the checkpoint instead of the start of the script.
A checkpoint is created by using the `checkpoint` function on an anchor literal (ex. `#anchor name`).
```
:deep choice = "deep choice"!script
| Do you want...
*| A green drinky bird?
| Your wish is my command.
#green bird!checkpoint // once reached, the script will be resumed from this point when called again
| What a magnificient drinky bird.
*| Ten million dollars?
| Your wish is my command.
#the dumb choice!checkpoint
// the checkpoint's attached block is called when resuming from the checkpoint only
| No take-backs.
| A bunch of useless money.
deep choice!
// will resume from the last reached checkpoint, i.e. in the previously selected choice
deep choice!
if(deep choice.reached(#green bird, false))
| You made an excellent choice.
```
## Branches
_For more detailled information on this, look at [branching and merging](api.md#branching-and-merging)._
Anselme allows for several scripts to run in parallel through branches. A branch is always created from a parent branch and inherit all its state.
Values modified in the child branch do not affect the parent branch, until the changes are merged back into the parent using the [`merge branch` method](standard_library.md#merge-branch-complete-flush-true).
This means that if a script is interrupted for any reason (e.g. the player exited the dialog or the game) before merging its changes back into the parent branch, it would be as if whatever was ran since the last merge did not happen (similarly to e.g. database transactions). Note that changes are merged into the parent branch automatically when a checkpoint is reached in a script.
It is therefore recommended to never operate on the main branch directly but only child branches - this way the state of the main branch should only be updated on checkpoints and manual merges, and should therefore makes it possible to ensure its consistency (which is important when retrieving its persistent data to store in the game save file).
# Translation
_For more detailled information on this, look at [translatables](api.md#translatables)._
Text and any value preceded by a `%` prefix will be replaced with its translation (if it exists) when evaluated.
```
// no translation defined, "Hello" is sent to the game
| Hello
// define translation for "Hello", "Bonjour" is sent to the game
| Hello | -> | Bonjour |
| Hello
// making any value translatable with %
%"red" -> "rouge"
%"red" // "rouge"
```
An Anselme script containing a ready-to-translate list of all translatables elements of a file can be obtained using the [translation template generator Lua API methods](#api.md#generate-translation-template). The template can then be loaded as a regular Anselme file for all the translations to be applied.

View file

@ -2,11 +2,6 @@ Various ideas and things that may or may not be done. It's like GitHub issues, b
Loosely ordered by willingness to implement. Loosely ordered by willingness to implement.
# To do or discard before stable release
Documentation:
* tutorial
# Can be done later # Can be done later
Translation. Translation.

View file

@ -12,18 +12,18 @@ This is version 2, a full rewrite. **Currently not stable.**
| Hi, what can I do for you? | Hi, what can I do for you?
*| a latte with a bunch of sugar and a pretty sprinkles please *| a latte with a bunch of sugar and a pretty sprinkles please
"from": "barista" # from: "barista" #
| Good choice. Here you go. Have a colorful day. | Good choice. Here you go. Have a colorful day.
money -= 10 money -= 10
*| triple expresso *| triple expresso
"from": "barista" # from: "barista" #
| Here. Have a nice day. | Here. Have a nice day.
money -= 2 money -= 2
*| a slap *| a slap
"from": "barista" # from: "barista" #
| With pleasure. | With pleasure.
"type": "sfx" # type: "sfx" #
| SLAP | SLAP
health points -= 2 health points -= 2