narrat 1.3.2 → 2.0.0-rc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +175 -0
  2. package/README.md +10 -0
  3. package/lib/app.vue.d.ts +27 -52
  4. package/lib/components/debug/debug-menu.vue.d.ts +1 -1
  5. package/lib/config.d.ts +7 -0
  6. package/lib/exports/plugins.d.ts +4 -4
  7. package/lib/index.d.ts +1 -4
  8. package/lib/index.esm.js +1553 -931
  9. package/lib/index.js +1553 -931
  10. package/lib/plugins/NarratPlugin.d.ts +1 -1
  11. package/lib/stores/hud-stats-store.d.ts +2 -0
  12. package/lib/stores/inventory-store.d.ts +2 -1
  13. package/lib/stores/main-store.d.ts +92 -110
  14. package/lib/stores/quest-log.d.ts +4 -1
  15. package/lib/stores/skills.d.ts +7 -4
  16. package/lib/stores/vm-store.d.ts +99 -104
  17. package/lib/types/parser.d.ts +34 -18
  18. package/lib/utils/audio-loader.d.ts +1 -0
  19. package/lib/utils/data-helpers.d.ts +5 -0
  20. package/lib/utils/logger.d.ts +1 -2
  21. package/lib/utils/skillchecks.d.ts +0 -3
  22. package/lib/utils/string-helpers.d.ts +2 -0
  23. package/lib/vm/commands/arithmetic-commands.d.ts +17 -0
  24. package/lib/vm/commands/audio-commands.d.ts +8 -0
  25. package/lib/vm/commands/choice.d.ts +36 -4
  26. package/lib/vm/commands/clear_dialog.d.ts +2 -3
  27. package/lib/vm/commands/command-helpers.d.ts +2 -0
  28. package/lib/vm/commands/command-plugin.d.ts +17 -8
  29. package/lib/vm/commands/flow-commands.d.ts +14 -0
  30. package/lib/vm/commands/if.d.ts +9 -1
  31. package/lib/vm/commands/inventory-commands.d.ts +14 -4
  32. package/lib/vm/commands/logic-command.d.ts +42 -0
  33. package/lib/vm/commands/notify.d.ts +3 -1
  34. package/lib/vm/commands/quest-commands.d.ts +29 -4
  35. package/lib/vm/commands/screen-commands.d.ts +8 -0
  36. package/lib/vm/commands/set.d.ts +5 -1
  37. package/lib/vm/commands/skill-commands.d.ts +33 -0
  38. package/lib/vm/commands/stats-commands.d.ts +12 -0
  39. package/lib/vm/commands/string-commands.d.ts +9 -0
  40. package/lib/vm/commands/text.d.ts +13 -2
  41. package/lib/vm/commands/wait.d.ts +3 -1
  42. package/lib/vm/vm-helpers.d.ts +6 -6
  43. package/lib/vm/vm-parser.d.ts +10 -1
  44. package/lib/vm/vm.d.ts +8 -6
  45. package/package.json +11 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,180 @@
1
1
  # Narrat changelog
2
2
 
