@magicborn/dialogue-forge 0.1.0

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 (241) hide show
  1. package/README.md +233 -0
  2. package/bin/dialogue-forge.js +78 -0
  3. package/demo/app/layout.tsx +36 -0
  4. package/demo/app/page.tsx +440 -0
  5. package/demo/components/ThemeSwitcher.tsx +611 -0
  6. package/demo/next.config.mjs +7 -0
  7. package/demo/package.json +29 -0
  8. package/demo/postcss.config.mjs +7 -0
  9. package/demo/public/logo.svg +1 -0
  10. package/demo/styles/globals.css +19 -0
  11. package/demo/tailwind.config.ts +90 -0
  12. package/demo/tsconfig.json +42 -0
  13. package/dist/components/ChoiceEdgeV2.d.ts +3 -0
  14. package/dist/components/ChoiceEdgeV2.js +103 -0
  15. package/dist/components/CodeBlock.d.ts +8 -0
  16. package/dist/components/CodeBlock.js +24 -0
  17. package/dist/components/ConditionAutocomplete.d.ts +14 -0
  18. package/dist/components/ConditionAutocomplete.js +284 -0
  19. package/dist/components/ConditionalNodeV2.d.ts +16 -0
  20. package/dist/components/ConditionalNodeV2.js +147 -0
  21. package/dist/components/DialogueEditorV2.d.ts +22 -0
  22. package/dist/components/DialogueEditorV2.js +1170 -0
  23. package/dist/components/EdgeIcon.d.ts +8 -0
  24. package/dist/components/EdgeIcon.js +13 -0
  25. package/dist/components/ExampleLoader.d.ts +11 -0
  26. package/dist/components/ExampleLoader.js +52 -0
  27. package/dist/components/ExampleLoaderButton.d.ts +15 -0
  28. package/dist/components/ExampleLoaderButton.js +102 -0
  29. package/dist/components/FlagManager.d.ts +11 -0
  30. package/dist/components/FlagManager.js +282 -0
  31. package/dist/components/FlagSelector.d.ts +11 -0
  32. package/dist/components/FlagSelector.js +235 -0
  33. package/dist/components/GuidePanel.d.ts +7 -0
  34. package/dist/components/GuidePanel.js +1176 -0
  35. package/dist/components/Minimap.d.ts +16 -0
  36. package/dist/components/Minimap.js +93 -0
  37. package/dist/components/NPCEdgeV2.d.ts +3 -0
  38. package/dist/components/NPCEdgeV2.js +104 -0
  39. package/dist/components/NPCNodeV2.d.ts +26 -0
  40. package/dist/components/NPCNodeV2.js +86 -0
  41. package/dist/components/NodeEditor.d.ts +18 -0
  42. package/dist/components/NodeEditor.js +1025 -0
  43. package/dist/components/PlayView.d.ts +12 -0
  44. package/dist/components/PlayView.js +307 -0
  45. package/dist/components/PlayerNodeV2.d.ts +16 -0
  46. package/dist/components/PlayerNodeV2.js +139 -0
  47. package/dist/components/ReactFlowPOC.d.ts +61 -0
  48. package/dist/components/ReactFlowPOC.js +312 -0
  49. package/dist/components/ScenePlayer.d.ts +18 -0
  50. package/dist/components/ScenePlayer.js +196 -0
  51. package/dist/components/YarnView.d.ts +9 -0
  52. package/dist/components/YarnView.js +45 -0
  53. package/dist/components/ZoomControls.d.ts +11 -0
  54. package/dist/components/ZoomControls.js +34 -0
  55. package/dist/esm/components/ChoiceEdgeV2.d.ts +3 -0
  56. package/dist/esm/components/ChoiceEdgeV2.js +67 -0
  57. package/dist/esm/components/CodeBlock.d.ts +8 -0
  58. package/dist/esm/components/CodeBlock.js +18 -0
  59. package/dist/esm/components/ConditionAutocomplete.d.ts +14 -0
  60. package/dist/esm/components/ConditionAutocomplete.js +248 -0
  61. package/dist/esm/components/ConditionalNodeV2.d.ts +16 -0
  62. package/dist/esm/components/ConditionalNodeV2.js +111 -0
  63. package/dist/esm/components/DialogueEditorV2.d.ts +22 -0
  64. package/dist/esm/components/DialogueEditorV2.js +1134 -0
  65. package/dist/esm/components/EdgeIcon.d.ts +8 -0
  66. package/dist/esm/components/EdgeIcon.js +7 -0
  67. package/dist/esm/components/ExampleLoader.d.ts +11 -0
  68. package/dist/esm/components/ExampleLoader.js +46 -0
  69. package/dist/esm/components/ExampleLoaderButton.d.ts +15 -0
  70. package/dist/esm/components/ExampleLoaderButton.js +66 -0
  71. package/dist/esm/components/FlagManager.d.ts +11 -0
  72. package/dist/esm/components/FlagManager.js +246 -0
  73. package/dist/esm/components/FlagSelector.d.ts +11 -0
  74. package/dist/esm/components/FlagSelector.js +199 -0
  75. package/dist/esm/components/GuidePanel.d.ts +7 -0
  76. package/dist/esm/components/GuidePanel.js +1140 -0
  77. package/dist/esm/components/Minimap.d.ts +16 -0
  78. package/dist/esm/components/Minimap.js +57 -0
  79. package/dist/esm/components/NPCEdgeV2.d.ts +3 -0
  80. package/dist/esm/components/NPCEdgeV2.js +68 -0
  81. package/dist/esm/components/NPCNodeV2.d.ts +26 -0
  82. package/dist/esm/components/NPCNodeV2.js +80 -0
  83. package/dist/esm/components/NodeEditor.d.ts +18 -0
  84. package/dist/esm/components/NodeEditor.js +989 -0
  85. package/dist/esm/components/PlayView.d.ts +12 -0
  86. package/dist/esm/components/PlayView.js +271 -0
  87. package/dist/esm/components/PlayerNodeV2.d.ts +16 -0
  88. package/dist/esm/components/PlayerNodeV2.js +103 -0
  89. package/dist/esm/components/ReactFlowPOC.d.ts +61 -0
  90. package/dist/esm/components/ReactFlowPOC.js +275 -0
  91. package/dist/esm/components/ScenePlayer.d.ts +18 -0
  92. package/dist/esm/components/ScenePlayer.js +160 -0
  93. package/dist/esm/components/YarnView.d.ts +9 -0
  94. package/dist/esm/components/YarnView.js +39 -0
  95. package/dist/esm/components/ZoomControls.d.ts +11 -0
  96. package/dist/esm/components/ZoomControls.js +28 -0
  97. package/dist/esm/examples/example-loader.d.ts +29 -0
  98. package/dist/esm/examples/example-loader.js +103 -0
  99. package/dist/esm/examples/examples-registry.d.ts +38 -0
  100. package/dist/esm/examples/examples-registry.js +153 -0
  101. package/dist/esm/examples/index.d.ts +26 -0
  102. package/dist/esm/examples/index.js +50 -0
  103. package/dist/esm/examples/legacy-examples.d.ts +9 -0
  104. package/dist/esm/examples/legacy-examples.js +814 -0
  105. package/dist/esm/examples/yarn-examples.d.ts +35 -0
  106. package/dist/esm/examples/yarn-examples.js +181 -0
  107. package/dist/esm/index.d.ts +21 -0
  108. package/dist/esm/index.js +26 -0
  109. package/dist/esm/lib/flag-manager.d.ts +21 -0
  110. package/dist/esm/lib/flag-manager.js +93 -0
  111. package/dist/esm/lib/yarn-converter/__tests__/round-trip.test.d.ts +1 -0
  112. package/dist/esm/lib/yarn-converter/__tests__/round-trip.test.js +169 -0
  113. package/dist/esm/lib/yarn-converter.d.ts +17 -0
  114. package/dist/esm/lib/yarn-converter.js +521 -0
  115. package/dist/esm/lib/yarn-runner/__tests__/condition-evaluator.test.d.ts +1 -0
  116. package/dist/esm/lib/yarn-runner/__tests__/condition-evaluator.test.js +171 -0
  117. package/dist/esm/lib/yarn-runner/__tests__/node-processor.test.d.ts +1 -0
  118. package/dist/esm/lib/yarn-runner/__tests__/node-processor.test.js +237 -0
  119. package/dist/esm/lib/yarn-runner/__tests__/variable-manager.test.d.ts +1 -0
  120. package/dist/esm/lib/yarn-runner/__tests__/variable-manager.test.js +106 -0
  121. package/dist/esm/lib/yarn-runner/condition-evaluator.d.ts +12 -0
  122. package/dist/esm/lib/yarn-runner/condition-evaluator.js +56 -0
  123. package/dist/esm/lib/yarn-runner/index.d.ts +12 -0
  124. package/dist/esm/lib/yarn-runner/index.js +11 -0
  125. package/dist/esm/lib/yarn-runner/node-processor.d.ts +18 -0
  126. package/dist/esm/lib/yarn-runner/node-processor.js +129 -0
  127. package/dist/esm/lib/yarn-runner/variable-manager.d.ts +51 -0
  128. package/dist/esm/lib/yarn-runner/variable-manager.js +120 -0
  129. package/dist/esm/lib/yarn-runner/variable-operations.d.ts +16 -0
  130. package/dist/esm/lib/yarn-runner/variable-operations.js +88 -0
  131. package/dist/esm/types/conditionals.d.ts +29 -0
  132. package/dist/esm/types/conditionals.js +1 -0
  133. package/dist/esm/types/constants.d.ts +59 -0
  134. package/dist/esm/types/constants.js +55 -0
  135. package/dist/esm/types/flags.d.ts +49 -0
  136. package/dist/esm/types/flags.js +49 -0
  137. package/dist/esm/types/game-state.d.ts +62 -0
  138. package/dist/esm/types/game-state.js +6 -0
  139. package/dist/esm/types/index.d.ts +77 -0
  140. package/dist/esm/types/index.js +1 -0
  141. package/dist/esm/utils/constants.d.ts +5 -0
  142. package/dist/esm/utils/constants.js +5 -0
  143. package/dist/esm/utils/feature-flags.d.ts +11 -0
  144. package/dist/esm/utils/feature-flags.js +11 -0
  145. package/dist/esm/utils/game-state-flattener.d.ts +41 -0
  146. package/dist/esm/utils/game-state-flattener.js +135 -0
  147. package/dist/esm/utils/layout/collision.d.ts +27 -0
  148. package/dist/esm/utils/layout/collision.js +74 -0
  149. package/dist/esm/utils/layout/index.d.ts +82 -0
  150. package/dist/esm/utils/layout/index.js +98 -0
  151. package/dist/esm/utils/layout/registry.d.ts +91 -0
  152. package/dist/esm/utils/layout/registry.js +148 -0
  153. package/dist/esm/utils/layout/strategies/dagre.d.ts +19 -0
  154. package/dist/esm/utils/layout/strategies/dagre.js +182 -0
  155. package/dist/esm/utils/layout/strategies/force.d.ts +21 -0
  156. package/dist/esm/utils/layout/strategies/force.js +178 -0
  157. package/dist/esm/utils/layout/strategies/grid.d.ts +17 -0
  158. package/dist/esm/utils/layout/strategies/grid.js +91 -0
  159. package/dist/esm/utils/layout/strategies/index.d.ts +8 -0
  160. package/dist/esm/utils/layout/strategies/index.js +8 -0
  161. package/dist/esm/utils/layout/types.d.ts +100 -0
  162. package/dist/esm/utils/layout/types.js +7 -0
  163. package/dist/esm/utils/layout.d.ts +9 -0
  164. package/dist/esm/utils/layout.js +17 -0
  165. package/dist/esm/utils/node-helpers.d.ts +7 -0
  166. package/dist/esm/utils/node-helpers.js +94 -0
  167. package/dist/esm/utils/reactflow-converter.d.ts +42 -0
  168. package/dist/esm/utils/reactflow-converter.js +217 -0
  169. package/dist/examples/example-loader.d.ts +29 -0
  170. package/dist/examples/example-loader.js +109 -0
  171. package/dist/examples/examples-registry.d.ts +38 -0
  172. package/dist/examples/examples-registry.js +160 -0
  173. package/dist/examples/index.d.ts +26 -0
  174. package/dist/examples/index.js +63 -0
  175. package/dist/examples/legacy-examples.d.ts +9 -0
  176. package/dist/examples/legacy-examples.js +817 -0
  177. package/dist/examples/yarn-examples.d.ts +35 -0
  178. package/dist/examples/yarn-examples.js +189 -0
  179. package/dist/index.d.ts +21 -0
  180. package/dist/index.js +66 -0
  181. package/dist/lib/flag-manager.d.ts +21 -0
  182. package/dist/lib/flag-manager.js +99 -0
  183. package/dist/lib/yarn-converter/__tests__/round-trip.test.d.ts +1 -0
  184. package/dist/lib/yarn-converter/__tests__/round-trip.test.js +171 -0
  185. package/dist/lib/yarn-converter.d.ts +17 -0
  186. package/dist/lib/yarn-converter.js +525 -0
  187. package/dist/lib/yarn-runner/__tests__/condition-evaluator.test.d.ts +1 -0
  188. package/dist/lib/yarn-runner/__tests__/condition-evaluator.test.js +173 -0
  189. package/dist/lib/yarn-runner/__tests__/node-processor.test.d.ts +1 -0
  190. package/dist/lib/yarn-runner/__tests__/node-processor.test.js +239 -0
  191. package/dist/lib/yarn-runner/__tests__/variable-manager.test.d.ts +1 -0
  192. package/dist/lib/yarn-runner/__tests__/variable-manager.test.js +108 -0
  193. package/dist/lib/yarn-runner/condition-evaluator.d.ts +12 -0
  194. package/dist/lib/yarn-runner/condition-evaluator.js +60 -0
  195. package/dist/lib/yarn-runner/index.d.ts +12 -0
  196. package/dist/lib/yarn-runner/index.js +21 -0
  197. package/dist/lib/yarn-runner/node-processor.d.ts +18 -0
  198. package/dist/lib/yarn-runner/node-processor.js +133 -0
  199. package/dist/lib/yarn-runner/variable-manager.d.ts +51 -0
  200. package/dist/lib/yarn-runner/variable-manager.js +124 -0
  201. package/dist/lib/yarn-runner/variable-operations.d.ts +16 -0
  202. package/dist/lib/yarn-runner/variable-operations.js +92 -0
  203. package/dist/types/conditionals.d.ts +29 -0
  204. package/dist/types/conditionals.js +2 -0
  205. package/dist/types/constants.d.ts +59 -0
  206. package/dist/types/constants.js +58 -0
  207. package/dist/types/flags.d.ts +49 -0
  208. package/dist/types/flags.js +52 -0
  209. package/dist/types/game-state.d.ts +62 -0
  210. package/dist/types/game-state.js +7 -0
  211. package/dist/types/index.d.ts +77 -0
  212. package/dist/types/index.js +2 -0
  213. package/dist/utils/constants.d.ts +5 -0
  214. package/dist/utils/constants.js +8 -0
  215. package/dist/utils/feature-flags.d.ts +11 -0
  216. package/dist/utils/feature-flags.js +14 -0
  217. package/dist/utils/game-state-flattener.d.ts +41 -0
  218. package/dist/utils/game-state-flattener.js +140 -0
  219. package/dist/utils/layout/collision.d.ts +27 -0
  220. package/dist/utils/layout/collision.js +77 -0
  221. package/dist/utils/layout/index.d.ts +82 -0
  222. package/dist/utils/layout/index.js +109 -0
  223. package/dist/utils/layout/registry.d.ts +91 -0
  224. package/dist/utils/layout/registry.js +151 -0
  225. package/dist/utils/layout/strategies/dagre.d.ts +19 -0
  226. package/dist/utils/layout/strategies/dagre.js +189 -0
  227. package/dist/utils/layout/strategies/force.d.ts +21 -0
  228. package/dist/utils/layout/strategies/force.js +182 -0
  229. package/dist/utils/layout/strategies/grid.d.ts +17 -0
  230. package/dist/utils/layout/strategies/grid.js +95 -0
  231. package/dist/utils/layout/strategies/index.d.ts +8 -0
  232. package/dist/utils/layout/strategies/index.js +14 -0
  233. package/dist/utils/layout/types.d.ts +100 -0
  234. package/dist/utils/layout/types.js +8 -0
  235. package/dist/utils/layout.d.ts +9 -0
  236. package/dist/utils/layout.js +25 -0
  237. package/dist/utils/node-helpers.d.ts +7 -0
  238. package/dist/utils/node-helpers.js +101 -0
  239. package/dist/utils/reactflow-converter.d.ts +42 -0
  240. package/dist/utils/reactflow-converter.js +223 -0
  241. package/package.json +70 -0
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processNode = processNode;
4
+ exports.isValidNextNode = isValidNextNode;
5
+ const condition_evaluator_1 = require("./condition-evaluator");
6
+ /**
7
+ * Processes a dialogue node and returns the result
8
+ */
9
+ function processNode(node, variableManager) {
10
+ // Player nodes - return choices
11
+ if (node.type === 'player') {
12
+ const availableChoices = node.choices?.filter(choice => {
13
+ if (!choice.conditions)
14
+ return true;
15
+ return (0, condition_evaluator_1.evaluateConditions)(choice.conditions, variableManager.getAllVariables(), variableManager.getAllMemoryFlags());
16
+ }) || [];
17
+ return {
18
+ content: '',
19
+ speaker: undefined,
20
+ nextNodeId: undefined,
21
+ isEnd: false,
22
+ isPlayerChoice: true,
23
+ choices: availableChoices
24
+ };
25
+ }
26
+ // Conditional nodes - evaluate blocks
27
+ if (node.type === 'conditional' && node.conditionalBlocks) {
28
+ const matchedBlock = findMatchingConditionalBlock(node.conditionalBlocks, variableManager);
29
+ if (matchedBlock) {
30
+ // Interpolate variables in content
31
+ const interpolatedContent = interpolateVariables(matchedBlock.content, variableManager);
32
+ return {
33
+ content: interpolatedContent,
34
+ speaker: matchedBlock.speaker,
35
+ nextNodeId: matchedBlock.nextNodeId || node.nextNodeId,
36
+ isEnd: !matchedBlock.nextNodeId && !node.nextNodeId,
37
+ isPlayerChoice: false,
38
+ choices: undefined
39
+ };
40
+ }
41
+ // No block matched - end dialogue
42
+ return {
43
+ content: '',
44
+ speaker: undefined,
45
+ nextNodeId: undefined,
46
+ isEnd: true,
47
+ isPlayerChoice: false,
48
+ choices: undefined
49
+ };
50
+ }
51
+ // NPC nodes - handle conditional blocks if present
52
+ if (node.type === 'npc') {
53
+ let content = node.content;
54
+ let speaker = node.speaker;
55
+ let nextNodeId = node.nextNodeId;
56
+ // Check for conditional blocks
57
+ if (node.conditionalBlocks && node.conditionalBlocks.length > 0) {
58
+ const matchedBlock = findMatchingConditionalBlock(node.conditionalBlocks, variableManager);
59
+ if (matchedBlock) {
60
+ content = matchedBlock.content;
61
+ speaker = matchedBlock.speaker || node.speaker;
62
+ // Conditional blocks can override nextNodeId
63
+ if (matchedBlock.nextNodeId) {
64
+ nextNodeId = matchedBlock.nextNodeId;
65
+ }
66
+ }
67
+ }
68
+ // Interpolate variables in content (e.g., "Hello {$name}")
69
+ content = interpolateVariables(content, variableManager);
70
+ return {
71
+ content,
72
+ speaker,
73
+ nextNodeId,
74
+ isEnd: !nextNodeId,
75
+ isPlayerChoice: false,
76
+ choices: undefined
77
+ };
78
+ }
79
+ // Default: end dialogue
80
+ return {
81
+ content: '',
82
+ speaker: undefined,
83
+ nextNodeId: undefined,
84
+ isEnd: true,
85
+ isPlayerChoice: false,
86
+ choices: undefined
87
+ };
88
+ }
89
+ /**
90
+ * Finds the first matching conditional block (if/elseif/else logic)
91
+ */
92
+ function findMatchingConditionalBlock(blocks, variableManager) {
93
+ let matchedBlock = null;
94
+ for (const block of blocks) {
95
+ if (block.type === 'else') {
96
+ // Only match else if no previous block matched
97
+ if (!matchedBlock) {
98
+ matchedBlock = block;
99
+ }
100
+ }
101
+ else if (block.condition && block.condition.length > 0) {
102
+ // Check if all conditions in this block are true
103
+ const allMatch = (0, condition_evaluator_1.evaluateConditions)(block.condition, variableManager.getAllVariables(), variableManager.getAllMemoryFlags());
104
+ if (allMatch) {
105
+ matchedBlock = block;
106
+ break; // Found a match, stop checking (if/elseif matched)
107
+ }
108
+ }
109
+ }
110
+ return matchedBlock;
111
+ }
112
+ /**
113
+ * Interpolates variables in text (e.g., "Hello {$name}" becomes "Hello John")
114
+ */
115
+ function interpolateVariables(text, variableManager) {
116
+ // Match {$variable} patterns
117
+ return text.replace(/\{\$(\w+)\}/g, (match, varName) => {
118
+ const value = variableManager.get(varName);
119
+ if (value === undefined) {
120
+ return match; // Keep original if variable not found
121
+ }
122
+ return String(value);
123
+ });
124
+ }
125
+ /**
126
+ * Validates that a nextNodeId exists and is valid
127
+ */
128
+ function isValidNextNode(nextNodeId, availableNodes) {
129
+ if (!nextNodeId || !nextNodeId.trim()) {
130
+ return false;
131
+ }
132
+ return !!availableNodes[nextNodeId];
133
+ }
@@ -0,0 +1,51 @@
1
+ import { VariableState } from './condition-evaluator';
2
+ /**
3
+ * Manages variable state for Yarn Spinner execution
4
+ * Handles both game flags (persistent) and dialogue flags (temporary)
5
+ */
6
+ export declare class VariableManager {
7
+ private variables;
8
+ private memoryFlags;
9
+ constructor(initialVariables?: VariableState, initialMemoryFlags?: Set<string>);
10
+ /**
11
+ * Get a variable value
12
+ */
13
+ get(name: string): boolean | number | string | undefined;
14
+ /**
15
+ * Set a variable value
16
+ */
17
+ set(name: string, value: boolean | number | string): void;
18
+ /**
19
+ * Apply an operation to a variable (e.g., +=, -=, *=, /=)
20
+ * If the variable doesn't exist, it's initialized to 0 for numeric operations
21
+ */
22
+ applyOperation(name: string, operator: '+' | '-' | '*' | '/', value: number): void;
23
+ /**
24
+ * Add a memory flag (dialogue flag - temporary)
25
+ */
26
+ addMemoryFlag(name: string): void;
27
+ /**
28
+ * Remove a memory flag
29
+ */
30
+ removeMemoryFlag(name: string): void;
31
+ /**
32
+ * Check if a memory flag exists
33
+ */
34
+ hasMemoryFlag(name: string): boolean;
35
+ /**
36
+ * Get all variables (persistent)
37
+ */
38
+ getAllVariables(): VariableState;
39
+ /**
40
+ * Get all memory flags
41
+ */
42
+ getAllMemoryFlags(): Set<string>;
43
+ /**
44
+ * Clear all memory flags (for dialogue reset)
45
+ */
46
+ clearMemoryFlags(): void;
47
+ /**
48
+ * Reset to initial state
49
+ */
50
+ reset(initialVariables?: VariableState, initialMemoryFlags?: Set<string>): void;
51
+ }
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VariableManager = void 0;
4
+ /**
5
+ * Manages variable state for Yarn Spinner execution
6
+ * Handles both game flags (persistent) and dialogue flags (temporary)
7
+ */
8
+ class VariableManager {
9
+ constructor(initialVariables, initialMemoryFlags) {
10
+ this.variables = {};
11
+ this.memoryFlags = new Set();
12
+ if (initialVariables) {
13
+ this.variables = { ...initialVariables };
14
+ }
15
+ if (initialMemoryFlags) {
16
+ this.memoryFlags = new Set(initialMemoryFlags);
17
+ }
18
+ }
19
+ /**
20
+ * Get a variable value
21
+ */
22
+ get(name) {
23
+ // Check persistent variables first
24
+ if (this.variables[name] !== undefined) {
25
+ return this.variables[name];
26
+ }
27
+ // Check memory flags (dialogue flags)
28
+ if (this.memoryFlags.has(name)) {
29
+ return true;
30
+ }
31
+ return undefined;
32
+ }
33
+ /**
34
+ * Set a variable value
35
+ */
36
+ set(name, value) {
37
+ this.variables[name] = value;
38
+ }
39
+ /**
40
+ * Apply an operation to a variable (e.g., +=, -=, *=, /=)
41
+ * If the variable doesn't exist, it's initialized to 0 for numeric operations
42
+ */
43
+ applyOperation(name, operator, value) {
44
+ const current = this.get(name);
45
+ let currentNum;
46
+ if (current === undefined) {
47
+ currentNum = 0;
48
+ }
49
+ else if (typeof current === 'number') {
50
+ currentNum = current;
51
+ }
52
+ else if (typeof current === 'string') {
53
+ // Try to parse string as number
54
+ const parsed = parseFloat(current);
55
+ currentNum = isNaN(parsed) ? 0 : parsed;
56
+ }
57
+ else {
58
+ // Boolean: treat true as 1, false as 0
59
+ currentNum = current ? 1 : 0;
60
+ }
61
+ let result;
62
+ switch (operator) {
63
+ case '+':
64
+ result = currentNum + value;
65
+ break;
66
+ case '-':
67
+ result = currentNum - value;
68
+ break;
69
+ case '*':
70
+ result = currentNum * value;
71
+ break;
72
+ case '/':
73
+ result = value !== 0 ? currentNum / value : currentNum;
74
+ break;
75
+ default:
76
+ result = currentNum;
77
+ }
78
+ this.variables[name] = result;
79
+ }
80
+ /**
81
+ * Add a memory flag (dialogue flag - temporary)
82
+ */
83
+ addMemoryFlag(name) {
84
+ this.memoryFlags.add(name);
85
+ }
86
+ /**
87
+ * Remove a memory flag
88
+ */
89
+ removeMemoryFlag(name) {
90
+ this.memoryFlags.delete(name);
91
+ }
92
+ /**
93
+ * Check if a memory flag exists
94
+ */
95
+ hasMemoryFlag(name) {
96
+ return this.memoryFlags.has(name);
97
+ }
98
+ /**
99
+ * Get all variables (persistent)
100
+ */
101
+ getAllVariables() {
102
+ return { ...this.variables };
103
+ }
104
+ /**
105
+ * Get all memory flags
106
+ */
107
+ getAllMemoryFlags() {
108
+ return new Set(this.memoryFlags);
109
+ }
110
+ /**
111
+ * Clear all memory flags (for dialogue reset)
112
+ */
113
+ clearMemoryFlags() {
114
+ this.memoryFlags.clear();
115
+ }
116
+ /**
117
+ * Reset to initial state
118
+ */
119
+ reset(initialVariables, initialMemoryFlags) {
120
+ this.variables = initialVariables ? { ...initialVariables } : {};
121
+ this.memoryFlags = initialMemoryFlags ? new Set(initialMemoryFlags) : new Set();
122
+ }
123
+ }
124
+ exports.VariableManager = VariableManager;
@@ -0,0 +1,16 @@
1
+ import { VariableManager } from './variable-manager';
2
+ /**
3
+ * Parses and executes a Yarn variable operation command
4
+ * Supports:
5
+ * - <<set $var = value>> (assignment)
6
+ * - <<set $var += value>> (addition)
7
+ * - <<set $var -= value>> (subtraction)
8
+ * - <<set $var *= value>> (multiplication)
9
+ * - <<set $var /= value>> (division)
10
+ */
11
+ export declare function executeVariableOperation(command: string, variableManager: VariableManager): void;
12
+ /**
13
+ * Extracts and executes all variable operations from a node's content
14
+ * This processes any <<set>> commands embedded in the dialogue text
15
+ */
16
+ export declare function processVariableOperationsInContent(content: string, variableManager: VariableManager): string;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeVariableOperation = executeVariableOperation;
4
+ exports.processVariableOperationsInContent = processVariableOperationsInContent;
5
+ /**
6
+ * Parses and executes a Yarn variable operation command
7
+ * Supports:
8
+ * - <<set $var = value>> (assignment)
9
+ * - <<set $var += value>> (addition)
10
+ * - <<set $var -= value>> (subtraction)
11
+ * - <<set $var *= value>> (multiplication)
12
+ * - <<set $var /= value>> (division)
13
+ */
14
+ function executeVariableOperation(command, variableManager) {
15
+ // Match: <<set $var = value>> or <<set $var += value>> etc.
16
+ const setMatch = command.match(/<<set\s+\$(\w+)\s*([+\-*/=]+)\s*(.+?)>>/);
17
+ if (!setMatch) {
18
+ return; // Invalid command, skip
19
+ }
20
+ const varName = setMatch[1];
21
+ const operator = setMatch[2].trim();
22
+ const valueStr = setMatch[3].trim();
23
+ // Parse the value
24
+ let value;
25
+ // Try to parse as number first
26
+ const numValue = parseFloat(valueStr);
27
+ if (!isNaN(numValue) && valueStr === String(numValue)) {
28
+ value = numValue;
29
+ }
30
+ else if (valueStr === 'true') {
31
+ value = true;
32
+ }
33
+ else if (valueStr === 'false') {
34
+ value = false;
35
+ }
36
+ else {
37
+ // Remove quotes if present
38
+ value = valueStr.replace(/^["']|["']$/g, '');
39
+ }
40
+ // Handle operations
41
+ if (operator === '=') {
42
+ // Simple assignment
43
+ variableManager.set(varName, value);
44
+ }
45
+ else if (operator === '+=') {
46
+ // Addition
47
+ if (typeof value === 'number') {
48
+ variableManager.applyOperation(varName, '+', value);
49
+ }
50
+ else {
51
+ // String concatenation
52
+ const current = variableManager.get(varName);
53
+ const currentStr = current !== undefined ? String(current) : '';
54
+ variableManager.set(varName, currentStr + String(value));
55
+ }
56
+ }
57
+ else if (operator === '-=') {
58
+ // Subtraction (numeric only)
59
+ if (typeof value === 'number') {
60
+ variableManager.applyOperation(varName, '-', value);
61
+ }
62
+ }
63
+ else if (operator === '*=') {
64
+ // Multiplication (numeric only)
65
+ if (typeof value === 'number') {
66
+ variableManager.applyOperation(varName, '*', value);
67
+ }
68
+ }
69
+ else if (operator === '/=') {
70
+ // Division (numeric only)
71
+ if (typeof value === 'number') {
72
+ variableManager.applyOperation(varName, '/', value);
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * Extracts and executes all variable operations from a node's content
78
+ * This processes any <<set>> commands embedded in the dialogue text
79
+ */
80
+ function processVariableOperationsInContent(content, variableManager) {
81
+ // Find all <<set>> commands
82
+ const setCommandRegex = /<<set\s+\$(\w+)\s*([+\-*/=]+)\s*(.+?)>>/g;
83
+ let processedContent = content;
84
+ let match;
85
+ while ((match = setCommandRegex.exec(content)) !== null) {
86
+ // Execute the command
87
+ executeVariableOperation(match[0], variableManager);
88
+ // Remove the command from content (it's executed, not displayed)
89
+ processedContent = processedContent.replace(match[0], '');
90
+ }
91
+ return processedContent.trim();
92
+ }
@@ -0,0 +1,29 @@
1
+ import { ConditionOperator } from './constants';
2
+ /**
3
+ * Conditional block for Yarn Spinner if/elseif/else/endif
4
+ */
5
+ export interface ConditionalBlock {
6
+ type: 'if' | 'elseif' | 'else';
7
+ condition?: {
8
+ flag: string;
9
+ operator: ConditionOperator | 'equals' | 'not_equals' | 'greater_than' | 'less_than' | 'greater_equal' | 'less_equal';
10
+ value?: boolean | number | string;
11
+ };
12
+ content: string;
13
+ nextNodeId?: string;
14
+ }
15
+ /**
16
+ * Extended DialogueNode with conditional support
17
+ */
18
+ export interface ConditionalDialogueNode {
19
+ id: string;
20
+ type: 'npc' | 'player' | 'conditional';
21
+ speaker?: string;
22
+ content: string;
23
+ choices?: any[];
24
+ nextNodeId?: string;
25
+ setFlags?: string[];
26
+ conditionals?: ConditionalBlock[];
27
+ x: number;
28
+ y: number;
29
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Type-safe constants for Dialogue Forge
3
+ * Use these instead of string literals for better type safety and IDE support
4
+ */
5
+ /**
6
+ * Node types in a dialogue tree
7
+ */
8
+ export declare const NODE_TYPE: {
9
+ readonly NPC: "npc";
10
+ readonly PLAYER: "player";
11
+ readonly CONDITIONAL: "conditional";
12
+ };
13
+ export type NodeType = typeof NODE_TYPE[keyof typeof NODE_TYPE];
14
+ /**
15
+ * Flag types for game state management
16
+ */
17
+ export declare const FLAG_TYPE: {
18
+ readonly DIALOGUE: "dialogue";
19
+ readonly QUEST: "quest";
20
+ readonly ACHIEVEMENT: "achievement";
21
+ readonly ITEM: "item";
22
+ readonly STAT: "stat";
23
+ readonly TITLE: "title";
24
+ readonly GLOBAL: "global";
25
+ };
26
+ /**
27
+ * Condition operators for choice visibility
28
+ */
29
+ export declare const CONDITION_OPERATOR: {
30
+ readonly IS_SET: "is_set";
31
+ readonly IS_NOT_SET: "is_not_set";
32
+ readonly EQUALS: "equals";
33
+ readonly NOT_EQUALS: "not_equals";
34
+ readonly GREATER_THAN: "greater_than";
35
+ readonly LESS_THAN: "less_than";
36
+ readonly GREATER_EQUAL: "greater_equal";
37
+ readonly LESS_EQUAL: "less_equal";
38
+ };
39
+ export type ConditionOperator = typeof CONDITION_OPERATOR[keyof typeof CONDITION_OPERATOR];
40
+ /**
41
+ * Flag value types
42
+ */
43
+ export declare const FLAG_VALUE_TYPE: {
44
+ readonly BOOLEAN: "boolean";
45
+ readonly NUMBER: "number";
46
+ readonly STRING: "string";
47
+ };
48
+ export type FlagValueType = typeof FLAG_VALUE_TYPE[keyof typeof FLAG_VALUE_TYPE];
49
+ /**
50
+ * Quest state values (common states for quest flags)
51
+ */
52
+ export declare const QUEST_STATE: {
53
+ readonly NOT_STARTED: "not_started";
54
+ readonly STARTED: "started";
55
+ readonly IN_PROGRESS: "in_progress";
56
+ readonly COMPLETED: "completed";
57
+ readonly FAILED: "failed";
58
+ };
59
+ export type QuestState = typeof QUEST_STATE[keyof typeof QUEST_STATE];
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ /**
3
+ * Type-safe constants for Dialogue Forge
4
+ * Use these instead of string literals for better type safety and IDE support
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.QUEST_STATE = exports.FLAG_VALUE_TYPE = exports.CONDITION_OPERATOR = exports.FLAG_TYPE = exports.NODE_TYPE = void 0;
8
+ /**
9
+ * Node types in a dialogue tree
10
+ */
11
+ exports.NODE_TYPE = {
12
+ NPC: 'npc',
13
+ PLAYER: 'player',
14
+ CONDITIONAL: 'conditional',
15
+ };
16
+ /**
17
+ * Flag types for game state management
18
+ */
19
+ exports.FLAG_TYPE = {
20
+ DIALOGUE: 'dialogue',
21
+ QUEST: 'quest',
22
+ ACHIEVEMENT: 'achievement',
23
+ ITEM: 'item',
24
+ STAT: 'stat',
25
+ TITLE: 'title',
26
+ GLOBAL: 'global',
27
+ };
28
+ /**
29
+ * Condition operators for choice visibility
30
+ */
31
+ exports.CONDITION_OPERATOR = {
32
+ IS_SET: 'is_set',
33
+ IS_NOT_SET: 'is_not_set',
34
+ EQUALS: 'equals',
35
+ NOT_EQUALS: 'not_equals',
36
+ GREATER_THAN: 'greater_than',
37
+ LESS_THAN: 'less_than',
38
+ GREATER_EQUAL: 'greater_equal',
39
+ LESS_EQUAL: 'less_equal',
40
+ };
41
+ /**
42
+ * Flag value types
43
+ */
44
+ exports.FLAG_VALUE_TYPE = {
45
+ BOOLEAN: 'boolean',
46
+ NUMBER: 'number',
47
+ STRING: 'string',
48
+ };
49
+ /**
50
+ * Quest state values (common states for quest flags)
51
+ */
52
+ exports.QUEST_STATE = {
53
+ NOT_STARTED: 'not_started',
54
+ STARTED: 'started',
55
+ IN_PROGRESS: 'in_progress',
56
+ COMPLETED: 'completed',
57
+ FAILED: 'failed',
58
+ };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Flag System for Dialogue Forge
3
+ *
4
+ * Flags represent game state that can be checked and modified by dialogues.
5
+ * Different flag types serve different purposes in the game.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { FLAG_TYPE, FlagSchema } from '@magicborn/dialogue-forge';
10
+ *
11
+ * const mySchema: FlagSchema = {
12
+ * flags: [
13
+ * {
14
+ * id: 'quest_main',
15
+ * name: 'Main Quest',
16
+ * type: FLAG_TYPE.QUEST,
17
+ * category: 'quests'
18
+ * }
19
+ * ]
20
+ * };
21
+ * ```
22
+ */
23
+ import { FLAG_TYPE, FlagValueType } from './constants';
24
+ export type FlagType = typeof FLAG_TYPE[keyof typeof FLAG_TYPE];
25
+ export interface FlagDefinition {
26
+ id: string;
27
+ name: string;
28
+ description?: string;
29
+ type: FlagType;
30
+ category?: string;
31
+ defaultValue?: boolean | number | string;
32
+ valueType?: FlagValueType;
33
+ }
34
+ export interface FlagSchema {
35
+ flags: FlagDefinition[];
36
+ categories?: string[];
37
+ }
38
+ /**
39
+ * Flag Reference - used in dialogue nodes
40
+ */
41
+ export interface FlagReference {
42
+ flagId: string;
43
+ operator?: 'is_set' | 'is_not_set' | 'equals' | 'greater_than' | 'less_than';
44
+ value?: boolean | number | string;
45
+ }
46
+ /**
47
+ * Example flag schema for a game
48
+ */
49
+ export declare const exampleFlagSchema: FlagSchema;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ /**
3
+ * Flag System for Dialogue Forge
4
+ *
5
+ * Flags represent game state that can be checked and modified by dialogues.
6
+ * Different flag types serve different purposes in the game.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { FLAG_TYPE, FlagSchema } from '@magicborn/dialogue-forge';
11
+ *
12
+ * const mySchema: FlagSchema = {
13
+ * flags: [
14
+ * {
15
+ * id: 'quest_main',
16
+ * name: 'Main Quest',
17
+ * type: FLAG_TYPE.QUEST,
18
+ * category: 'quests'
19
+ * }
20
+ * ]
21
+ * };
22
+ * ```
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.exampleFlagSchema = void 0;
26
+ const constants_1 = require("./constants");
27
+ /**
28
+ * Example flag schema for a game
29
+ */
30
+ exports.exampleFlagSchema = {
31
+ categories: ['quests', 'achievements', 'items', 'stats', 'titles'],
32
+ flags: [
33
+ // Quest flags
34
+ { id: 'quest_dragon_slayer', name: 'Dragon Slayer Quest', type: constants_1.FLAG_TYPE.QUEST, category: 'quests', valueType: constants_1.FLAG_VALUE_TYPE.STRING },
35
+ { id: 'quest_dragon_slayer_complete', name: 'Dragon Slayer Complete', type: constants_1.FLAG_TYPE.QUEST, category: 'quests' },
36
+ // Achievement flags
37
+ { id: 'achievement_first_quest', name: 'First Quest', type: constants_1.FLAG_TYPE.ACHIEVEMENT, category: 'achievements' },
38
+ { id: 'achievement_dragon_slayer', name: 'Dragon Slayer', type: constants_1.FLAG_TYPE.ACHIEVEMENT, category: 'achievements' },
39
+ // Item flags
40
+ { id: 'item_ancient_key', name: 'Ancient Key', type: constants_1.FLAG_TYPE.ITEM, category: 'items' },
41
+ { id: 'item_gold', name: 'Gold', type: constants_1.FLAG_TYPE.STAT, category: 'stats', valueType: constants_1.FLAG_VALUE_TYPE.NUMBER, defaultValue: 0 },
42
+ // Stat flags
43
+ { id: 'stat_reputation', name: 'Reputation', type: constants_1.FLAG_TYPE.STAT, category: 'stats', valueType: constants_1.FLAG_VALUE_TYPE.NUMBER, defaultValue: 0 },
44
+ { id: 'stat_charisma', name: 'Charisma', type: constants_1.FLAG_TYPE.STAT, category: 'stats', valueType: constants_1.FLAG_VALUE_TYPE.NUMBER, defaultValue: 10 },
45
+ // Title flags
46
+ { id: 'title_hero', name: 'Hero', type: constants_1.FLAG_TYPE.TITLE, category: 'titles' },
47
+ // Dialogue flags (temporary, dialogue-scoped)
48
+ { id: 'dialogue_met_stranger', name: 'Met Stranger', type: constants_1.FLAG_TYPE.DIALOGUE, category: 'dialogue' },
49
+ { id: 'dialogue_seeks_knowledge', name: 'Seeks Knowledge', type: constants_1.FLAG_TYPE.DIALOGUE, category: 'dialogue' },
50
+ { id: 'dialogue_hostile', name: 'Hostile Response', type: constants_1.FLAG_TYPE.DIALOGUE, category: 'dialogue' },
51
+ ]
52
+ };