@doodle-engine/core 0.0.7 → 0.0.8

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.
package/dist/core.js CHANGED
@@ -1,224 +1,224 @@
1
1
  var L = Object.defineProperty;
2
- var k = (e, t, n) => t in e ? L(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
- var v = (e, t, n) => k(e, typeof t != "symbol" ? t + "" : t, n);
4
- function x(e, t) {
5
- switch (e.type) {
2
+ var x = (n, t, e) => t in n ? L(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
+ var v = (n, t, e) => x(n, typeof t != "symbol" ? t + "" : t, e);
4
+ function O(n, t) {
5
+ switch (n.type) {
6
6
  case "hasFlag":
7
- return O(e.flag, t);
7
+ return k(n.flag, t);
8
8
  case "notFlag":
9
- return V(e.flag, t);
9
+ return V(n.flag, t);
10
10
  case "hasItem":
11
- return R(e.itemId, t);
11
+ return R(n.itemId, t);
12
12
  case "variableEquals":
13
- return P(e.variable, e.value, t);
13
+ return D(n.variable, n.value, t);
14
14
  case "variableGreaterThan":
15
- return D(e.variable, e.value, t);
15
+ return P(n.variable, n.value, t);
16
16
  case "variableLessThan":
17
- return q(e.variable, e.value, t);
17
+ return $(n.variable, n.value, t);
18
18
  case "atLocation":
19
- return W(e.locationId, t);
19
+ return q(n.locationId, t);
20
20
  case "questAtStage":
21
- return F(e.questId, e.stageId, t);
21
+ return F(n.questId, n.stageId, t);
22
22
  case "characterAt":
23
- return M(e.characterId, e.locationId, t);
23
+ return W(n.characterId, n.locationId, t);
24
24
  case "characterInParty":
25
- return G(e.characterId, t);
25
+ return M(n.characterId, t);
26
26
  case "relationshipAbove":
27
- return $(e.characterId, e.value, t);
27
+ return G(n.characterId, n.value, t);
28
28
  case "relationshipBelow":
29
- return H(e.characterId, e.value, t);
29
+ return H(n.characterId, n.value, t);
30
30
  case "timeIs":
31
- return U(e.startHour, e.endHour, t);
31
+ return j(n.startHour, n.endHour, t);
32
32
  case "itemAt":
33
- return j(e.itemId, e.locationId, t);
33
+ return Q(n.itemId, n.locationId, t);
34
34
  default:
35
35
  return !1;
36
36
  }
37
37
  }
38
- function A(e, t) {
39
- return e.every((n) => x(n, t));
38
+ function I(n, t) {
39
+ return n.every((e) => O(e, t));
40
40
  }
41
- function O(e, t) {
42
- return t.flags[e] === !0;
41
+ function k(n, t) {
42
+ return t.flags[n] === !0;
43
43
  }
44
- function V(e, t) {
45
- return t.flags[e] !== !0;
44
+ function V(n, t) {
45
+ return t.flags[n] !== !0;
46
46
  }
47
- function R(e, t) {
48
- return t.inventory.includes(e);
47
+ function R(n, t) {
48
+ return t.inventory.includes(n);
49
49
  }
50
- function P(e, t, n) {
51
- return n.variables[e] === t;
50
+ function D(n, t, e) {
51
+ return e.variables[n] === t;
52
52
  }
53
- function D(e, t, n) {
54
- const r = n.variables[e];
53
+ function P(n, t, e) {
54
+ const r = e.variables[n];
55
55
  return typeof r == "number" && r > t;
56
56
  }
57
- function q(e, t, n) {
58
- const r = n.variables[e];
57
+ function $(n, t, e) {
58
+ const r = e.variables[n];
59
59
  return typeof r == "number" && r < t;
60
60
  }
61
- function W(e, t) {
62
- return t.currentLocation === e;
61
+ function q(n, t) {
62
+ return t.currentLocation === n;
63
63
  }
64
- function F(e, t, n) {
65
- return n.questProgress[e] === t;
64
+ function F(n, t, e) {
65
+ return e.questProgress[n] === t;
66
66
  }
67
- function M(e, t, n) {
68
- const r = n.characterState[e];
67
+ function W(n, t, e) {
68
+ const r = e.characterState[n];
69
69
  return (r == null ? void 0 : r.location) === t;
70
70
  }
71
- function G(e, t) {
72
- const n = t.characterState[e];
73
- return (n == null ? void 0 : n.inParty) === !0;
71
+ function M(n, t) {
72
+ const e = t.characterState[n];
73
+ return (e == null ? void 0 : e.inParty) === !0;
74
74
  }
75
- function $(e, t, n) {
76
- const r = n.characterState[e];
75
+ function G(n, t, e) {
76
+ const r = e.characterState[n];
77
77
  return r !== void 0 && r.relationship > t;
78
78
  }
79
- function H(e, t, n) {
80
- const r = n.characterState[e];
79
+ function H(n, t, e) {
80
+ const r = e.characterState[n];
81
81
  return r !== void 0 && r.relationship < t;
82
82
  }
83
- function U(e, t, n) {
84
- const r = n.currentTime.hour;
85
- return e < t ? r >= e && r < t : r >= e || r < t;
83
+ function j(n, t, e) {
84
+ const r = e.currentTime.hour;
85
+ return n < t ? r >= n && r < t : r >= n || r < t;
86
86
  }
87
- function j(e, t, n) {
88
- return n.itemLocations[e] === t;
87
+ function Q(n, t, e) {
88
+ return e.itemLocations[n] === t;
89
89
  }
90
- function J(e, t) {
91
- switch (e.type) {
90
+ function J(n, t) {
91
+ switch (n.type) {
92
92
  case "setFlag":
93
- return Q(e.flag, t);
93
+ return U(n.flag, t);
94
94
  case "clearFlag":
95
- return B(e.flag, t);
95
+ return B(n.flag, t);
96
96
  case "setVariable":
97
- return _(e.variable, e.value, t);
97
+ return _(n.variable, n.value, t);
98
98
  case "addVariable":
99
- return z(e.variable, e.value, t);
99
+ return z(n.variable, n.value, t);
100
100
  case "addItem":
101
- return Y(e.itemId, t);
101
+ return Y(n.itemId, t);
102
102
  case "removeItem":
103
- return K(e.itemId, t);
103
+ return K(n.itemId, t);
104
104
  case "moveItem":
105
- return X(e.itemId, e.locationId, t);
105
+ return X(n.itemId, n.locationId, t);
106
106
  case "goToLocation":
107
- return Z(e.locationId, t);
107
+ return Z(n.locationId, t);
108
108
  case "advanceTime":
109
- return tt(e.hours, t);
109
+ return tt(n.hours, t);
110
110
  case "setQuestStage":
111
- return et(e.questId, e.stageId, t);
111
+ return et(n.questId, n.stageId, t);
112
112
  case "addJournalEntry":
113
- return nt(e.entryId, t);
113
+ return nt(n.entryId, t);
114
114
  case "startDialogue":
115
- return rt(e.dialogueId, t);
115
+ return rt(n.dialogueId, t);
116
116
  case "endDialogue":
117
117
  return at(t);
118
118
  case "setCharacterLocation":
119
- return it(e.characterId, e.locationId, t);
119
+ return it(n.characterId, n.locationId, t);
120
120
  case "addToParty":
121
- return st(e.characterId, t);
121
+ return st(n.characterId, t);
122
122
  case "removeFromParty":
123
- return ot(e.characterId, t);
123
+ return ot(n.characterId, t);
124
124
  case "setRelationship":
125
- return ct(e.characterId, e.value, t);
125
+ return ct(n.characterId, n.value, t);
126
126
  case "addRelationship":
127
- return ut(e.characterId, e.value, t);
127
+ return lt(n.characterId, n.value, t);
128
128
  case "setCharacterStat":
129
- return lt(e.characterId, e.stat, e.value, t);
129
+ return ut(n.characterId, n.stat, n.value, t);
130
130
  case "addCharacterStat":
131
- return dt(e.characterId, e.stat, e.value, t);
131
+ return dt(n.characterId, n.stat, n.value, t);
132
132
  case "setMapEnabled":
133
- return ht(e.enabled, t);
133
+ return ht(n.enabled, t);
134
134
  case "playMusic":
135
135
  return t;
136
136
  case "playSound":
137
- return ft(e.sound, t);
137
+ return gt(n.sound, t);
138
138
  case "notify":
139
- return pt(e.message, t);
139
+ return pt(n.message, t);
140
140
  case "playVideo":
141
- return mt(e.file, t);
141
+ return ft(n.file, t);
142
142
  default:
143
143
  return t;
144
144
  }
145
145
  }
146
- function y(e, t) {
147
- return e.reduce((n, r) => J(r, n), t);
146
+ function y(n, t) {
147
+ return n.reduce((e, r) => J(r, e), t);
148
148
  }
149
- function Q(e, t) {
149
+ function U(n, t) {
150
150
  return {
151
151
  ...t,
152
152
  flags: {
153
153
  ...t.flags,
154
- [e]: !0
154
+ [n]: !0
155
155
  }
156
156
  };
157
157
  }
158
- function B(e, t) {
158
+ function B(n, t) {
159
159
  return {
160
160
  ...t,
161
161
  flags: {
162
162
  ...t.flags,
163
- [e]: !1
163
+ [n]: !1
164
164
  }
165
165
  };
166
166
  }
167
- function _(e, t, n) {
167
+ function _(n, t, e) {
168
168
  return {
169
- ...n,
169
+ ...e,
170
170
  variables: {
171
- ...n.variables,
172
- [e]: t
171
+ ...e.variables,
172
+ [n]: t
173
173
  }
174
174
  };
175
175
  }
176
- function z(e, t, n) {
177
- const r = n.variables[e], a = typeof r == "number" ? r + t : t;
176
+ function z(n, t, e) {
177
+ const r = e.variables[n], a = typeof r == "number" ? r + t : t;
178
178
  return {
179
- ...n,
179
+ ...e,
180
180
  variables: {
181
- ...n.variables,
182
- [e]: a
181
+ ...e.variables,
182
+ [n]: a
183
183
  }
184
184
  };
185
185
  }
186
- function Y(e, t) {
187
- return t.inventory.includes(e) ? t : {
186
+ function Y(n, t) {
187
+ return t.inventory.includes(n) ? t : {
188
188
  ...t,
189
- inventory: [...t.inventory, e],
189
+ inventory: [...t.inventory, n],
190
190
  itemLocations: {
191
191
  ...t.itemLocations,
192
- [e]: "inventory"
192
+ [n]: "inventory"
193
193
  }
194
194
  };
195
195
  }
196
- function K(e, t) {
196
+ function K(n, t) {
197
197
  return {
198
198
  ...t,
199
- inventory: t.inventory.filter((n) => n !== e)
199
+ inventory: t.inventory.filter((e) => e !== n)
200
200
  // Note: itemLocation is NOT updated here - the item stays at "inventory"
201
201
  // or wherever it was. Use moveItem to relocate it.
202
202
  };
203
203
  }
204
- function X(e, t, n) {
204
+ function X(n, t, e) {
205
205
  return {
206
- ...n,
207
- inventory: n.inventory.filter((r) => r !== e),
206
+ ...e,
207
+ inventory: e.inventory.filter((r) => r !== n),
208
208
  itemLocations: {
209
- ...n.itemLocations,
210
- [e]: t
209
+ ...e.itemLocations,
210
+ [n]: t
211
211
  }
212
212
  };
213
213
  }
214
- function Z(e, t) {
214
+ function Z(n, t) {
215
215
  return {
216
216
  ...t,
217
- currentLocation: e
217
+ currentLocation: n
218
218
  };
219
219
  }
220
- function tt(e, t) {
221
- const n = t.currentTime.hour + e, r = Math.floor(n / 24), a = n % 24;
220
+ function tt(n, t) {
221
+ const e = t.currentTime.hour + n, r = Math.floor(e / 24), a = e % 24;
222
222
  return {
223
223
  ...t,
224
224
  currentTime: {
@@ -227,128 +227,128 @@ function tt(e, t) {
227
227
  }
228
228
  };
229
229
  }
230
- function et(e, t, n) {
230
+ function et(n, t, e) {
231
231
  return {
232
- ...n,
232
+ ...e,
233
233
  questProgress: {
234
- ...n.questProgress,
235
- [e]: t
234
+ ...e.questProgress,
235
+ [n]: t
236
236
  }
237
237
  };
238
238
  }
239
- function nt(e, t) {
240
- return t.unlockedJournalEntries.includes(e) ? t : {
239
+ function nt(n, t) {
240
+ return t.unlockedJournalEntries.includes(n) ? t : {
241
241
  ...t,
242
- unlockedJournalEntries: [...t.unlockedJournalEntries, e]
242
+ unlockedJournalEntries: [...t.unlockedJournalEntries, n]
243
243
  };
244
244
  }
245
- function rt(e, t) {
245
+ function rt(n, t) {
246
246
  return {
247
247
  ...t,
248
248
  dialogueState: {
249
- dialogueId: e,
249
+ dialogueId: n,
250
250
  nodeId: ""
251
251
  // Will be set by engine when it looks up the dialogue
252
252
  }
253
253
  };
254
254
  }
255
- function at(e) {
255
+ function at(n) {
256
256
  return {
257
- ...e,
257
+ ...n,
258
258
  dialogueState: null
259
259
  };
260
260
  }
261
- function it(e, t, n) {
262
- const r = n.characterState[e];
261
+ function it(n, t, e) {
262
+ const r = e.characterState[n];
263
263
  return r ? {
264
- ...n,
264
+ ...e,
265
265
  characterState: {
266
- ...n.characterState,
267
- [e]: {
266
+ ...e.characterState,
267
+ [n]: {
268
268
  ...r,
269
269
  location: t
270
270
  }
271
271
  }
272
- } : n;
272
+ } : e;
273
273
  }
274
- function st(e, t) {
275
- const n = t.characterState[e];
276
- return n ? {
274
+ function st(n, t) {
275
+ const e = t.characterState[n];
276
+ return e ? {
277
277
  ...t,
278
278
  characterState: {
279
279
  ...t.characterState,
280
- [e]: {
281
- ...n,
280
+ [n]: {
281
+ ...e,
282
282
  inParty: !0
283
283
  }
284
284
  }
285
285
  } : t;
286
286
  }
287
- function ot(e, t) {
288
- const n = t.characterState[e];
289
- return n ? {
287
+ function ot(n, t) {
288
+ const e = t.characterState[n];
289
+ return e ? {
290
290
  ...t,
291
291
  characterState: {
292
292
  ...t.characterState,
293
- [e]: {
294
- ...n,
293
+ [n]: {
294
+ ...e,
295
295
  inParty: !1
296
296
  }
297
297
  }
298
298
  } : t;
299
299
  }
300
- function ct(e, t, n) {
301
- const r = n.characterState[e];
300
+ function ct(n, t, e) {
301
+ const r = e.characterState[n];
302
302
  return r ? {
303
- ...n,
303
+ ...e,
304
304
  characterState: {
305
- ...n.characterState,
306
- [e]: {
305
+ ...e.characterState,
306
+ [n]: {
307
307
  ...r,
308
308
  relationship: t
309
309
  }
310
310
  }
311
- } : n;
311
+ } : e;
312
312
  }
313
- function ut(e, t, n) {
314
- const r = n.characterState[e];
313
+ function lt(n, t, e) {
314
+ const r = e.characterState[n];
315
315
  return r ? {
316
- ...n,
316
+ ...e,
317
317
  characterState: {
318
- ...n.characterState,
319
- [e]: {
318
+ ...e.characterState,
319
+ [n]: {
320
320
  ...r,
321
321
  relationship: r.relationship + t
322
322
  }
323
323
  }
324
- } : n;
324
+ } : e;
325
325
  }
326
- function lt(e, t, n, r) {
327
- const a = r.characterState[e];
326
+ function ut(n, t, e, r) {
327
+ const a = r.characterState[n];
328
328
  return a ? {
329
329
  ...r,
330
330
  characterState: {
331
331
  ...r.characterState,
332
- [e]: {
332
+ [n]: {
333
333
  ...a,
334
334
  stats: {
335
335
  ...a.stats,
336
- [t]: n
336
+ [t]: e
337
337
  }
338
338
  }
339
339
  }
340
340
  } : r;
341
341
  }
342
- function dt(e, t, n, r) {
343
- const a = r.characterState[e];
342
+ function dt(n, t, e, r) {
343
+ const a = r.characterState[n];
344
344
  if (!a)
345
345
  return r;
346
- const s = a.stats[t], i = typeof s == "number" ? s + n : n;
346
+ const s = a.stats[t], i = typeof s == "number" ? s + e : e;
347
347
  return {
348
348
  ...r,
349
349
  characterState: {
350
350
  ...r.characterState,
351
- [e]: {
351
+ [n]: {
352
352
  ...a,
353
353
  stats: {
354
354
  ...a.stats,
@@ -358,84 +358,84 @@ function dt(e, t, n, r) {
358
358
  }
359
359
  };
360
360
  }
361
- function ht(e, t) {
361
+ function ht(n, t) {
362
362
  return {
363
363
  ...t,
364
- mapEnabled: e
364
+ mapEnabled: n
365
365
  };
366
366
  }
367
- function pt(e, t) {
367
+ function pt(n, t) {
368
368
  return {
369
369
  ...t,
370
- notifications: [...t.notifications, e]
370
+ notifications: [...t.notifications, n]
371
371
  };
372
372
  }
373
- function ft(e, t) {
373
+ function gt(n, t) {
374
374
  return {
375
375
  ...t,
376
- pendingSounds: [...t.pendingSounds, e]
376
+ pendingSounds: [...t.pendingSounds, n]
377
377
  };
378
378
  }
379
- function mt(e, t) {
379
+ function ft(n, t) {
380
380
  return {
381
381
  ...t,
382
- pendingVideo: e
382
+ pendingVideo: n
383
383
  };
384
384
  }
385
- function w(e, t) {
386
- if (!e.startsWith("@"))
387
- return e;
388
- const n = e.slice(1);
389
- return t[n] ?? e;
385
+ function A(n, t) {
386
+ if (!n.startsWith("@"))
387
+ return n;
388
+ const e = n.slice(1);
389
+ return t[e] ?? n;
390
390
  }
391
- function Ot(e) {
392
- return (t) => w(t, e);
391
+ function kt(n) {
392
+ return (t) => A(t, n);
393
393
  }
394
- function gt(e, t) {
395
- const n = t.locales[e.currentLocale] ?? {}, r = (C) => w(C, n), a = bt(e.currentLocation, t, r), s = yt(e, t, r), i = St(e, t, r), { dialogue: o, choices: c } = vt(e, t, r), u = It(e, t, r), d = Tt(e, t, r), m = Et(e, t, r), g = At(e, t, r), l = e.mapEnabled ? wt(e, t, r) : null, f = t.locations[e.currentLocation], h = (f == null ? void 0 : f.music) ?? "", p = (f == null ? void 0 : f.ambient) ?? "", b = e.notifications.map(r), S = [...e.pendingSounds], N = e.pendingVideo;
394
+ function mt(n, t) {
395
+ const e = t.locales[n.currentLocale] ?? {}, r = (C) => A(C, e), a = bt(n.currentLocation, t, r), s = yt(n, t, r), i = St(n, t, r), { dialogue: o, choices: c } = vt(n, t, r), l = It(n, t, r), d = Tt(n, t, r), f = Nt(n, t, r), m = Et(n, t, r), u = n.mapEnabled ? At(n, t, r) : null, g = t.locations[n.currentLocation], h = (g == null ? void 0 : g.music) ?? "", p = (g == null ? void 0 : g.ambient) ?? "", b = n.notifications.map(r), S = [...n.pendingSounds], w = n.pendingVideo;
396
396
  return {
397
397
  location: a,
398
398
  charactersHere: s,
399
399
  itemsHere: i,
400
400
  choices: c,
401
401
  dialogue: o,
402
- party: u,
402
+ party: l,
403
403
  inventory: d,
404
- quests: m,
405
- journal: g,
406
- variables: { ...e.variables },
407
- time: e.currentTime,
408
- map: l,
404
+ quests: f,
405
+ journal: m,
406
+ variables: { ...n.variables },
407
+ time: n.currentTime,
408
+ map: u,
409
409
  music: h,
410
410
  ambient: p,
411
411
  notifications: b,
412
412
  pendingSounds: S,
413
- pendingVideo: N
413
+ pendingVideo: w
414
414
  };
415
415
  }
416
- function bt(e, t, n) {
417
- const r = t.locations[e];
416
+ function bt(n, t, e) {
417
+ const r = t.locations[n];
418
418
  return r ? {
419
419
  id: r.id,
420
- name: n(r.name),
421
- description: n(r.description),
420
+ name: e(r.name),
421
+ description: e(r.description),
422
422
  banner: r.banner
423
423
  } : {
424
- id: e,
425
- name: e,
426
- description: `Location not found: ${e}`,
424
+ id: n,
425
+ name: n,
426
+ description: `Location not found: ${n}`,
427
427
  banner: ""
428
428
  };
429
429
  }
430
- function yt(e, t, n) {
430
+ function yt(n, t, e) {
431
431
  const r = [];
432
- for (const [a, s] of Object.entries(e.characterState))
433
- if (s.location === e.currentLocation) {
432
+ for (const [a, s] of Object.entries(n.characterState))
433
+ if (s.location === n.currentLocation) {
434
434
  const i = t.characters[a];
435
435
  i && r.push({
436
436
  id: i.id,
437
- name: n(i.name),
438
- biography: n(i.biography),
437
+ name: e(i.name),
438
+ biography: e(i.biography),
439
439
  portrait: i.portrait,
440
440
  location: s.location,
441
441
  inParty: s.inParty,
@@ -445,15 +445,15 @@ function yt(e, t, n) {
445
445
  }
446
446
  return r;
447
447
  }
448
- function St(e, t, n) {
448
+ function St(n, t, e) {
449
449
  const r = [];
450
- for (const [a, s] of Object.entries(e.itemLocations))
451
- if (s === e.currentLocation) {
450
+ for (const [a, s] of Object.entries(n.itemLocations))
451
+ if (s === n.currentLocation) {
452
452
  const i = t.items[a];
453
453
  i && r.push({
454
454
  id: i.id,
455
- name: n(i.name),
456
- description: n(i.description),
455
+ name: e(i.name),
456
+ description: e(i.description),
457
457
  icon: i.icon,
458
458
  image: i.image,
459
459
  stats: i.stats
@@ -461,40 +461,40 @@ function St(e, t, n) {
461
461
  }
462
462
  return r;
463
463
  }
464
- function vt(e, t, n) {
465
- var c, u;
466
- if (!e.dialogueState)
464
+ function vt(n, t, e) {
465
+ var c, l;
466
+ if (!n.dialogueState)
467
467
  return { dialogue: null, choices: [] };
468
- const r = t.dialogues[e.dialogueState.dialogueId];
468
+ const r = t.dialogues[n.dialogueState.dialogueId];
469
469
  if (!r)
470
470
  return { dialogue: null, choices: [] };
471
471
  const a = r.nodes.find((d) => {
472
- var m;
473
- return d.id === ((m = e.dialogueState) == null ? void 0 : m.nodeId);
472
+ var f;
473
+ return d.id === ((f = n.dialogueState) == null ? void 0 : f.nodeId);
474
474
  });
475
475
  if (!a)
476
476
  return { dialogue: null, choices: [] };
477
- const s = a.speaker ? n(((c = t.characters[a.speaker]) == null ? void 0 : c.name) ?? a.speaker) : "Narrator", i = {
477
+ const s = a.speaker ? e(((c = t.characters[a.speaker]) == null ? void 0 : c.name) ?? a.speaker) : "Narrator", i = {
478
478
  speaker: a.speaker,
479
479
  speakerName: s,
480
- text: n(a.text),
481
- portrait: a.portrait ?? ((u = t.characters[a.speaker ?? ""]) == null ? void 0 : u.portrait),
480
+ text: e(a.text),
481
+ portrait: a.portrait ?? ((l = t.characters[a.speaker ?? ""]) == null ? void 0 : l.portrait),
482
482
  voice: a.voice
483
- }, o = a.choices.filter((d) => !d.conditions || d.conditions.length === 0 ? !0 : A(d.conditions, e)).map((d) => ({
483
+ }, o = a.choices.filter((d) => !d.conditions || d.conditions.length === 0 ? !0 : I(d.conditions, n)).map((d) => ({
484
484
  id: d.id,
485
- text: n(d.text)
485
+ text: e(d.text)
486
486
  }));
487
487
  return { dialogue: i, choices: o };
488
488
  }
489
- function It(e, t, n) {
489
+ function It(n, t, e) {
490
490
  const r = [];
491
- for (const [a, s] of Object.entries(e.characterState))
491
+ for (const [a, s] of Object.entries(n.characterState))
492
492
  if (s.inParty) {
493
493
  const i = t.characters[a];
494
494
  i && r.push({
495
495
  id: i.id,
496
- name: n(i.name),
497
- biography: n(i.biography),
496
+ name: e(i.name),
497
+ biography: e(i.biography),
498
498
  portrait: i.portrait,
499
499
  location: s.location,
500
500
  inParty: s.inParty,
@@ -504,47 +504,47 @@ function It(e, t, n) {
504
504
  }
505
505
  return r;
506
506
  }
507
- function Tt(e, t, n) {
508
- return e.inventory.map((r) => {
507
+ function Tt(n, t, e) {
508
+ return n.inventory.map((r) => {
509
509
  const a = t.items[r];
510
510
  return a ? {
511
511
  id: a.id,
512
- name: n(a.name),
513
- description: n(a.description),
512
+ name: e(a.name),
513
+ description: e(a.description),
514
514
  icon: a.icon,
515
515
  image: a.image,
516
516
  stats: a.stats
517
517
  } : null;
518
518
  }).filter((r) => r !== null);
519
519
  }
520
- function Et(e, t, n) {
520
+ function Nt(n, t, e) {
521
521
  const r = [];
522
- for (const [a, s] of Object.entries(e.questProgress)) {
522
+ for (const [a, s] of Object.entries(n.questProgress)) {
523
523
  const i = t.quests[a];
524
524
  if (!i) continue;
525
525
  const o = i.stages.find((c) => c.id === s);
526
526
  o && r.push({
527
527
  id: i.id,
528
- name: n(i.name),
529
- description: n(i.description),
528
+ name: e(i.name),
529
+ description: e(i.description),
530
530
  currentStage: o.id,
531
- currentStageDescription: n(o.description)
531
+ currentStageDescription: e(o.description)
532
532
  });
533
533
  }
534
534
  return r;
535
535
  }
536
- function At(e, t, n) {
537
- return e.unlockedJournalEntries.map((r) => {
536
+ function Et(n, t, e) {
537
+ return n.unlockedJournalEntries.map((r) => {
538
538
  const a = t.journalEntries[r];
539
539
  return a ? {
540
540
  id: a.id,
541
- title: n(a.title),
542
- text: n(a.text),
541
+ title: e(a.title),
542
+ text: e(a.text),
543
543
  category: a.category
544
544
  } : null;
545
545
  }).filter((r) => r !== null);
546
546
  }
547
- function wt(e, t, n) {
547
+ function At(n, t, e) {
548
548
  const r = Object.keys(t.maps);
549
549
  if (r.length === 0) return null;
550
550
  const a = t.maps[r[0]];
@@ -553,15 +553,15 @@ function wt(e, t, n) {
553
553
  const o = t.locations[i.id];
554
554
  return {
555
555
  id: i.id,
556
- name: o ? n(o.name) : i.id,
556
+ name: o ? e(o.name) : i.id,
557
557
  x: i.x,
558
558
  y: i.y,
559
- isCurrent: i.id === e.currentLocation
559
+ isCurrent: i.id === n.currentLocation
560
560
  };
561
561
  });
562
562
  return {
563
563
  id: a.id,
564
- name: n(a.name),
564
+ name: e(a.name),
565
565
  image: a.image,
566
566
  scale: a.scale,
567
567
  locations: s
@@ -574,10 +574,10 @@ class Vt {
574
574
  * @param registry - Content registry with all game entities
575
575
  * @param state - Initial game state
576
576
  */
577
- constructor(t, n) {
577
+ constructor(t, e) {
578
578
  v(this, "registry");
579
579
  v(this, "state");
580
- this.registry = t, this.state = n;
580
+ this.registry = t, this.state = e;
581
581
  }
582
582
  // ===========================================================================
583
583
  // Core API Methods
@@ -591,9 +591,9 @@ class Vt {
591
591
  * @returns Initial snapshot
592
592
  */
593
593
  newGame(t) {
594
- const n = {};
594
+ const e = {};
595
595
  for (const [a, s] of Object.entries(this.registry.characters))
596
- n[a] = {
596
+ e[a] = {
597
597
  location: s.location,
598
598
  inParty: !1,
599
599
  relationship: 0,
@@ -613,7 +613,7 @@ class Vt {
613
613
  unlockedJournalEntries: [],
614
614
  playerNotes: [],
615
615
  dialogueState: null,
616
- characterState: n,
616
+ characterState: e,
617
617
  itemLocations: r,
618
618
  mapEnabled: !0,
619
619
  notifications: [],
@@ -659,10 +659,10 @@ class Vt {
659
659
  selectChoice(t) {
660
660
  if (!this.state.dialogueState)
661
661
  return this.buildSnapshotAndClearTransients();
662
- const n = this.registry.dialogues[this.state.dialogueState.dialogueId];
663
- if (!n)
662
+ const e = this.registry.dialogues[this.state.dialogueState.dialogueId];
663
+ if (!e)
664
664
  return this.buildSnapshotAndClearTransients();
665
- const r = n.nodes.find((i) => {
665
+ const r = e.nodes.find((i) => {
666
666
  var o;
667
667
  return i.id === ((o = this.state.dialogueState) == null ? void 0 : o.nodeId);
668
668
  });
@@ -672,17 +672,32 @@ class Vt {
672
672
  if (!a)
673
673
  return this.buildSnapshotAndClearTransients();
674
674
  a.effects && (this.state = y(a.effects, this.state));
675
- const s = n.nodes.find((i) => i.id === a.next);
676
- return s ? (this.state = {
675
+ const s = e.nodes.find((i) => i.id === a.next);
676
+ if (!s)
677
+ return this.state = {
678
+ ...this.state,
679
+ dialogueState: null
680
+ }, this.buildSnapshotAndClearTransients();
681
+ if (this.state = {
677
682
  ...this.state,
678
683
  dialogueState: {
679
- dialogueId: n.id,
684
+ dialogueId: e.id,
680
685
  nodeId: s.id
681
686
  }
682
- }, s.effects && (this.state = y(s.effects, this.state))) : this.state = {
683
- ...this.state,
684
- dialogueState: null
685
- }, this.buildSnapshotAndClearTransients();
687
+ }, s.effects && (this.state = y(s.effects, this.state)), s.choices.length === 0) {
688
+ const i = this.resolveNextNode(s);
689
+ i ? this.state = {
690
+ ...this.state,
691
+ dialogueState: {
692
+ dialogueId: e.id,
693
+ nodeId: i
694
+ }
695
+ } : this.state = {
696
+ ...this.state,
697
+ dialogueState: null
698
+ };
699
+ }
700
+ return this.buildSnapshotAndClearTransients();
686
701
  }
687
702
  /**
688
703
  * Player clicked on a character to talk.
@@ -693,20 +708,35 @@ class Vt {
693
708
  * @returns New snapshot with dialogue started
694
709
  */
695
710
  talkTo(t) {
696
- const n = this.registry.characters[t];
697
- if (!n || !n.dialogue)
711
+ const e = this.registry.characters[t];
712
+ if (!e || !e.dialogue)
698
713
  return this.buildSnapshotAndClearTransients();
699
- const r = this.registry.dialogues[n.dialogue];
714
+ const r = this.registry.dialogues[e.dialogue];
700
715
  if (!r)
701
716
  return this.buildSnapshotAndClearTransients();
702
717
  const a = r.nodes.find((s) => s.id === r.startNode);
703
- return a ? (this.state = {
718
+ if (!a)
719
+ return this.buildSnapshotAndClearTransients();
720
+ if (this.state = {
704
721
  ...this.state,
705
722
  dialogueState: {
706
723
  dialogueId: r.id,
707
724
  nodeId: a.id
708
725
  }
709
- }, a.effects && (this.state = y(a.effects, this.state)), this.buildSnapshotAndClearTransients()) : this.buildSnapshotAndClearTransients();
726
+ }, a.effects && (this.state = y(a.effects, this.state)), a.choices.length === 0) {
727
+ const s = this.resolveNextNode(a);
728
+ s ? this.state = {
729
+ ...this.state,
730
+ dialogueState: {
731
+ dialogueId: r.id,
732
+ nodeId: s
733
+ }
734
+ } : this.state = {
735
+ ...this.state,
736
+ dialogueState: null
737
+ };
738
+ }
739
+ return this.buildSnapshotAndClearTransients();
710
740
  }
711
741
  /**
712
742
  * Player clicked on an item to pick it up.
@@ -737,24 +767,24 @@ class Vt {
737
767
  travelTo(t) {
738
768
  if (!this.state.mapEnabled)
739
769
  return this.buildSnapshotAndClearTransients();
740
- const n = Object.keys(this.registry.maps);
741
- if (n.length === 0)
770
+ const e = Object.keys(this.registry.maps);
771
+ if (e.length === 0)
742
772
  return this.buildSnapshotAndClearTransients();
743
- const r = this.registry.maps[n[0]];
773
+ const r = this.registry.maps[e[0]];
744
774
  if (!r)
745
775
  return this.buildSnapshotAndClearTransients();
746
- const a = r.locations.find((m) => m.id === this.state.currentLocation), s = r.locations.find((m) => m.id === t);
776
+ const a = r.locations.find((f) => f.id === this.state.currentLocation), s = r.locations.find((f) => f.id === t);
747
777
  if (!a || !s)
748
778
  return this.buildSnapshotAndClearTransients();
749
779
  const i = Math.sqrt(
750
780
  Math.pow(s.x - a.x, 2) + Math.pow(s.y - a.y, 2)
751
- ), o = Math.round(i * r.scale), c = this.state.currentTime.hour + o, u = Math.floor(c / 24), d = c % 24;
781
+ ), o = Math.round(i * r.scale), c = this.state.currentTime.hour + o, l = Math.floor(c / 24), d = c % 24;
752
782
  return this.state = {
753
783
  ...this.state,
754
784
  currentLocation: t,
755
785
  dialogueState: null,
756
786
  currentTime: {
757
- day: this.state.currentTime.day + u,
787
+ day: this.state.currentTime.day + l,
758
788
  hour: d
759
789
  }
760
790
  }, this.checkTriggeredDialogues(), this.buildSnapshotAndClearTransients();
@@ -768,11 +798,11 @@ class Vt {
768
798
  * @param text - Note content
769
799
  * @returns New snapshot with note added
770
800
  */
771
- writeNote(t, n) {
801
+ writeNote(t, e) {
772
802
  const r = {
773
803
  id: `note_${Date.now()}`,
774
804
  title: t,
775
- text: n
805
+ text: e
776
806
  };
777
807
  return this.state = {
778
808
  ...this.state,
@@ -790,7 +820,7 @@ class Vt {
790
820
  deleteNote(t) {
791
821
  return this.state = {
792
822
  ...this.state,
793
- playerNotes: this.state.playerNotes.filter((n) => n.id !== t)
823
+ playerNotes: this.state.playerNotes.filter((e) => e.id !== t)
794
824
  }, this.buildSnapshotAndClearTransients();
795
825
  }
796
826
  /**
@@ -825,7 +855,7 @@ class Vt {
825
855
  * Transient state is data that should only appear in one snapshot.
826
856
  */
827
857
  buildSnapshotAndClearTransients() {
828
- const t = gt(this.state, this.registry);
858
+ const t = mt(this.state, this.registry);
829
859
  return this.state = {
830
860
  ...this.state,
831
861
  notifications: [],
@@ -833,6 +863,24 @@ class Vt {
833
863
  pendingVideo: null
834
864
  }, t;
835
865
  }
866
+ /**
867
+ * Resolve the next node ID from a dialogue node.
868
+ *
869
+ * Evaluates conditionalNext (IF blocks) in order, returning the first passing condition's next node.
870
+ * Falls through to node.next if no conditionalNext passes.
871
+ * Returns null if neither exists (end dialogue).
872
+ *
873
+ * @param node - The dialogue node to resolve next from
874
+ * @returns Next node ID, or null to end dialogue
875
+ */
876
+ resolveNextNode(t) {
877
+ if (t.conditionalNext && t.conditionalNext.length > 0) {
878
+ for (const e of t.conditionalNext)
879
+ if (I([e.condition], this.state))
880
+ return e.next;
881
+ }
882
+ return t.next ?? null;
883
+ }
836
884
  /**
837
885
  * Check for dialogues that should auto-trigger at the current location.
838
886
  *
@@ -843,28 +891,40 @@ class Vt {
843
891
  */
844
892
  checkTriggeredDialogues() {
845
893
  for (const t of Object.values(this.registry.dialogues)) {
846
- if (t.triggerLocation !== this.state.currentLocation || t.conditions && !A(t.conditions, this.state))
894
+ if (t.triggerLocation !== this.state.currentLocation || t.conditions && !I(t.conditions, this.state))
847
895
  continue;
848
- const n = t.nodes.find((r) => r.id === t.startNode);
849
- if (n) {
850
- this.state = {
896
+ const e = t.nodes.find((r) => r.id === t.startNode);
897
+ if (e) {
898
+ if (this.state = {
851
899
  ...this.state,
852
900
  dialogueState: {
853
901
  dialogueId: t.id,
854
- nodeId: n.id
902
+ nodeId: e.id
855
903
  }
856
- }, n.effects && (this.state = y(n.effects, this.state));
904
+ }, e.effects && (this.state = y(e.effects, this.state)), e.choices.length === 0) {
905
+ const r = this.resolveNextNode(e);
906
+ r ? this.state = {
907
+ ...this.state,
908
+ dialogueState: {
909
+ dialogueId: t.id,
910
+ nodeId: r
911
+ }
912
+ } : this.state = {
913
+ ...this.state,
914
+ dialogueState: null
915
+ };
916
+ }
857
917
  break;
858
918
  }
859
919
  }
860
920
  }
861
921
  }
862
- function Nt(e) {
863
- return e.split(`
864
- `).map((t, n) => ({
922
+ function wt(n) {
923
+ return n.split(`
924
+ `).map((t, e) => ({
865
925
  original: t,
866
- lineNumber: n + 1
867
- })).map(({ original: t, lineNumber: n }) => {
926
+ lineNumber: e + 1
927
+ })).map(({ original: t, lineNumber: e }) => {
868
928
  let r = t;
869
929
  const a = t.indexOf("#");
870
930
  if (a === -1)
@@ -872,22 +932,22 @@ function Nt(e) {
872
932
  else {
873
933
  const o = t.match(/"[^"]*"/);
874
934
  if (o) {
875
- const c = t.indexOf(o[0]), u = c + o[0].length;
876
- a < c ? r = t.substring(0, a) : a >= c && a < u ? r = t.substring(0, u) + t.substring(u).split("#")[0] : r = t.substring(0, a);
935
+ const c = t.indexOf(o[0]), l = c + o[0].length;
936
+ a < c ? r = t.substring(0, a) : a >= c && a < l ? r = t.substring(0, l) + t.substring(l).split("#")[0] : r = t.substring(0, a);
877
937
  } else
878
938
  r = t.substring(0, a);
879
939
  }
880
940
  const s = r.length - r.trimStart().length;
881
- return { line: r.trim(), lineNumber: n, indent: s };
941
+ return { line: r.trim(), lineNumber: e, indent: s };
882
942
  }).filter((t) => t.line.length > 0);
883
943
  }
884
- function I(e) {
885
- const t = e.trim();
944
+ function T(n) {
945
+ const t = n.trim();
886
946
  return t.startsWith("@") ? t : t.startsWith('"') && t.endsWith('"') ? t.substring(1, t.length - 1) : t;
887
947
  }
888
- function T(e) {
889
- const t = e.trim().split(/\s+/), n = t[0];
890
- switch (n) {
948
+ function N(n) {
949
+ const t = n.trim().split(/\s+/), e = t[0];
950
+ switch (e) {
891
951
  case "hasFlag":
892
952
  return { type: "hasFlag", flag: t[1] };
893
953
  case "notFlag":
@@ -941,229 +1001,229 @@ function T(e) {
941
1001
  case "itemAt":
942
1002
  return { type: "itemAt", itemId: t[1], locationId: t[2] };
943
1003
  default:
944
- throw new Error(`Unknown condition type: ${n}`);
1004
+ throw new Error(`Unknown condition type: ${e}`);
945
1005
  }
946
1006
  }
947
- function E(e) {
948
- const t = e.trim();
1007
+ function E(n) {
1008
+ const t = n.trim();
949
1009
  if (t.startsWith("NOTIFY "))
950
- return { type: "notify", message: I(t.substring(7)) };
1010
+ return { type: "notify", message: T(t.substring(7)) };
951
1011
  if (t.startsWith("MUSIC "))
952
1012
  return { type: "playMusic", track: t.substring(6).trim() };
953
1013
  if (t.startsWith("SOUND "))
954
1014
  return { type: "playSound", sound: t.substring(6).trim() };
955
1015
  if (t.startsWith("VIDEO "))
956
1016
  return { type: "playVideo", file: t.substring(6).trim() };
957
- const n = t.split(/\s+/), r = n[0];
1017
+ const e = t.split(/\s+/), r = e[0];
958
1018
  switch (r) {
959
1019
  case "SET":
960
- if (n[1] === "flag")
961
- return { type: "setFlag", flag: n[2] };
962
- if (n[1] === "variable")
1020
+ if (e[1] === "flag")
1021
+ return { type: "setFlag", flag: e[2] };
1022
+ if (e[1] === "variable")
963
1023
  return {
964
1024
  type: "setVariable",
965
- variable: n[2],
966
- value: isNaN(Number(n[3])) ? n[3] : Number(n[3])
1025
+ variable: e[2],
1026
+ value: isNaN(Number(e[3])) ? e[3] : Number(e[3])
967
1027
  };
968
- if (n[1] === "questStage")
969
- return { type: "setQuestStage", questId: n[2], stageId: n[3] };
970
- if (n[1] === "characterLocation")
1028
+ if (e[1] === "questStage")
1029
+ return { type: "setQuestStage", questId: e[2], stageId: e[3] };
1030
+ if (e[1] === "characterLocation")
971
1031
  return {
972
1032
  type: "setCharacterLocation",
973
- characterId: n[2],
974
- locationId: n[3]
1033
+ characterId: e[2],
1034
+ locationId: e[3]
975
1035
  };
976
- if (n[1] === "relationship")
1036
+ if (e[1] === "relationship")
977
1037
  return {
978
1038
  type: "setRelationship",
979
- characterId: n[2],
980
- value: Number(n[3])
1039
+ characterId: e[2],
1040
+ value: Number(e[3])
981
1041
  };
982
- if (n[1] === "characterStat")
1042
+ if (e[1] === "characterStat")
983
1043
  return {
984
1044
  type: "setCharacterStat",
985
- characterId: n[2],
986
- stat: n[3],
987
- value: isNaN(Number(n[4])) ? n[4] : Number(n[4])
1045
+ characterId: e[2],
1046
+ stat: e[3],
1047
+ value: isNaN(Number(e[4])) ? e[4] : Number(e[4])
988
1048
  };
989
- if (n[1] === "mapEnabled")
990
- return { type: "setMapEnabled", enabled: n[2] === "true" };
991
- throw new Error(`Unknown SET effect: ${n[1]}`);
1049
+ if (e[1] === "mapEnabled")
1050
+ return { type: "setMapEnabled", enabled: e[2] === "true" };
1051
+ throw new Error(`Unknown SET effect: ${e[1]}`);
992
1052
  case "CLEAR":
993
- if (n[1] === "flag")
994
- return { type: "clearFlag", flag: n[2] };
995
- throw new Error(`Unknown CLEAR effect: ${n[1]}`);
1053
+ if (e[1] === "flag")
1054
+ return { type: "clearFlag", flag: e[2] };
1055
+ throw new Error(`Unknown CLEAR effect: ${e[1]}`);
996
1056
  case "ADD":
997
- if (n[1] === "variable")
1057
+ if (e[1] === "variable")
998
1058
  return {
999
1059
  type: "addVariable",
1000
- variable: n[2],
1001
- value: Number(n[3])
1060
+ variable: e[2],
1061
+ value: Number(e[3])
1002
1062
  };
1003
- if (n[1] === "item")
1004
- return { type: "addItem", itemId: n[2] };
1005
- if (n[1] === "journalEntry")
1006
- return { type: "addJournalEntry", entryId: n[2] };
1007
- if (n[1] === "toParty")
1008
- return { type: "addToParty", characterId: n[2] };
1009
- if (n[1] === "relationship")
1063
+ if (e[1] === "item")
1064
+ return { type: "addItem", itemId: e[2] };
1065
+ if (e[1] === "journalEntry")
1066
+ return { type: "addJournalEntry", entryId: e[2] };
1067
+ if (e[1] === "toParty")
1068
+ return { type: "addToParty", characterId: e[2] };
1069
+ if (e[1] === "relationship")
1010
1070
  return {
1011
1071
  type: "addRelationship",
1012
- characterId: n[2],
1013
- value: Number(n[3])
1072
+ characterId: e[2],
1073
+ value: Number(e[3])
1014
1074
  };
1015
- if (n[1] === "characterStat")
1075
+ if (e[1] === "characterStat")
1016
1076
  return {
1017
1077
  type: "addCharacterStat",
1018
- characterId: n[2],
1019
- stat: n[3],
1020
- value: Number(n[4])
1078
+ characterId: e[2],
1079
+ stat: e[3],
1080
+ value: Number(e[4])
1021
1081
  };
1022
- throw new Error(`Unknown ADD effect: ${n[1]}`);
1082
+ throw new Error(`Unknown ADD effect: ${e[1]}`);
1023
1083
  case "REMOVE":
1024
- if (n[1] === "item")
1025
- return { type: "removeItem", itemId: n[2] };
1026
- if (n[1] === "fromParty")
1027
- return { type: "removeFromParty", characterId: n[2] };
1028
- throw new Error(`Unknown REMOVE effect: ${n[1]}`);
1084
+ if (e[1] === "item")
1085
+ return { type: "removeItem", itemId: e[2] };
1086
+ if (e[1] === "fromParty")
1087
+ return { type: "removeFromParty", characterId: e[2] };
1088
+ throw new Error(`Unknown REMOVE effect: ${e[1]}`);
1029
1089
  case "MOVE":
1030
- if (n[1] === "item")
1031
- return { type: "moveItem", itemId: n[2], locationId: n[3] };
1032
- throw new Error(`Unknown MOVE effect: ${n[1]}`);
1090
+ if (e[1] === "item")
1091
+ return { type: "moveItem", itemId: e[2], locationId: e[3] };
1092
+ throw new Error(`Unknown MOVE effect: ${e[1]}`);
1033
1093
  case "GOTO":
1034
- if (n[1] === "location")
1035
- return { type: "goToLocation", locationId: n[2] };
1094
+ if (e[1] === "location")
1095
+ return { type: "goToLocation", locationId: e[2] };
1036
1096
  throw new Error("GOTO should not be parsed as an effect");
1037
1097
  case "ADVANCE":
1038
- if (n[1] === "time")
1039
- return { type: "advanceTime", hours: Number(n[2]) };
1040
- throw new Error(`Unknown ADVANCE effect: ${n[1]}`);
1098
+ if (e[1] === "time")
1099
+ return { type: "advanceTime", hours: Number(e[2]) };
1100
+ throw new Error(`Unknown ADVANCE effect: ${e[1]}`);
1041
1101
  case "START":
1042
- if (n[1] === "dialogue")
1043
- return { type: "startDialogue", dialogueId: n[2] };
1044
- throw new Error(`Unknown START effect: ${n[1]}`);
1102
+ if (e[1] === "dialogue")
1103
+ return { type: "startDialogue", dialogueId: e[2] };
1104
+ throw new Error(`Unknown START effect: ${e[1]}`);
1045
1105
  case "END":
1046
- if (n[1] === "dialogue")
1106
+ if (e[1] === "dialogue")
1047
1107
  return { type: "endDialogue" };
1048
1108
  throw new Error("END should not be parsed as an effect");
1049
1109
  default:
1050
1110
  throw new Error(`Unknown effect keyword: ${r}`);
1051
1111
  }
1052
1112
  }
1053
- function Ct(e, t, n) {
1054
- const r = e[t], a = I(r.line.substring(7)), s = [], i = [];
1113
+ function Ct(n, t, e) {
1114
+ const r = n[t], a = T(r.line.substring(7)), s = [], i = [];
1055
1115
  let o = "", c = t + 1;
1056
- const u = r.indent;
1057
- for (; c < e.length; ) {
1058
- const l = e[c];
1059
- if (l.line === "END" && l.indent === u) {
1116
+ const l = r.indent;
1117
+ for (; c < n.length; ) {
1118
+ const u = n[c];
1119
+ if (u.line === "END" && u.indent === l) {
1060
1120
  c++;
1061
1121
  break;
1062
1122
  }
1063
- if (l.line.startsWith("REQUIRE ")) {
1064
- const f = l.line.substring(8).trim();
1065
- s.push(T(f)), c++;
1066
- } else if (l.line.startsWith("GOTO ")) {
1067
- const f = l.line.substring(5).trim();
1068
- if (f.startsWith("location ")) {
1069
- const h = f.substring(9).trim();
1123
+ if (u.line.startsWith("REQUIRE ")) {
1124
+ const g = u.line.substring(8).trim();
1125
+ s.push(N(g)), c++;
1126
+ } else if (u.line.startsWith("GOTO ")) {
1127
+ const g = u.line.substring(5).trim();
1128
+ if (g.startsWith("location ")) {
1129
+ const h = g.substring(9).trim();
1070
1130
  i.push({ type: "goToLocation", locationId: h }), i.push({ type: "endDialogue" }), o = "";
1071
1131
  } else
1072
- o = f;
1132
+ o = g;
1073
1133
  c++;
1074
- } else l.line.includes(":") || i.push(E(l.line)), c++;
1134
+ } else u.line.includes(":") || i.push(E(u.line)), c++;
1075
1135
  }
1076
1136
  const d = a.replace(/[@"]/g, "").replace(/[^a-z0-9]/gi, "_");
1077
1137
  return { choice: {
1078
- id: `${n}_choice_${d.toLowerCase().substring(0, 30)}`,
1138
+ id: `${e}_choice_${d.toLowerCase().substring(0, 30)}`,
1079
1139
  text: a,
1080
1140
  conditions: s.length > 0 ? s : void 0,
1081
1141
  effects: i.length > 0 ? i : void 0,
1082
1142
  next: o || ""
1083
1143
  }, nextIndex: c };
1084
1144
  }
1085
- function Lt(e, t) {
1086
- const n = e[t], r = n.line.substring(3).trim(), a = T(r);
1145
+ function Lt(n, t) {
1146
+ const e = n[t], r = e.line.substring(3).trim(), a = N(r);
1087
1147
  let s;
1088
1148
  const i = [];
1089
1149
  let o = t + 1;
1090
- const c = n.indent;
1091
- for (; o < e.length; ) {
1092
- const u = e[o];
1093
- if (u.line === "END" && u.indent === c) {
1150
+ const c = e.indent;
1151
+ for (; o < n.length; ) {
1152
+ const l = n[o];
1153
+ if (l.line === "END" && l.indent === c) {
1094
1154
  o++;
1095
1155
  break;
1096
1156
  }
1097
- u.line.startsWith("GOTO ") ? (s = u.line.substring(5).trim(), o++) : (i.push(E(u.line)), o++);
1157
+ l.line.startsWith("GOTO ") ? (s = l.line.substring(5).trim(), o++) : (i.push(E(l.line)), o++);
1098
1158
  }
1099
1159
  return { condition: a, next: s, effects: i, nextIndex: o };
1100
1160
  }
1101
- function kt(e, t) {
1102
- const r = e[t].line.substring(5).trim();
1161
+ function xt(n, t) {
1162
+ const r = n[t].line.substring(5).trim();
1103
1163
  let a = null, s = "", i, o;
1104
- const c = [], u = [], d = [];
1105
- let m;
1106
- const g = [];
1107
- let l = t + 1;
1108
- for (; l < e.length; ) {
1109
- const h = e[l];
1164
+ const c = [], l = [], d = [];
1165
+ let f;
1166
+ const m = [];
1167
+ let u = t + 1;
1168
+ for (; u < n.length; ) {
1169
+ const h = n[u];
1110
1170
  if (h.line.startsWith("NODE "))
1111
1171
  break;
1112
1172
  if (h.line.includes(":") && !h.line.startsWith("VOICE")) {
1113
1173
  const p = h.line.indexOf(":"), b = h.line.substring(0, p).trim(), S = h.line.substring(p + 1).trim();
1114
- b === "NARRATOR" ? a = null : a = b.toLowerCase(), s = I(S), l++;
1174
+ b === "NARRATOR" ? a = null : a = b.toLowerCase(), s = T(S), u++;
1115
1175
  } else if (h.line.startsWith("VOICE "))
1116
- i = h.line.substring(6).trim(), l++;
1176
+ i = h.line.substring(6).trim(), u++;
1117
1177
  else if (h.line.startsWith("PORTRAIT "))
1118
- o = h.line.substring(9).trim(), l++;
1178
+ o = h.line.substring(9).trim(), u++;
1119
1179
  else if (h.line.startsWith("CHOICE ")) {
1120
- const p = Ct(e, l, r);
1121
- u.push(p.choice), l = p.nextIndex;
1180
+ const p = Ct(n, u, r);
1181
+ l.push(p.choice), u = p.nextIndex;
1122
1182
  } else if (h.line.startsWith("IF ")) {
1123
- const p = Lt(e, l);
1124
- p.next && g.push({
1183
+ const p = Lt(n, u);
1184
+ p.next && m.push({
1125
1185
  condition: p.condition,
1126
1186
  next: p.next
1127
- }), d.push(...p.effects), l = p.nextIndex;
1187
+ }), d.push(...p.effects), u = p.nextIndex;
1128
1188
  } else if (h.line.startsWith("GOTO ")) {
1129
1189
  const p = h.line.substring(5).trim();
1130
1190
  if (p.startsWith("location ")) {
1131
1191
  const b = p.substring(9).trim();
1132
1192
  d.push({ type: "goToLocation", locationId: b }), d.push({ type: "endDialogue" });
1133
1193
  } else
1134
- m = p;
1135
- l++;
1194
+ f = p;
1195
+ u++;
1136
1196
  } else
1137
- d.push(E(h.line)), l++;
1197
+ d.push(E(h.line)), u++;
1138
1198
  }
1139
- const f = {
1199
+ const g = {
1140
1200
  id: r,
1141
1201
  speaker: a,
1142
1202
  text: s,
1143
1203
  voice: i,
1144
1204
  portrait: o,
1145
1205
  conditions: c.length > 0 ? c : void 0,
1146
- choices: u,
1206
+ choices: l,
1147
1207
  effects: d.length > 0 ? d : void 0,
1148
- next: m
1208
+ next: f
1149
1209
  };
1150
- return g.length > 0 && (f.conditionalNext = g), { node: f, nextIndex: l };
1210
+ return m.length > 0 && (g.conditionalNext = m), { node: g, nextIndex: u };
1151
1211
  }
1152
- function Rt(e, t) {
1153
- const n = Nt(e);
1212
+ function Rt(n, t) {
1213
+ const e = wt(n);
1154
1214
  let r;
1155
1215
  const a = [], s = [];
1156
1216
  let i = "", o = 0;
1157
- for (; o < n.length; ) {
1158
- const c = n[o];
1217
+ for (; o < e.length; ) {
1218
+ const c = e[o];
1159
1219
  if (c.line.startsWith("TRIGGER "))
1160
1220
  r = c.line.substring(8).trim(), o++;
1161
1221
  else if (c.line.startsWith("REQUIRE ")) {
1162
- const u = c.line.substring(8).trim();
1163
- a.push(T(u)), o++;
1222
+ const l = c.line.substring(8).trim();
1223
+ a.push(N(l)), o++;
1164
1224
  } else if (c.line.startsWith("NODE ")) {
1165
- const u = kt(n, o);
1166
- s.push(u.node), i || (i = u.node.id), o = u.nextIndex;
1225
+ const l = xt(e, o);
1226
+ s.push(l.node), i || (i = l.node.id), o = l.nextIndex;
1167
1227
  } else
1168
1228
  throw new Error(`Unexpected token at line ${c.lineNumber}: ${c.line}`);
1169
1229
  }
@@ -1175,18 +1235,83 @@ function Rt(e, t) {
1175
1235
  nodes: s
1176
1236
  };
1177
1237
  }
1238
+ function Dt(n, t) {
1239
+ const e = n;
1240
+ window.doodle = {
1241
+ // Flag manipulation
1242
+ setFlag(r) {
1243
+ e.state.flags[r] = !0, t(), console.log(`🐾 Flag set: ${r}`);
1244
+ },
1245
+ clearFlag(r) {
1246
+ delete e.state.flags[r], t(), console.log(`🐾 Flag cleared: ${r}`);
1247
+ },
1248
+ // Variable manipulation
1249
+ setVariable(r, a) {
1250
+ e.state.variables[r] = a, t(), console.log(`🐾 Variable set: ${r} = ${a}`);
1251
+ },
1252
+ getVariable(r) {
1253
+ const a = e.state.variables[r];
1254
+ return console.log(`🐾 Variable: ${r} = ${a}`), a;
1255
+ },
1256
+ // Location control
1257
+ teleport(r) {
1258
+ n.travelTo(r), t(), console.log(`🐾 Teleported to: ${r}`);
1259
+ },
1260
+ // Dialogue control
1261
+ triggerDialogue(r) {
1262
+ const a = e.registry.dialogues[r];
1263
+ if (!a) {
1264
+ console.error(`🐾 Dialogue not found: ${r}`);
1265
+ return;
1266
+ }
1267
+ const s = a.nodes.find((i) => i.id === a.startNode);
1268
+ if (!s) {
1269
+ console.error(`🐾 Start node not found for dialogue: ${r}`);
1270
+ return;
1271
+ }
1272
+ e.state.dialogueState = {
1273
+ dialogueId: a.id,
1274
+ nodeId: s.id
1275
+ }, t(), console.log(`🐾 Triggered dialogue: ${r}`);
1276
+ },
1277
+ // Quest control
1278
+ setQuestStage(r, a) {
1279
+ e.state.questProgress[r] = a, t(), console.log(`🐾 Quest stage set: ${r} -> ${a}`);
1280
+ },
1281
+ // Inventory control
1282
+ addItem(r) {
1283
+ e.state.inventory.includes(r) ? console.log(`🐾 Item already in inventory: ${r}`) : (e.state.inventory.push(r), e.state.itemLocations[r] = "inventory", t(), console.log(`🐾 Item added: ${r}`));
1284
+ },
1285
+ removeItem(r) {
1286
+ const a = e.state.inventory.indexOf(r);
1287
+ a !== -1 ? (e.state.inventory.splice(a, 1), delete e.state.itemLocations[r], t(), console.log(`🐾 Item removed: ${r}`)) : console.log(`🐾 Item not in inventory: ${r}`);
1288
+ },
1289
+ // Inspection
1290
+ inspect() {
1291
+ const r = n.getSnapshot();
1292
+ console.log("🐾 DOODLE ENGINE INSPECTOR 🐾"), console.log(""), console.log("Current Location:", r.location.name), console.log("Current Time:", `Day ${r.time.day}, Hour ${r.time.hour}`), console.log("Flags:", Object.keys(e.state.flags)), console.log("Variables:", e.state.variables), console.log("Inventory:", r.inventory.map((a) => a.name)), console.log("Quest Progress:", e.state.questProgress), console.log(""), console.log("Available commands:"), console.log(" doodle.setFlag(flag)"), console.log(" doodle.clearFlag(flag)"), console.log(" doodle.setVariable(variable, value)"), console.log(" doodle.getVariable(variable)"), console.log(" doodle.teleport(locationId)"), console.log(" doodle.triggerDialogue(dialogueId)"), console.log(" doodle.setQuestStage(questId, stageId)"), console.log(" doodle.addItem(itemId)"), console.log(" doodle.removeItem(itemId)"), console.log(" doodle.inspectState()"), console.log(" doodle.inspectRegistry()");
1293
+ },
1294
+ inspectState() {
1295
+ return console.log("🐾 GAME STATE:", e.state), e.state;
1296
+ },
1297
+ inspectRegistry() {
1298
+ return console.log("🐾 CONTENT REGISTRY:", e.registry), e.registry;
1299
+ }
1300
+ }, console.log("🐾 Doodle Engine dev tools enabled! Type `doodle.inspect()` to see available commands.");
1301
+ }
1178
1302
  const Pt = "0.0.1";
1179
1303
  export {
1180
1304
  Vt as Engine,
1181
1305
  Pt as VERSION,
1182
1306
  J as applyEffect,
1183
1307
  y as applyEffects,
1184
- gt as buildSnapshot,
1185
- Ot as createResolver,
1186
- x as evaluateCondition,
1187
- A as evaluateConditions,
1188
- T as parseCondition,
1308
+ mt as buildSnapshot,
1309
+ kt as createResolver,
1310
+ Dt as enableDevTools,
1311
+ O as evaluateCondition,
1312
+ I as evaluateConditions,
1313
+ N as parseCondition,
1189
1314
  Rt as parseDialogue,
1190
1315
  E as parseEffect,
1191
- w as resolveText
1316
+ A as resolveText
1192
1317
  };