@doodle-engine/core 0.0.6 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @doodle-engine/core
2
2
 
3
+ ## 0.0.8
4
+
5
+ ### Patch Changes
6
+
7
+ - 599ce7c: Dev tooling and DSL validation
8
+
9
+ ## 0.0.7
10
+
11
+ ### Patch Changes
12
+
13
+ - b7ac02f: Fix Github release tagging
14
+
3
15
  ## 0.0.6
4
16
 
5
17
  ### Patch Changes
package/dist/core.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var O=Object.defineProperty;var V=(e,t,n)=>t in e?O(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var T=(e,t,n)=>V(e,typeof t!="symbol"?t+"":t,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function N(e,t){switch(e.type){case"hasFlag":return R(e.flag,t);case"notFlag":return P(e.flag,t);case"hasItem":return D(e.itemId,t);case"variableEquals":return q(e.variable,e.value,t);case"variableGreaterThan":return W(e.variable,e.value,t);case"variableLessThan":return F(e.variable,e.value,t);case"atLocation":return M(e.locationId,t);case"questAtStage":return G(e.questId,e.stageId,t);case"characterAt":return $(e.characterId,e.locationId,t);case"characterInParty":return H(e.characterId,t);case"relationshipAbove":return U(e.characterId,e.value,t);case"relationshipBelow":return j(e.characterId,e.value,t);case"timeIs":return J(e.startHour,e.endHour,t);case"itemAt":return Q(e.itemId,e.locationId,t);default:return!1}}function E(e,t){return e.every(n=>N(n,t))}function R(e,t){return t.flags[e]===!0}function P(e,t){return t.flags[e]!==!0}function D(e,t){return t.inventory.includes(e)}function q(e,t,n){return n.variables[e]===t}function W(e,t,n){const r=n.variables[e];return typeof r=="number"&&r>t}function F(e,t,n){const r=n.variables[e];return typeof r=="number"&&r<t}function M(e,t){return t.currentLocation===e}function G(e,t,n){return n.questProgress[e]===t}function $(e,t,n){const r=n.characterState[e];return(r==null?void 0:r.location)===t}function H(e,t){const n=t.characterState[e];return(n==null?void 0:n.inParty)===!0}function U(e,t,n){const r=n.characterState[e];return r!==void 0&&r.relationship>t}function j(e,t,n){const r=n.characterState[e];return r!==void 0&&r.relationship<t}function J(e,t,n){const r=n.currentTime.hour;return e<t?r>=e&&r<t:r>=e||r<t}function Q(e,t,n){return n.itemLocations[e]===t}function C(e,t){switch(e.type){case"setFlag":return B(e.flag,t);case"clearFlag":return _(e.flag,t);case"setVariable":return z(e.variable,e.value,t);case"addVariable":return Y(e.variable,e.value,t);case"addItem":return K(e.itemId,t);case"removeItem":return X(e.itemId,t);case"moveItem":return Z(e.itemId,e.locationId,t);case"goToLocation":return tt(e.locationId,t);case"advanceTime":return et(e.hours,t);case"setQuestStage":return nt(e.questId,e.stageId,t);case"addJournalEntry":return rt(e.entryId,t);case"startDialogue":return at(e.dialogueId,t);case"endDialogue":return it(t);case"setCharacterLocation":return st(e.characterId,e.locationId,t);case"addToParty":return ot(e.characterId,t);case"removeFromParty":return ct(e.characterId,t);case"setRelationship":return ut(e.characterId,e.value,t);case"addRelationship":return lt(e.characterId,e.value,t);case"setCharacterStat":return dt(e.characterId,e.stat,e.value,t);case"addCharacterStat":return ht(e.characterId,e.stat,e.value,t);case"setMapEnabled":return pt(e.enabled,t);case"playMusic":return t;case"playSound":return mt(e.sound,t);case"notify":return ft(e.message,t);case"playVideo":return gt(e.file,t);default:return t}}function y(e,t){return e.reduce((n,r)=>C(r,n),t)}function B(e,t){return{...t,flags:{...t.flags,[e]:!0}}}function _(e,t){return{...t,flags:{...t.flags,[e]:!1}}}function z(e,t,n){return{...n,variables:{...n.variables,[e]:t}}}function Y(e,t,n){const r=n.variables[e],a=typeof r=="number"?r+t:t;return{...n,variables:{...n.variables,[e]:a}}}function K(e,t){return t.inventory.includes(e)?t:{...t,inventory:[...t.inventory,e],itemLocations:{...t.itemLocations,[e]:"inventory"}}}function X(e,t){return{...t,inventory:t.inventory.filter(n=>n!==e)}}function Z(e,t,n){return{...n,inventory:n.inventory.filter(r=>r!==e),itemLocations:{...n.itemLocations,[e]:t}}}function tt(e,t){return{...t,currentLocation:e}}function et(e,t){const n=t.currentTime.hour+e,r=Math.floor(n/24),a=n%24;return{...t,currentTime:{day:t.currentTime.day+r,hour:a}}}function nt(e,t,n){return{...n,questProgress:{...n.questProgress,[e]:t}}}function rt(e,t){return t.unlockedJournalEntries.includes(e)?t:{...t,unlockedJournalEntries:[...t.unlockedJournalEntries,e]}}function at(e,t){return{...t,dialogueState:{dialogueId:e,nodeId:""}}}function it(e){return{...e,dialogueState:null}}function st(e,t,n){const r=n.characterState[e];return r?{...n,characterState:{...n.characterState,[e]:{...r,location:t}}}:n}function ot(e,t){const n=t.characterState[e];return n?{...t,characterState:{...t.characterState,[e]:{...n,inParty:!0}}}:t}function ct(e,t){const n=t.characterState[e];return n?{...t,characterState:{...t.characterState,[e]:{...n,inParty:!1}}}:t}function ut(e,t,n){const r=n.characterState[e];return r?{...n,characterState:{...n.characterState,[e]:{...r,relationship:t}}}:n}function lt(e,t,n){const r=n.characterState[e];return r?{...n,characterState:{...n.characterState,[e]:{...r,relationship:r.relationship+t}}}:n}function dt(e,t,n,r){const a=r.characterState[e];return a?{...r,characterState:{...r.characterState,[e]:{...a,stats:{...a.stats,[t]:n}}}}:r}function ht(e,t,n,r){const a=r.characterState[e];if(!a)return r;const s=a.stats[t],i=typeof s=="number"?s+n:n;return{...r,characterState:{...r.characterState,[e]:{...a,stats:{...a.stats,[t]:i}}}}}function pt(e,t){return{...t,mapEnabled:e}}function ft(e,t){return{...t,notifications:[...t.notifications,e]}}function mt(e,t){return{...t,pendingSounds:[...t.pendingSounds,e]}}function gt(e,t){return{...t,pendingVideo:e}}function A(e,t){if(!e.startsWith("@"))return e;const n=e.slice(1);return t[n]??e}function bt(e){return t=>A(t,e)}function L(e,t){const n=t.locales[e.currentLocale]??{},r=x=>A(x,n),a=yt(e.currentLocation,t,r),s=St(e,t,r),i=vt(e,t,r),{dialogue:o,choices:c}=It(e,t,r),u=Tt(e,t,r),d=Et(e,t,r),m=At(e,t,r),g=wt(e,t,r),l=e.mapEnabled?Nt(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),I=[...e.pendingSounds],k=e.pendingVideo;return{location:a,charactersHere:s,itemsHere:i,choices:c,dialogue:o,party:u,inventory:d,quests:m,journal:g,variables:{...e.variables},time:e.currentTime,map:l,music:h,ambient:p,notifications:b,pendingSounds:I,pendingVideo:k}}function yt(e,t,n){const r=t.locations[e];return r?{id:r.id,name:n(r.name),description:n(r.description),banner:r.banner}:{id:e,name:e,description:`Location not found: ${e}`,banner:""}}function St(e,t,n){const r=[];for(const[a,s]of Object.entries(e.characterState))if(s.location===e.currentLocation){const i=t.characters[a];i&&r.push({id:i.id,name:n(i.name),biography:n(i.biography),portrait:i.portrait,location:s.location,inParty:s.inParty,relationship:s.relationship,stats:s.stats})}return r}function vt(e,t,n){const r=[];for(const[a,s]of Object.entries(e.itemLocations))if(s===e.currentLocation){const i=t.items[a];i&&r.push({id:i.id,name:n(i.name),description:n(i.description),icon:i.icon,image:i.image,stats:i.stats})}return r}function It(e,t,n){var c,u;if(!e.dialogueState)return{dialogue:null,choices:[]};const r=t.dialogues[e.dialogueState.dialogueId];if(!r)return{dialogue:null,choices:[]};const a=r.nodes.find(d=>{var m;return d.id===((m=e.dialogueState)==null?void 0:m.nodeId)});if(!a)return{dialogue:null,choices:[]};const s=a.speaker?n(((c=t.characters[a.speaker])==null?void 0:c.name)??a.speaker):"Narrator",i={speaker:a.speaker,speakerName:s,text:n(a.text),portrait:a.portrait??((u=t.characters[a.speaker??""])==null?void 0:u.portrait),voice:a.voice},o=a.choices.filter(d=>!d.conditions||d.conditions.length===0?!0:E(d.conditions,e)).map(d=>({id:d.id,text:n(d.text)}));return{dialogue:i,choices:o}}function Tt(e,t,n){const r=[];for(const[a,s]of Object.entries(e.characterState))if(s.inParty){const i=t.characters[a];i&&r.push({id:i.id,name:n(i.name),biography:n(i.biography),portrait:i.portrait,location:s.location,inParty:s.inParty,relationship:s.relationship,stats:s.stats})}return r}function Et(e,t,n){return e.inventory.map(r=>{const a=t.items[r];return a?{id:a.id,name:n(a.name),description:n(a.description),icon:a.icon,image:a.image,stats:a.stats}:null}).filter(r=>r!==null)}function At(e,t,n){const r=[];for(const[a,s]of Object.entries(e.questProgress)){const i=t.quests[a];if(!i)continue;const o=i.stages.find(c=>c.id===s);o&&r.push({id:i.id,name:n(i.name),description:n(i.description),currentStage:o.id,currentStageDescription:n(o.description)})}return r}function wt(e,t,n){return e.unlockedJournalEntries.map(r=>{const a=t.journalEntries[r];return a?{id:a.id,title:n(a.title),text:n(a.text),category:a.category}:null}).filter(r=>r!==null)}function Nt(e,t,n){const r=Object.keys(t.maps);if(r.length===0)return null;const a=t.maps[r[0]];if(!a)return null;const s=a.locations.map(i=>{const o=t.locations[i.id];return{id:i.id,name:o?n(o.name):i.id,x:i.x,y:i.y,isCurrent:i.id===e.currentLocation}});return{id:a.id,name:n(a.name),image:a.image,scale:a.scale,locations:s}}class Ct{constructor(t,n){T(this,"registry");T(this,"state");this.registry=t,this.state=n}newGame(t){const n={};for(const[a,s]of Object.entries(this.registry.characters))n[a]={location:s.location,inParty:!1,relationship:0,stats:{...s.stats}};const r={};for(const[a,s]of Object.entries(this.registry.items))r[a]=s.location;return this.state={currentLocation:t.startLocation,currentTime:{...t.startTime},flags:{...t.startFlags},variables:{...t.startVariables},inventory:[...t.startInventory],questProgress:{},unlockedJournalEntries:[],playerNotes:[],dialogueState:null,characterState:n,itemLocations:r,mapEnabled:!0,notifications:[],pendingSounds:[],pendingVideo:null,currentLocale:"en"},this.checkTriggeredDialogues(),this.buildSnapshotAndClearTransients()}loadGame(t){return this.state={...t.state},this.buildSnapshotAndClearTransients()}saveGame(){return{version:"1.0",timestamp:new Date().toISOString(),state:{...this.state}}}selectChoice(t){if(!this.state.dialogueState)return this.buildSnapshotAndClearTransients();const n=this.registry.dialogues[this.state.dialogueState.dialogueId];if(!n)return this.buildSnapshotAndClearTransients();const r=n.nodes.find(i=>{var o;return i.id===((o=this.state.dialogueState)==null?void 0:o.nodeId)});if(!r)return this.buildSnapshotAndClearTransients();const a=r.choices.find(i=>i.id===t);if(!a)return this.buildSnapshotAndClearTransients();a.effects&&(this.state=y(a.effects,this.state));const s=n.nodes.find(i=>i.id===a.next);return s?(this.state={...this.state,dialogueState:{dialogueId:n.id,nodeId:s.id}},s.effects&&(this.state=y(s.effects,this.state))):this.state={...this.state,dialogueState:null},this.buildSnapshotAndClearTransients()}talkTo(t){const n=this.registry.characters[t];if(!n||!n.dialogue)return this.buildSnapshotAndClearTransients();const r=this.registry.dialogues[n.dialogue];if(!r)return this.buildSnapshotAndClearTransients();const a=r.nodes.find(s=>s.id===r.startNode);return a?(this.state={...this.state,dialogueState:{dialogueId:r.id,nodeId:a.id}},a.effects&&(this.state=y(a.effects,this.state)),this.buildSnapshotAndClearTransients()):this.buildSnapshotAndClearTransients()}takeItem(t){return this.state.itemLocations[t]!==this.state.currentLocation?this.buildSnapshotAndClearTransients():(this.state={...this.state,inventory:[...this.state.inventory,t],itemLocations:{...this.state.itemLocations,[t]:"inventory"}},this.buildSnapshotAndClearTransients())}travelTo(t){if(!this.state.mapEnabled)return this.buildSnapshotAndClearTransients();const n=Object.keys(this.registry.maps);if(n.length===0)return this.buildSnapshotAndClearTransients();const r=this.registry.maps[n[0]];if(!r)return this.buildSnapshotAndClearTransients();const a=r.locations.find(m=>m.id===this.state.currentLocation),s=r.locations.find(m=>m.id===t);if(!a||!s)return this.buildSnapshotAndClearTransients();const i=Math.sqrt(Math.pow(s.x-a.x,2)+Math.pow(s.y-a.y,2)),o=Math.round(i*r.scale),c=this.state.currentTime.hour+o,u=Math.floor(c/24),d=c%24;return this.state={...this.state,currentLocation:t,dialogueState:null,currentTime:{day:this.state.currentTime.day+u,hour:d}},this.checkTriggeredDialogues(),this.buildSnapshotAndClearTransients()}writeNote(t,n){const r={id:`note_${Date.now()}`,title:t,text:n};return this.state={...this.state,playerNotes:[...this.state.playerNotes,r]},this.buildSnapshotAndClearTransients()}deleteNote(t){return this.state={...this.state,playerNotes:this.state.playerNotes.filter(n=>n.id!==t)},this.buildSnapshotAndClearTransients()}setLocale(t){return this.state={...this.state,currentLocale:t},this.buildSnapshotAndClearTransients()}getSnapshot(){return this.buildSnapshotAndClearTransients()}buildSnapshotAndClearTransients(){const t=L(this.state,this.registry);return this.state={...this.state,notifications:[],pendingSounds:[],pendingVideo:null},t}checkTriggeredDialogues(){for(const t of Object.values(this.registry.dialogues)){if(t.triggerLocation!==this.state.currentLocation||t.conditions&&!E(t.conditions,this.state))continue;const n=t.nodes.find(r=>r.id===t.startNode);if(n){this.state={...this.state,dialogueState:{dialogueId:t.id,nodeId:n.id}},n.effects&&(this.state=y(n.effects,this.state));break}}}}function Lt(e){return e.split(`
2
- `).map((t,n)=>({original:t,lineNumber:n+1})).map(({original:t,lineNumber:n})=>{let r=t;const a=t.indexOf("#");if(a===-1)r=t;else{const o=t.match(/"[^"]*"/);if(o){const c=t.indexOf(o[0]),u=c+o[0].length;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)}else r=t.substring(0,a)}const s=r.length-r.trimStart().length;return{line:r.trim(),lineNumber:n,indent:s}}).filter(t=>t.line.length>0)}function w(e){const t=e.trim();return t.startsWith("@")?t:t.startsWith('"')&&t.endsWith('"')?t.substring(1,t.length-1):t}function S(e){const t=e.trim().split(/\s+/),n=t[0];switch(n){case"hasFlag":return{type:"hasFlag",flag:t[1]};case"notFlag":return{type:"notFlag",flag:t[1]};case"hasItem":return{type:"hasItem",itemId:t[1]};case"variableEquals":return{type:"variableEquals",variable:t[1],value:isNaN(Number(t[2]))?t[2]:Number(t[2])};case"variableGreaterThan":return{type:"variableGreaterThan",variable:t[1],value:Number(t[2])};case"variableLessThan":return{type:"variableLessThan",variable:t[1],value:Number(t[2])};case"atLocation":return{type:"atLocation",locationId:t[1]};case"questAtStage":return{type:"questAtStage",questId:t[1],stageId:t[2]};case"characterAt":return{type:"characterAt",characterId:t[1],locationId:t[2]};case"characterInParty":return{type:"characterInParty",characterId:t[1]};case"relationshipAbove":return{type:"relationshipAbove",characterId:t[1],value:Number(t[2])};case"relationshipBelow":return{type:"relationshipBelow",characterId:t[1],value:Number(t[2])};case"timeIs":return{type:"timeIs",startHour:Number(t[1]),endHour:Number(t[2])};case"itemAt":return{type:"itemAt",itemId:t[1],locationId:t[2]};default:throw new Error(`Unknown condition type: ${n}`)}}function v(e){const t=e.trim();if(t.startsWith("NOTIFY "))return{type:"notify",message:w(t.substring(7))};if(t.startsWith("MUSIC "))return{type:"playMusic",track:t.substring(6).trim()};if(t.startsWith("SOUND "))return{type:"playSound",sound:t.substring(6).trim()};if(t.startsWith("VIDEO "))return{type:"playVideo",file:t.substring(6).trim()};const n=t.split(/\s+/),r=n[0];switch(r){case"SET":if(n[1]==="flag")return{type:"setFlag",flag:n[2]};if(n[1]==="variable")return{type:"setVariable",variable:n[2],value:isNaN(Number(n[3]))?n[3]:Number(n[3])};if(n[1]==="questStage")return{type:"setQuestStage",questId:n[2],stageId:n[3]};if(n[1]==="characterLocation")return{type:"setCharacterLocation",characterId:n[2],locationId:n[3]};if(n[1]==="relationship")return{type:"setRelationship",characterId:n[2],value:Number(n[3])};if(n[1]==="characterStat")return{type:"setCharacterStat",characterId:n[2],stat:n[3],value:isNaN(Number(n[4]))?n[4]:Number(n[4])};if(n[1]==="mapEnabled")return{type:"setMapEnabled",enabled:n[2]==="true"};throw new Error(`Unknown SET effect: ${n[1]}`);case"CLEAR":if(n[1]==="flag")return{type:"clearFlag",flag:n[2]};throw new Error(`Unknown CLEAR effect: ${n[1]}`);case"ADD":if(n[1]==="variable")return{type:"addVariable",variable:n[2],value:Number(n[3])};if(n[1]==="item")return{type:"addItem",itemId:n[2]};if(n[1]==="journalEntry")return{type:"addJournalEntry",entryId:n[2]};if(n[1]==="toParty")return{type:"addToParty",characterId:n[2]};if(n[1]==="relationship")return{type:"addRelationship",characterId:n[2],value:Number(n[3])};if(n[1]==="characterStat")return{type:"addCharacterStat",characterId:n[2],stat:n[3],value:Number(n[4])};throw new Error(`Unknown ADD effect: ${n[1]}`);case"REMOVE":if(n[1]==="item")return{type:"removeItem",itemId:n[2]};if(n[1]==="fromParty")return{type:"removeFromParty",characterId:n[2]};throw new Error(`Unknown REMOVE effect: ${n[1]}`);case"MOVE":if(n[1]==="item")return{type:"moveItem",itemId:n[2],locationId:n[3]};throw new Error(`Unknown MOVE effect: ${n[1]}`);case"GOTO":if(n[1]==="location")return{type:"goToLocation",locationId:n[2]};throw new Error("GOTO should not be parsed as an effect");case"ADVANCE":if(n[1]==="time")return{type:"advanceTime",hours:Number(n[2])};throw new Error(`Unknown ADVANCE effect: ${n[1]}`);case"START":if(n[1]==="dialogue")return{type:"startDialogue",dialogueId:n[2]};throw new Error(`Unknown START effect: ${n[1]}`);case"END":if(n[1]==="dialogue")return{type:"endDialogue"};throw new Error("END should not be parsed as an effect");default:throw new Error(`Unknown effect keyword: ${r}`)}}function kt(e,t,n){const r=e[t],a=w(r.line.substring(7)),s=[],i=[];let o="",c=t+1;const u=r.indent;for(;c<e.length;){const l=e[c];if(l.line==="END"&&l.indent===u){c++;break}if(l.line.startsWith("REQUIRE ")){const f=l.line.substring(8).trim();s.push(S(f)),c++}else if(l.line.startsWith("GOTO ")){const f=l.line.substring(5).trim();if(f.startsWith("location ")){const h=f.substring(9).trim();i.push({type:"goToLocation",locationId:h}),i.push({type:"endDialogue"}),o=""}else o=f;c++}else l.line.includes(":")||i.push(v(l.line)),c++}const d=a.replace(/[@"]/g,"").replace(/[^a-z0-9]/gi,"_");return{choice:{id:`${n}_choice_${d.toLowerCase().substring(0,30)}`,text:a,conditions:s.length>0?s:void 0,effects:i.length>0?i:void 0,next:o||""},nextIndex:c}}function xt(e,t){const n=e[t],r=n.line.substring(3).trim(),a=S(r);let s;const i=[];let o=t+1;const c=n.indent;for(;o<e.length;){const u=e[o];if(u.line==="END"&&u.indent===c){o++;break}u.line.startsWith("GOTO ")?(s=u.line.substring(5).trim(),o++):(i.push(v(u.line)),o++)}return{condition:a,next:s,effects:i,nextIndex:o}}function Ot(e,t){const r=e[t].line.substring(5).trim();let a=null,s="",i,o;const c=[],u=[],d=[];let m;const g=[];let l=t+1;for(;l<e.length;){const h=e[l];if(h.line.startsWith("NODE "))break;if(h.line.includes(":")&&!h.line.startsWith("VOICE")){const p=h.line.indexOf(":"),b=h.line.substring(0,p).trim(),I=h.line.substring(p+1).trim();b==="NARRATOR"?a=null:a=b.toLowerCase(),s=w(I),l++}else if(h.line.startsWith("VOICE "))i=h.line.substring(6).trim(),l++;else if(h.line.startsWith("PORTRAIT "))o=h.line.substring(9).trim(),l++;else if(h.line.startsWith("CHOICE ")){const p=kt(e,l,r);u.push(p.choice),l=p.nextIndex}else if(h.line.startsWith("IF ")){const p=xt(e,l);p.next&&g.push({condition:p.condition,next:p.next}),d.push(...p.effects),l=p.nextIndex}else if(h.line.startsWith("GOTO ")){const p=h.line.substring(5).trim();if(p.startsWith("location ")){const b=p.substring(9).trim();d.push({type:"goToLocation",locationId:b}),d.push({type:"endDialogue"})}else m=p;l++}else d.push(v(h.line)),l++}const f={id:r,speaker:a,text:s,voice:i,portrait:o,conditions:c.length>0?c:void 0,choices:u,effects:d.length>0?d:void 0,next:m};return g.length>0&&(f.conditionalNext=g),{node:f,nextIndex:l}}function Vt(e,t){const n=Lt(e);let r;const a=[],s=[];let i="",o=0;for(;o<n.length;){const c=n[o];if(c.line.startsWith("TRIGGER "))r=c.line.substring(8).trim(),o++;else if(c.line.startsWith("REQUIRE ")){const u=c.line.substring(8).trim();a.push(S(u)),o++}else if(c.line.startsWith("NODE ")){const u=Ot(n,o);s.push(u.node),i||(i=u.node.id),o=u.nextIndex}else throw new Error(`Unexpected token at line ${c.lineNumber}: ${c.line}`)}return{id:t,triggerLocation:r,conditions:a.length>0?a:void 0,startNode:i,nodes:s}}const Rt="0.0.1";exports.Engine=Ct;exports.VERSION=Rt;exports.applyEffect=C;exports.applyEffects=y;exports.buildSnapshot=L;exports.createResolver=bt;exports.evaluateCondition=N;exports.evaluateConditions=E;exports.parseCondition=S;exports.parseDialogue=Vt;exports.parseEffect=v;exports.resolveText=A;
1
+ "use strict";var V=Object.defineProperty;var k=(n,t,e)=>t in n?V(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var E=(n,t,e)=>k(n,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function w(n,t){switch(n.type){case"hasFlag":return R(n.flag,t);case"notFlag":return D(n.flag,t);case"hasItem":return P(n.itemId,t);case"variableEquals":return $(n.variable,n.value,t);case"variableGreaterThan":return q(n.variable,n.value,t);case"variableLessThan":return F(n.variable,n.value,t);case"atLocation":return W(n.locationId,t);case"questAtStage":return M(n.questId,n.stageId,t);case"characterAt":return G(n.characterId,n.locationId,t);case"characterInParty":return H(n.characterId,t);case"relationshipAbove":return j(n.characterId,n.value,t);case"relationshipBelow":return Q(n.characterId,n.value,t);case"timeIs":return J(n.startHour,n.endHour,t);case"itemAt":return U(n.itemId,n.locationId,t);default:return!1}}function S(n,t){return n.every(e=>w(e,t))}function R(n,t){return t.flags[n]===!0}function D(n,t){return t.flags[n]!==!0}function P(n,t){return t.inventory.includes(n)}function $(n,t,e){return e.variables[n]===t}function q(n,t,e){const r=e.variables[n];return typeof r=="number"&&r>t}function F(n,t,e){const r=e.variables[n];return typeof r=="number"&&r<t}function W(n,t){return t.currentLocation===n}function M(n,t,e){return e.questProgress[n]===t}function G(n,t,e){const r=e.characterState[n];return(r==null?void 0:r.location)===t}function H(n,t){const e=t.characterState[n];return(e==null?void 0:e.inParty)===!0}function j(n,t,e){const r=e.characterState[n];return r!==void 0&&r.relationship>t}function Q(n,t,e){const r=e.characterState[n];return r!==void 0&&r.relationship<t}function J(n,t,e){const r=e.currentTime.hour;return n<t?r>=n&&r<t:r>=n||r<t}function U(n,t,e){return e.itemLocations[n]===t}function C(n,t){switch(n.type){case"setFlag":return B(n.flag,t);case"clearFlag":return _(n.flag,t);case"setVariable":return z(n.variable,n.value,t);case"addVariable":return Y(n.variable,n.value,t);case"addItem":return K(n.itemId,t);case"removeItem":return X(n.itemId,t);case"moveItem":return Z(n.itemId,n.locationId,t);case"goToLocation":return tt(n.locationId,t);case"advanceTime":return et(n.hours,t);case"setQuestStage":return nt(n.questId,n.stageId,t);case"addJournalEntry":return rt(n.entryId,t);case"startDialogue":return at(n.dialogueId,t);case"endDialogue":return it(t);case"setCharacterLocation":return ot(n.characterId,n.locationId,t);case"addToParty":return st(n.characterId,t);case"removeFromParty":return lt(n.characterId,t);case"setRelationship":return ct(n.characterId,n.value,t);case"addRelationship":return ut(n.characterId,n.value,t);case"setCharacterStat":return dt(n.characterId,n.stat,n.value,t);case"addCharacterStat":return ht(n.characterId,n.stat,n.value,t);case"setMapEnabled":return pt(n.enabled,t);case"playMusic":return t;case"playSound":return ft(n.sound,t);case"notify":return gt(n.message,t);case"playVideo":return mt(n.file,t);default:return t}}function y(n,t){return n.reduce((e,r)=>C(r,e),t)}function B(n,t){return{...t,flags:{...t.flags,[n]:!0}}}function _(n,t){return{...t,flags:{...t.flags,[n]:!1}}}function z(n,t,e){return{...e,variables:{...e.variables,[n]:t}}}function Y(n,t,e){const r=e.variables[n],a=typeof r=="number"?r+t:t;return{...e,variables:{...e.variables,[n]:a}}}function K(n,t){return t.inventory.includes(n)?t:{...t,inventory:[...t.inventory,n],itemLocations:{...t.itemLocations,[n]:"inventory"}}}function X(n,t){return{...t,inventory:t.inventory.filter(e=>e!==n)}}function Z(n,t,e){return{...e,inventory:e.inventory.filter(r=>r!==n),itemLocations:{...e.itemLocations,[n]:t}}}function tt(n,t){return{...t,currentLocation:n}}function et(n,t){const e=t.currentTime.hour+n,r=Math.floor(e/24),a=e%24;return{...t,currentTime:{day:t.currentTime.day+r,hour:a}}}function nt(n,t,e){return{...e,questProgress:{...e.questProgress,[n]:t}}}function rt(n,t){return t.unlockedJournalEntries.includes(n)?t:{...t,unlockedJournalEntries:[...t.unlockedJournalEntries,n]}}function at(n,t){return{...t,dialogueState:{dialogueId:n,nodeId:""}}}function it(n){return{...n,dialogueState:null}}function ot(n,t,e){const r=e.characterState[n];return r?{...e,characterState:{...e.characterState,[n]:{...r,location:t}}}:e}function st(n,t){const e=t.characterState[n];return e?{...t,characterState:{...t.characterState,[n]:{...e,inParty:!0}}}:t}function lt(n,t){const e=t.characterState[n];return e?{...t,characterState:{...t.characterState,[n]:{...e,inParty:!1}}}:t}function ct(n,t,e){const r=e.characterState[n];return r?{...e,characterState:{...e.characterState,[n]:{...r,relationship:t}}}:e}function ut(n,t,e){const r=e.characterState[n];return r?{...e,characterState:{...e.characterState,[n]:{...r,relationship:r.relationship+t}}}:e}function dt(n,t,e,r){const a=r.characterState[n];return a?{...r,characterState:{...r.characterState,[n]:{...a,stats:{...a.stats,[t]:e}}}}:r}function ht(n,t,e,r){const a=r.characterState[n];if(!a)return r;const o=a.stats[t],i=typeof o=="number"?o+e:e;return{...r,characterState:{...r.characterState,[n]:{...a,stats:{...a.stats,[t]:i}}}}}function pt(n,t){return{...t,mapEnabled:n}}function gt(n,t){return{...t,notifications:[...t.notifications,n]}}function ft(n,t){return{...t,pendingSounds:[...t.pendingSounds,n]}}function mt(n,t){return{...t,pendingVideo:n}}function N(n,t){if(!n.startsWith("@"))return n;const e=n.slice(1);return t[e]??n}function bt(n){return t=>N(t,n)}function L(n,t){const e=t.locales[n.currentLocale]??{},r=O=>N(O,e),a=yt(n.currentLocation,t,r),o=St(n,t,r),i=vt(n,t,r),{dialogue:s,choices:l}=It(n,t,r),c=Tt(n,t,r),d=Et(n,t,r),f=Nt(n,t,r),m=At(n,t,r),u=n.mapEnabled?wt(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),T=[...n.pendingSounds],x=n.pendingVideo;return{location:a,charactersHere:o,itemsHere:i,choices:l,dialogue:s,party:c,inventory:d,quests:f,journal:m,variables:{...n.variables},time:n.currentTime,map:u,music:h,ambient:p,notifications:b,pendingSounds:T,pendingVideo:x}}function yt(n,t,e){const r=t.locations[n];return r?{id:r.id,name:e(r.name),description:e(r.description),banner:r.banner}:{id:n,name:n,description:`Location not found: ${n}`,banner:""}}function St(n,t,e){const r=[];for(const[a,o]of Object.entries(n.characterState))if(o.location===n.currentLocation){const i=t.characters[a];i&&r.push({id:i.id,name:e(i.name),biography:e(i.biography),portrait:i.portrait,location:o.location,inParty:o.inParty,relationship:o.relationship,stats:o.stats})}return r}function vt(n,t,e){const r=[];for(const[a,o]of Object.entries(n.itemLocations))if(o===n.currentLocation){const i=t.items[a];i&&r.push({id:i.id,name:e(i.name),description:e(i.description),icon:i.icon,image:i.image,stats:i.stats})}return r}function It(n,t,e){var l,c;if(!n.dialogueState)return{dialogue:null,choices:[]};const r=t.dialogues[n.dialogueState.dialogueId];if(!r)return{dialogue:null,choices:[]};const a=r.nodes.find(d=>{var f;return d.id===((f=n.dialogueState)==null?void 0:f.nodeId)});if(!a)return{dialogue:null,choices:[]};const o=a.speaker?e(((l=t.characters[a.speaker])==null?void 0:l.name)??a.speaker):"Narrator",i={speaker:a.speaker,speakerName:o,text:e(a.text),portrait:a.portrait??((c=t.characters[a.speaker??""])==null?void 0:c.portrait),voice:a.voice},s=a.choices.filter(d=>!d.conditions||d.conditions.length===0?!0:S(d.conditions,n)).map(d=>({id:d.id,text:e(d.text)}));return{dialogue:i,choices:s}}function Tt(n,t,e){const r=[];for(const[a,o]of Object.entries(n.characterState))if(o.inParty){const i=t.characters[a];i&&r.push({id:i.id,name:e(i.name),biography:e(i.biography),portrait:i.portrait,location:o.location,inParty:o.inParty,relationship:o.relationship,stats:o.stats})}return r}function Et(n,t,e){return n.inventory.map(r=>{const a=t.items[r];return a?{id:a.id,name:e(a.name),description:e(a.description),icon:a.icon,image:a.image,stats:a.stats}:null}).filter(r=>r!==null)}function Nt(n,t,e){const r=[];for(const[a,o]of Object.entries(n.questProgress)){const i=t.quests[a];if(!i)continue;const s=i.stages.find(l=>l.id===o);s&&r.push({id:i.id,name:e(i.name),description:e(i.description),currentStage:s.id,currentStageDescription:e(s.description)})}return r}function At(n,t,e){return n.unlockedJournalEntries.map(r=>{const a=t.journalEntries[r];return a?{id:a.id,title:e(a.title),text:e(a.text),category:a.category}:null}).filter(r=>r!==null)}function wt(n,t,e){const r=Object.keys(t.maps);if(r.length===0)return null;const a=t.maps[r[0]];if(!a)return null;const o=a.locations.map(i=>{const s=t.locations[i.id];return{id:i.id,name:s?e(s.name):i.id,x:i.x,y:i.y,isCurrent:i.id===n.currentLocation}});return{id:a.id,name:e(a.name),image:a.image,scale:a.scale,locations:o}}class Ct{constructor(t,e){E(this,"registry");E(this,"state");this.registry=t,this.state=e}newGame(t){const e={};for(const[a,o]of Object.entries(this.registry.characters))e[a]={location:o.location,inParty:!1,relationship:0,stats:{...o.stats}};const r={};for(const[a,o]of Object.entries(this.registry.items))r[a]=o.location;return this.state={currentLocation:t.startLocation,currentTime:{...t.startTime},flags:{...t.startFlags},variables:{...t.startVariables},inventory:[...t.startInventory],questProgress:{},unlockedJournalEntries:[],playerNotes:[],dialogueState:null,characterState:e,itemLocations:r,mapEnabled:!0,notifications:[],pendingSounds:[],pendingVideo:null,currentLocale:"en"},this.checkTriggeredDialogues(),this.buildSnapshotAndClearTransients()}loadGame(t){return this.state={...t.state},this.buildSnapshotAndClearTransients()}saveGame(){return{version:"1.0",timestamp:new Date().toISOString(),state:{...this.state}}}selectChoice(t){if(!this.state.dialogueState)return this.buildSnapshotAndClearTransients();const e=this.registry.dialogues[this.state.dialogueState.dialogueId];if(!e)return this.buildSnapshotAndClearTransients();const r=e.nodes.find(i=>{var s;return i.id===((s=this.state.dialogueState)==null?void 0:s.nodeId)});if(!r)return this.buildSnapshotAndClearTransients();const a=r.choices.find(i=>i.id===t);if(!a)return this.buildSnapshotAndClearTransients();a.effects&&(this.state=y(a.effects,this.state));const o=e.nodes.find(i=>i.id===a.next);if(!o)return this.state={...this.state,dialogueState:null},this.buildSnapshotAndClearTransients();if(this.state={...this.state,dialogueState:{dialogueId:e.id,nodeId:o.id}},o.effects&&(this.state=y(o.effects,this.state)),o.choices.length===0){const i=this.resolveNextNode(o);i?this.state={...this.state,dialogueState:{dialogueId:e.id,nodeId:i}}:this.state={...this.state,dialogueState:null}}return this.buildSnapshotAndClearTransients()}talkTo(t){const e=this.registry.characters[t];if(!e||!e.dialogue)return this.buildSnapshotAndClearTransients();const r=this.registry.dialogues[e.dialogue];if(!r)return this.buildSnapshotAndClearTransients();const a=r.nodes.find(o=>o.id===r.startNode);if(!a)return this.buildSnapshotAndClearTransients();if(this.state={...this.state,dialogueState:{dialogueId:r.id,nodeId:a.id}},a.effects&&(this.state=y(a.effects,this.state)),a.choices.length===0){const o=this.resolveNextNode(a);o?this.state={...this.state,dialogueState:{dialogueId:r.id,nodeId:o}}:this.state={...this.state,dialogueState:null}}return this.buildSnapshotAndClearTransients()}takeItem(t){return this.state.itemLocations[t]!==this.state.currentLocation?this.buildSnapshotAndClearTransients():(this.state={...this.state,inventory:[...this.state.inventory,t],itemLocations:{...this.state.itemLocations,[t]:"inventory"}},this.buildSnapshotAndClearTransients())}travelTo(t){if(!this.state.mapEnabled)return this.buildSnapshotAndClearTransients();const e=Object.keys(this.registry.maps);if(e.length===0)return this.buildSnapshotAndClearTransients();const r=this.registry.maps[e[0]];if(!r)return this.buildSnapshotAndClearTransients();const a=r.locations.find(f=>f.id===this.state.currentLocation),o=r.locations.find(f=>f.id===t);if(!a||!o)return this.buildSnapshotAndClearTransients();const i=Math.sqrt(Math.pow(o.x-a.x,2)+Math.pow(o.y-a.y,2)),s=Math.round(i*r.scale),l=this.state.currentTime.hour+s,c=Math.floor(l/24),d=l%24;return this.state={...this.state,currentLocation:t,dialogueState:null,currentTime:{day:this.state.currentTime.day+c,hour:d}},this.checkTriggeredDialogues(),this.buildSnapshotAndClearTransients()}writeNote(t,e){const r={id:`note_${Date.now()}`,title:t,text:e};return this.state={...this.state,playerNotes:[...this.state.playerNotes,r]},this.buildSnapshotAndClearTransients()}deleteNote(t){return this.state={...this.state,playerNotes:this.state.playerNotes.filter(e=>e.id!==t)},this.buildSnapshotAndClearTransients()}setLocale(t){return this.state={...this.state,currentLocale:t},this.buildSnapshotAndClearTransients()}getSnapshot(){return this.buildSnapshotAndClearTransients()}buildSnapshotAndClearTransients(){const t=L(this.state,this.registry);return this.state={...this.state,notifications:[],pendingSounds:[],pendingVideo:null},t}resolveNextNode(t){if(t.conditionalNext&&t.conditionalNext.length>0){for(const e of t.conditionalNext)if(S([e.condition],this.state))return e.next}return t.next??null}checkTriggeredDialogues(){for(const t of Object.values(this.registry.dialogues)){if(t.triggerLocation!==this.state.currentLocation||t.conditions&&!S(t.conditions,this.state))continue;const e=t.nodes.find(r=>r.id===t.startNode);if(e){if(this.state={...this.state,dialogueState:{dialogueId:t.id,nodeId:e.id}},e.effects&&(this.state=y(e.effects,this.state)),e.choices.length===0){const r=this.resolveNextNode(e);r?this.state={...this.state,dialogueState:{dialogueId:t.id,nodeId:r}}:this.state={...this.state,dialogueState:null}}break}}}}function Lt(n){return n.split(`
2
+ `).map((t,e)=>({original:t,lineNumber:e+1})).map(({original:t,lineNumber:e})=>{let r=t;const a=t.indexOf("#");if(a===-1)r=t;else{const s=t.match(/"[^"]*"/);if(s){const l=t.indexOf(s[0]),c=l+s[0].length;a<l?r=t.substring(0,a):a>=l&&a<c?r=t.substring(0,c)+t.substring(c).split("#")[0]:r=t.substring(0,a)}else r=t.substring(0,a)}const o=r.length-r.trimStart().length;return{line:r.trim(),lineNumber:e,indent:o}}).filter(t=>t.line.length>0)}function A(n){const t=n.trim();return t.startsWith("@")?t:t.startsWith('"')&&t.endsWith('"')?t.substring(1,t.length-1):t}function v(n){const t=n.trim().split(/\s+/),e=t[0];switch(e){case"hasFlag":return{type:"hasFlag",flag:t[1]};case"notFlag":return{type:"notFlag",flag:t[1]};case"hasItem":return{type:"hasItem",itemId:t[1]};case"variableEquals":return{type:"variableEquals",variable:t[1],value:isNaN(Number(t[2]))?t[2]:Number(t[2])};case"variableGreaterThan":return{type:"variableGreaterThan",variable:t[1],value:Number(t[2])};case"variableLessThan":return{type:"variableLessThan",variable:t[1],value:Number(t[2])};case"atLocation":return{type:"atLocation",locationId:t[1]};case"questAtStage":return{type:"questAtStage",questId:t[1],stageId:t[2]};case"characterAt":return{type:"characterAt",characterId:t[1],locationId:t[2]};case"characterInParty":return{type:"characterInParty",characterId:t[1]};case"relationshipAbove":return{type:"relationshipAbove",characterId:t[1],value:Number(t[2])};case"relationshipBelow":return{type:"relationshipBelow",characterId:t[1],value:Number(t[2])};case"timeIs":return{type:"timeIs",startHour:Number(t[1]),endHour:Number(t[2])};case"itemAt":return{type:"itemAt",itemId:t[1],locationId:t[2]};default:throw new Error(`Unknown condition type: ${e}`)}}function I(n){const t=n.trim();if(t.startsWith("NOTIFY "))return{type:"notify",message:A(t.substring(7))};if(t.startsWith("MUSIC "))return{type:"playMusic",track:t.substring(6).trim()};if(t.startsWith("SOUND "))return{type:"playSound",sound:t.substring(6).trim()};if(t.startsWith("VIDEO "))return{type:"playVideo",file:t.substring(6).trim()};const e=t.split(/\s+/),r=e[0];switch(r){case"SET":if(e[1]==="flag")return{type:"setFlag",flag:e[2]};if(e[1]==="variable")return{type:"setVariable",variable:e[2],value:isNaN(Number(e[3]))?e[3]:Number(e[3])};if(e[1]==="questStage")return{type:"setQuestStage",questId:e[2],stageId:e[3]};if(e[1]==="characterLocation")return{type:"setCharacterLocation",characterId:e[2],locationId:e[3]};if(e[1]==="relationship")return{type:"setRelationship",characterId:e[2],value:Number(e[3])};if(e[1]==="characterStat")return{type:"setCharacterStat",characterId:e[2],stat:e[3],value:isNaN(Number(e[4]))?e[4]:Number(e[4])};if(e[1]==="mapEnabled")return{type:"setMapEnabled",enabled:e[2]==="true"};throw new Error(`Unknown SET effect: ${e[1]}`);case"CLEAR":if(e[1]==="flag")return{type:"clearFlag",flag:e[2]};throw new Error(`Unknown CLEAR effect: ${e[1]}`);case"ADD":if(e[1]==="variable")return{type:"addVariable",variable:e[2],value:Number(e[3])};if(e[1]==="item")return{type:"addItem",itemId:e[2]};if(e[1]==="journalEntry")return{type:"addJournalEntry",entryId:e[2]};if(e[1]==="toParty")return{type:"addToParty",characterId:e[2]};if(e[1]==="relationship")return{type:"addRelationship",characterId:e[2],value:Number(e[3])};if(e[1]==="characterStat")return{type:"addCharacterStat",characterId:e[2],stat:e[3],value:Number(e[4])};throw new Error(`Unknown ADD effect: ${e[1]}`);case"REMOVE":if(e[1]==="item")return{type:"removeItem",itemId:e[2]};if(e[1]==="fromParty")return{type:"removeFromParty",characterId:e[2]};throw new Error(`Unknown REMOVE effect: ${e[1]}`);case"MOVE":if(e[1]==="item")return{type:"moveItem",itemId:e[2],locationId:e[3]};throw new Error(`Unknown MOVE effect: ${e[1]}`);case"GOTO":if(e[1]==="location")return{type:"goToLocation",locationId:e[2]};throw new Error("GOTO should not be parsed as an effect");case"ADVANCE":if(e[1]==="time")return{type:"advanceTime",hours:Number(e[2])};throw new Error(`Unknown ADVANCE effect: ${e[1]}`);case"START":if(e[1]==="dialogue")return{type:"startDialogue",dialogueId:e[2]};throw new Error(`Unknown START effect: ${e[1]}`);case"END":if(e[1]==="dialogue")return{type:"endDialogue"};throw new Error("END should not be parsed as an effect");default:throw new Error(`Unknown effect keyword: ${r}`)}}function xt(n,t,e){const r=n[t],a=A(r.line.substring(7)),o=[],i=[];let s="",l=t+1;const c=r.indent;for(;l<n.length;){const u=n[l];if(u.line==="END"&&u.indent===c){l++;break}if(u.line.startsWith("REQUIRE ")){const g=u.line.substring(8).trim();o.push(v(g)),l++}else if(u.line.startsWith("GOTO ")){const g=u.line.substring(5).trim();if(g.startsWith("location ")){const h=g.substring(9).trim();i.push({type:"goToLocation",locationId:h}),i.push({type:"endDialogue"}),s=""}else s=g;l++}else u.line.includes(":")||i.push(I(u.line)),l++}const d=a.replace(/[@"]/g,"").replace(/[^a-z0-9]/gi,"_");return{choice:{id:`${e}_choice_${d.toLowerCase().substring(0,30)}`,text:a,conditions:o.length>0?o:void 0,effects:i.length>0?i:void 0,next:s||""},nextIndex:l}}function Ot(n,t){const e=n[t],r=e.line.substring(3).trim(),a=v(r);let o;const i=[];let s=t+1;const l=e.indent;for(;s<n.length;){const c=n[s];if(c.line==="END"&&c.indent===l){s++;break}c.line.startsWith("GOTO ")?(o=c.line.substring(5).trim(),s++):(i.push(I(c.line)),s++)}return{condition:a,next:o,effects:i,nextIndex:s}}function Vt(n,t){const r=n[t].line.substring(5).trim();let a=null,o="",i,s;const l=[],c=[],d=[];let f;const m=[];let u=t+1;for(;u<n.length;){const h=n[u];if(h.line.startsWith("NODE "))break;if(h.line.includes(":")&&!h.line.startsWith("VOICE")){const p=h.line.indexOf(":"),b=h.line.substring(0,p).trim(),T=h.line.substring(p+1).trim();b==="NARRATOR"?a=null:a=b.toLowerCase(),o=A(T),u++}else if(h.line.startsWith("VOICE "))i=h.line.substring(6).trim(),u++;else if(h.line.startsWith("PORTRAIT "))s=h.line.substring(9).trim(),u++;else if(h.line.startsWith("CHOICE ")){const p=xt(n,u,r);c.push(p.choice),u=p.nextIndex}else if(h.line.startsWith("IF ")){const p=Ot(n,u);p.next&&m.push({condition:p.condition,next:p.next}),d.push(...p.effects),u=p.nextIndex}else if(h.line.startsWith("GOTO ")){const p=h.line.substring(5).trim();if(p.startsWith("location ")){const b=p.substring(9).trim();d.push({type:"goToLocation",locationId:b}),d.push({type:"endDialogue"})}else f=p;u++}else d.push(I(h.line)),u++}const g={id:r,speaker:a,text:o,voice:i,portrait:s,conditions:l.length>0?l:void 0,choices:c,effects:d.length>0?d:void 0,next:f};return m.length>0&&(g.conditionalNext=m),{node:g,nextIndex:u}}function kt(n,t){const e=Lt(n);let r;const a=[],o=[];let i="",s=0;for(;s<e.length;){const l=e[s];if(l.line.startsWith("TRIGGER "))r=l.line.substring(8).trim(),s++;else if(l.line.startsWith("REQUIRE ")){const c=l.line.substring(8).trim();a.push(v(c)),s++}else if(l.line.startsWith("NODE ")){const c=Vt(e,s);o.push(c.node),i||(i=c.node.id),s=c.nextIndex}else throw new Error(`Unexpected token at line ${l.lineNumber}: ${l.line}`)}return{id:t,triggerLocation:r,conditions:a.length>0?a:void 0,startNode:i,nodes:o}}function Rt(n,t){const e=n;window.doodle={setFlag(r){e.state.flags[r]=!0,t(),console.log(`🐾 Flag set: ${r}`)},clearFlag(r){delete e.state.flags[r],t(),console.log(`🐾 Flag cleared: ${r}`)},setVariable(r,a){e.state.variables[r]=a,t(),console.log(`🐾 Variable set: ${r} = ${a}`)},getVariable(r){const a=e.state.variables[r];return console.log(`🐾 Variable: ${r} = ${a}`),a},teleport(r){n.travelTo(r),t(),console.log(`🐾 Teleported to: ${r}`)},triggerDialogue(r){const a=e.registry.dialogues[r];if(!a){console.error(`🐾 Dialogue not found: ${r}`);return}const o=a.nodes.find(i=>i.id===a.startNode);if(!o){console.error(`🐾 Start node not found for dialogue: ${r}`);return}e.state.dialogueState={dialogueId:a.id,nodeId:o.id},t(),console.log(`🐾 Triggered dialogue: ${r}`)},setQuestStage(r,a){e.state.questProgress[r]=a,t(),console.log(`🐾 Quest stage set: ${r} -> ${a}`)},addItem(r){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}`))},removeItem(r){const a=e.state.inventory.indexOf(r);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}`)},inspect(){const r=n.getSnapshot();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()")},inspectState(){return console.log("🐾 GAME STATE:",e.state),e.state},inspectRegistry(){return console.log("🐾 CONTENT REGISTRY:",e.registry),e.registry}},console.log("🐾 Doodle Engine dev tools enabled! Type `doodle.inspect()` to see available commands.")}const Dt="0.0.1";exports.Engine=Ct;exports.VERSION=Dt;exports.applyEffect=C;exports.applyEffects=y;exports.buildSnapshot=L;exports.createResolver=bt;exports.enableDevTools=Rt;exports.evaluateCondition=w;exports.evaluateConditions=S;exports.parseCondition=v;exports.parseDialogue=kt;exports.parseEffect=I;exports.resolveText=N;