3
+ ## 2.0.0-rc3
4
+
5
+ * Improvements to debugging to show more useful info on parser/runtime errors
6
+ * Corrected display of line numbers in errors
7
+ * Made parser continue parsing after errors to make it easier to see all errors at once and to be able to play the game even if there are parser errors
8
+
9
+ ## 2.0.0-rc1
10
+
11
+ ### Narrat 2.0
12
+
13
+ ### What changed in narrat 2.0
14
+
15
+ Narrat has a **new language syntax** in 2.0.0 - The parser has been improved to turn the narrat scripting into a full programming language with support for expressions, variables and functions
16
+
17
+ The syntax is generally the same so existing scripts would mostly work, except for the use of `$if` (which used to be a hack by sending your code to JavaScript [eval](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)).
18
+
19
+ ### Script updating tool
20
+
21
+ There is a [script updating tool](https://github.com/liana-pigeot/Narrat-Script-Updater) which can be used to help automatically update existing scripts from 1.x to work with the new syntax.
22
+
23
+ {% hint style="danger" %}
24
+ The old syntax is largely compatible, but the $if instruction works very differently now. The script will update those $if instructions to match the new system, but might fail at updating long series of conditions in $if
25
+ {% endhint %}
26
+
27
+ ### Installing narrat 2.0
28
+
29
+ Narrat 2.0 is currently published under a different tag to avoid people on 1.x accidentally installing it.
30
+
31
+ To install narrat to, run `npm install narrat@next`. The `next` tag is where the latest 2.x version is published.
32
+
33
+ ### Expressions
34
+
35
+ Expressions are now a first party feature. An expression is any operation between parenthesis. Any command in the game can be used as an expression, if it returns a value. For example `(+ 2 3)` is an expression that would get evaluated to `5`.
36
+
37
+ ### Syntax for using commands
38
+
39
+ The syntax for using commands hasn't changed, but it's been formalised.
40
+
41
+ The format for any operation is `[operator] [arg1] [arg2] [arg3] ...`. Operator is the command's keyword (like `talk`, `set`, `if` etc).
42
+
43
+ For example:
44
+
45
+ `set data.player.score 3` is the operator `set` with arguments `data.player.score` and `3`.
46
+
47
+ `set data.player.score (+ $data.player.score 2)`
48
+
49
+ The first command would set `3` in `data.player.score`.
50
+
51
+ The second command is also a set on `data.player.score`, but the second argument (the value) is an expression itself: `(+ $data.player.score 2)`. So the final resulting command is effectively `set data.player.score 5`.
52
+
53
+ ### Using Variables
54
+
55
+ To use a variable's value in a command, prefix its name with `$` as in the example above. In the case of the `set` command, we want to pass to set the variable's name, not its value, so we don't use `$` at the start.
56
+
57
+ Variables are also available in string interpolation as before, to insert variables in text:
58
+
59
+ `talk player idle "Hello %{data.player.name}"`
60
+
61
+ ### New If syntax
62
+
63
+ The previous `$if` is gone, now `if` is a command itself, which takes one argument: the condition. If the condition is true it plays the next branch, and it can have an optional else branch.
64
+
65
+ Example:
66
+
67
+ ```py
68
+ set data.age 25
69
+ if (> $data.age 18):
70
+ "The player is an adult"
71
+ else:
72
+ "The player is not an adult"
73
+ ```
74
+
75
+ #### More details on syntax and expressions
76
+
77
+ More complex example:
78
+
79
+ ```py
80
+ main:
81
+ set data.winThreshold 10
82
+ set data.player.score 5
83
+ set data.player.scoreBonus 5
84
+ if (== (+ $data.player.score $data.player.scoreBonus) $data.winThreshold):
85
+ "The player won!"
86
+ ```
87
+
88
+ In this example, the script stores a few variables, and then uses them in an `if` to compare their value. The `==` operation returns true if all arguments are equal, while the `+` operation adds values together and returns the result.
89
+
90
+ Here's how the code above would get broken down as the expressions get calculated:
91
+
92
+ ```py
93
+ if (== (+ $player.score $player.scoreBonus) $data.winThreshold):
94
+ if (== 10 $data.winThreshold):
95
+ if (== 10 10):
96
+ if true
97
+ ```
98
+
99
+ ### New operators
100
+
101
+ A lot of new operators have been added to be able to perform basic operations with the new scripting system:
102
+
103
+ - `+`, `-`, `*`, `/` : Will add/substract/etc arguments passed and return the value. Can take infinite arguments
104
+ - `||` and `&&` : Will or/and all arguments passed and return true or false. Inifinite arguments
105
+ - `>`, `>=`, `<`, `<=`, `==`, `!=` : Compares arguments 1 and 2, returns true or false. Note: equality uses truthy equality, not strict equality
106
+ - `!`: Negates argument 1
107
+ - `?`: Ternary operation. Arg 1 is the condition, 2 is what gets returned on success, 3 what gets returned on failure
108
+
109
+ ### New helper functions
110
+
111
+ New helper functions for easily checking quests and inventory without long lines:
112
+
113
+ - `quest_completed? [questId]`: Returns true if the quest `questId` is completed
114
+ - `objective_completed? [questId] [objectiveId]`: Same for an objective
115
+ - Also quest_started and `objective_started`
116
+ - `has_item? [itemId] [amount (optional)]`: Returns true if the player has an item (if amount is passed, the player needs to have amount or more of it)
117
+ - `item_amount? [itemId]` Returns how many of an item the player has.
118
+
119
+ ### Local variables
120
+
121
+ Local variables can now be declared. They exist inside the scope in which they are declared. Example
122
+
123
+ ```python
124
+ main:
125
+ run variables_test
126
+ "The variable 'test' is now undefined because we left the scope it was created in: %{test}"
127
+
128
+ variables_test:
129
+ var test 1
130
+ "Test value is %{test}"
131
+ ```
132
+
133
+ ### Function with arguments and return values
134
+
135
+ Labels are now "functions" and can take arguments or return values.
136
+
137
+ Example:
138
+
139
+ ```renpy
140
+ main:
141
+ var meal (run_label takeout_menu Cake)
142
+ "The player chose to eat %{meal}"
143
+
144
+ takeout_menu third_option:
145
+ var meal ""
146
+ choice:
147
+ talk helper idle "Which meal do you want?"
148
+ "Pizza":
149
+ set meal pizza
150
+ "Burger":
151
+ set meal burger
152
+ "%{third_option}":
153
+ set meal $third_option
154
+ talk helper idle "Chosen %{meal}"
155
+ return $meal
156
+
157
+ ```
158
+
159
+ ### Other new features
160
+
161
+ #### Audio triggers
162
+
163
+ New audio triggers feature to play sounds on certain events in the game.
164
+
165
+ Simply add the sounds to the config:
166
+
167
+ ```json
168
+ "audioTriggers": {
169
+ "onPlayerAnswered": "click",
170
+ "onPressStart": "game_start",
171
+ "onSkillCheckFailure": "failure",
172
+ "onSkillCheckSuccess": "success"
173
+ }
174
+ ```
175
+
176
+ Keys are event names, and values are the id of an audio you've defined in the config. For now all the available events are the ones above. Once defined, the sound will play every time that event is triggered.
177
+
3
178
  ## 1.3.2
4
179
 
5
180
  - Improvement to variables editor for debugging
package/README.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # 🚀 Narrat
2
2
 
3
+ ## Narrat 2.0
4
+
5
+ This is the narrat 2.0 branch. See the [Narrat 2.0 update docs](https://docs.get-narrat.com/readme/narrat-2.0) for more info, or look at the changelog.
6
+
7
+ 2.0 version can be installed with `npm install narrat@next`, as it's not pushed as the main release yet (main release is still 1.x).
8
+
9
+ There are syntax changes in usage of $if functions and also an auto script converter available in the [2.0 update docs](https://docs.get-narrat.com/readme/narrat-2.0).
10
+
11
+ ## Original Docs
12
+
3
13
  ![example workflow](https://github.com/nialna/narrat/actions/workflows/main.yml/badge.svg)
4
14
 
5
15
  A narrative game engine for text-based games. Inspired by renpy syntax, but built to be customisable, extendable and web-focused. See the [website](https://get-narrat.com)
package/lib/app.vue.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { PropType } from 'vue';
2
2
  import { DialogBoxParameters } from './types/dialog-box-types';
3
3
  import { GameConfig } from './types/app-types';
4
- import { AppOptions } from '.';
4
+ import { AppOptions } from './config';
5
5
  import { Parser } from './types/parser';
6
6
  import { DialogKey } from './stores/dialog-store';
7
7
  declare const _default: import("vue").DefineComponent<{
@@ -22,56 +22,32 @@ declare const _default: import("vue").DefineComponent<{
22
22
  }[]>;
23
23
  stack: import("vue").ComputedRef<{
24
24
  currentIndex: number;
25
- branch: {
26
- code: string;
27
- args: string[];
28
- operator: string;
29
- commandType: string;
30
- options: Parser.EmptyOptions | {
31
- condition: string;
32
- success: any[];
33
- failure?: any[];
34
- } | {
35
- label: string;
36
- } | {
37
- text: string;
38
- } | {
39
- prompt: any;
40
- choices: {
41
- choice: string;
42
- branch: any[];
43
- condition?: string;
44
- skillCheck?: {
45
- id: string;
46
- skill: string;
47
- value: number;
48
- hideAfterRoll: boolean;
49
- success: {
50
- text: string;
51
- branch: any[];
52
- };
53
- failure: {
54
- text: string;
55
- branch?: any[];
56
- };
57
- };
58
- index: number;
59
- }[];
60
- } | {
61
- screen: string;
62
- } | {
63
- mode: "sound" | "music";
64
- audio: string;
65
- } | {
66
- mode: "sound" | "music";
67
- audio?: string;
68
- } | {
69
- duration: number;
70
- };
71
- fileName: string;
72
- line: number;
73
- }[];
25
+ branchData: {
26
+ branch: {
27
+ code: string;
28
+ command: {
29
+ commandType: string;
30
+ operator: string;
31
+ args: (Parser.Primitive | {
32
+ code: string;
33
+ command: any;
34
+ fileName: string;
35
+ line: number;
36
+ })[];
37
+ options: Parser.DefaultArg;
38
+ staticOptions?: unknown;
39
+ };
40
+ fileName: string;
41
+ line: number;
42
+ }[];
43
+ args?: string[];
44
+ };
74
45
  label: string;
46
+ scope: {
47
+ [key: string]: any;
48
+ };
49
+ onComplete?: (result: any) => void;
50
+ returnValue: any;
75
51
  }[]>;
76
52
  modal: import("vue").ComputedRef<string | false>;
77
53
  flowState: import("vue").ComputedRef<"menu" | "playing">;
@@ -85,7 +61,6 @@ declare const _default: import("vue").DefineComponent<{
85
61
  }, {
86
62
  dialogLength(): number;
87
63
  lastDialog(): DialogKey | undefined;
88
- command(): Parser.Command;
89
64
  picture(): string | undefined;
90
65
  backgroundStyle(): any;
91
66
  layoutWidth(): number;
@@ -106,7 +81,7 @@ declare const _default: import("vue").DefineComponent<{
106
81
  gameStyle(): any;
107
82
  screenRatio(): number;
108
83
  dialogContainerStyle(): any;
109
- currentLine: () => Parser.Command;
84
+ currentLine: () => Parser.ParsedExpression<Parser.DefaultArg, undefined>;
110
85
  screenWidth: () => number;
111
86
  screenHeight: () => number;
112
87
  canvasWidth: () => number;
@@ -40,7 +40,7 @@ declare const _default: import("vue").DefineComponent<{}, {
40
40
  onSearchInput(): void;
41
41
  save(): void;
42
42
  wordCount(): void;
43
- countWordsInScriptLine(scriptLine: Parser.Command): number;
43
+ countWordsInScriptLine(scriptLine: Parser.ParsedExpression): number;
44
44
  countWordsInString(string: string): number;
45
45
  countWordsInScriptBranch(branch: Parser.Branch): number;
46
46
  getPlayTimeString(): string;
package/lib/config.d.ts CHANGED
@@ -4,6 +4,10 @@ export declare function getSkillConfig(id: string): SkillData;
4
4
  export declare function getItemConfig(id: string): ItemData;
5
5
  export declare function getQuestConfig(questId: string): QuestData;
6
6
  export declare function getObjectiveConfig(quest: string, objectiveId: string): ObjectiveData;
7
+ export interface AppOptions {
8
+ logging: boolean;
9
+ debug: boolean;
10
+ }
7
11
  export interface Config {
8
12
  gameTitle: string;
9
13
  images: {
@@ -79,6 +83,9 @@ export interface Config {
79
83
  quests: {
80
84
  [key: string]: QuestData;
81
85
  };
86
+ audioTriggers: {
87
+ [key: string]: string;
88
+ };
82
89
  }
83
90
  export interface QuestData {
84
91
  title: string;
@@ -2,7 +2,7 @@ import { NarratPlugin } from '../plugins/NarratPlugin';
2
2
  import { CommandPlugin, generateParser } from '../vm/commands/command-plugin';
3
3
  import type { CommandRunner } from '../vm/commands/command-plugin';
4
4
  export declare type NarratLifecycleHook = <T extends [...any[]]>(...args: T) => void;
5
- declare type NarratPluginObject = {
5
+ declare type NarratPluginObject<T> = {
6
6
  onPageLoaded?: NarratLifecycleHook;
7
7
  onNarratSetup?: NarratLifecycleHook;
8
8
  onAppMounted?: NarratLifecycleHook;
@@ -11,9 +11,9 @@ declare type NarratPluginObject = {
11
11
  onGameStart?: NarratLifecycleHook;
12
12
  onGameMounted?: NarratLifecycleHook;
13
13
  onGameUnmounted?: NarratLifecycleHook;
14
- customCommands?: CommandPlugin[];
14
+ customCommands?: CommandPlugin<T>[];
15
15
  };
16
- declare function registerPlugin(plugin: NarratPluginObject): void;
17
- declare function addCommand(command: CommandPlugin): void;
16
+ declare function registerPlugin<T>(plugin: NarratPluginObject<T>): void;
17
+ declare function addCommand<T>(command: CommandPlugin<T>): void;
18
18
  export { CommandRunner };
19
19
  export { CommandPlugin, NarratPluginObject, NarratPlugin, registerPlugin, addCommand, generateParser, };
package/lib/index.d.ts CHANGED
@@ -2,10 +2,7 @@ import 'es6-promise/auto';
2
2
  import './/sass/main.css';
3
3
  import { App } from 'vue';
4
4
  import { GameConfig } from './types/app-types';
5
- export interface AppOptions {
6
- logging: boolean;
7
- debug: boolean;
8
- }
5
+ import { AppOptions } from './config';
9
6
  export declare function startApp(config: GameConfig, options: AppOptions): Promise<void>;
10
7
  export declare type Narrat = {
11
8
  app: App;