{"inkVersion":21,"root":[["#","^AUTHOR: Rรฉmy Vim","/#","#","^TITLE: Ink Story Template","/#","#","^PAGE_MENU: sheet, inventory_page, relationships ,,credits,content_warnings","/#","#","^THEME: light","/#","#","^TONE_INDICATORS: on","/#","#","^TONE: flirty local_fire_department","/#","#","^TONE: shy favorite","/#","#","^TONE: bold star","/#","#","^TONE: sarcasm ๐Ÿ˜","/#","#","^TONE: danger warning","/#","\n","\n","\n","\n","\n","\n","\n","\n","\n","\n","\n","\n","\n","\n","\n","\n","^: Template Feature Demo","\n","ev",{"x()":"NOW"},"/ev",{"VAR=":"session_start","re":true},"\n","^Welcome, storyteller!","\n","^So you're thinking about using [Ink](www.inklestudios.com/ink/) for your interactive fiction? Excellent choice. And you've found this template to go with it? Even better.","\n","^Here's what this template adds to your Ink stories:","\n","^> Complete save/load system with file import/export","\n","^> Easy text formatting using a markdown-esque system","\n","^> Reader-friendly theme and accessibility features","\n","^> Special reference pages (character sheets, maps, etc.)","\n","^> Easy image, audio, and background additions","\n","^> Looks great on phones, tablets, and computers","\n","^> Graceful error recovery when things go wrong","\n","^Ready to see how easy this is? Every feature you're about to experience will often take less than a line in your Ink script.","\n",{"->":"feature_menu"},["done",{"#n":"g-0"}],null],"done",{"feature_menu":[["^What would you like to explore in more detail?","\n","ev","str","^Save & Load","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Settings","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Text Formatting","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Choices","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Special Pages","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^User Input","/str","/ev",{"*":".^.c-5","flg":4},"ev","str","^Stat Bars","/str","/ev",{"*":".^.c-6","flg":4},"ev","str","^Media (Images & Audio)","/str","/ev",{"*":".^.c-7","flg":4},"ev","str","^Functions","/str","/ev",{"*":".^.c-8","flg":4},"ev","str","^Notifications","/str","/ev",{"*":".^.c-9","flg":4},"ev","str","^Styling","/str","/ev",{"*":".^.c-10","flg":4},"ev","str","^Getting Started","/str","/ev",{"*":".^.c-11","flg":4},{"c-0":["^ ",{"->":"saves_demo"},"\n",null],"c-1":["^ ",{"->":"settings_demo"},"\n",null],"c-2":["^ ",{"->":"formatting_demo"},"\n",null],"c-3":["^ ",{"->":"choices_demo"},"\n",null],"c-4":["^ ",{"->":"special_pages_demo"},"\n",null],"c-5":["^ ",{"->":"input_demo"},"\n",null],"c-6":["^ ",{"->":"statbars_demo"},"\n",null],"c-7":["^ ",{"->":"media_demo"},"\n",null],"c-8":["^ ",{"->":"functions"},"\n",null],"c-9":["^ ",{"->":"notifications_demo"},"\n",null],"c-10":["^ ",{"->":"styling_demo"},"\n",null],"c-11":["^ ",{"->":"getting_started"},"\n",null]}],null],"credits":["#","^SPECIAL_PAGE","/#","^: Credits","\n","^This _Ink Story Template_ is developed and maintained by [Rรฉmy Vim](www.tumblr.com/remyvim).","\n","^You can find the source code on GitHub: [github.com/RemyVim/ink-if-story-template](github.com/RemyVim/ink-if-story-template).","\n","^:: Built With","\n","^> __[Ink](www.inklestudios.com/ink/)__ by Inkle Studios","\n","^> __[inkjs](github.com/y-lohse/inkjs)__ for web playback","\n","^> Vanilla JavaScript (no frameworks)","\n","^> Modern CSS with responsive design","\n","^:: Images","\n","^> The seamless flower image used in this demo is by Anna Bazanova and can be purchased on [Vecteezy](www.vecteezy.com/vector-art/13507569-floral-seamless-retro-pattern-in-the-style-of-the-70s-hippie-aesthetics-flower-power-fashionable-vintage-60s-orange-yellow-brown-colors-fabric-wrapping-paper)","\n","^> The notification bell sound is from Jam FX, available on [Uppbeat](uppbeat.io/sfx/notification-alert-positive-bell/163519/45910)","\n","^:: Fonts","\n","^> [Merriweather](fonts.google.com/specimen/Merriweather) is by Sorkin Type","\n","^> [Inter](fonts.google.com/specimen/Inter) is by Rasmus Andersson","\n","^> [OpenDyslexic](opendyslexic.org) is by Abbie Gonzalez","\n","^> [Material Icons](fonts.google.com/icons) by Google","\n","done",null],"content_warnings":["#","^SPECIAL_PAGE","/#","^: Content Warnings","\n","^This demo contains:","\n","^> Intense button clicking action","\n","^> Graphic descriptions of text formatting","\n","^> Compulsive save file creation","\n","^> Strong language (like \"Ink\" and \"JavaScript\")","\n","^> Mature themes including proper error handling","\n","^> May cause sudden urges to write interactive fiction","\n","done",null],"sheet":["#","^SPECIAL_PAGE: Character Stats","/#","^: Character Stats","\n","^Your current stats...","\n","^__Hero Name:__ \"","ev",{"VAR?":"hero_name"},"out","/ev","^\"","\n","^__Hero Level:__ ","ev",{"VAR?":"character_level"},"out","/ev","\n","^__Skills Known:__","\n","ev",{"VAR?":"skills"},"LIST_COUNT",0,">","/ev",[{"->":".^.b","c":true},{"b":["\n","ev",{"VAR?":"skills"},{"VAR?":"combat"},"?","/ev",[{"->":".^.b","c":true},{"b":["^ โš”๏ธ Combat",{"->":".^.^.^.7"},null]}],"nop","\n","ev",{"VAR?":"skills"},{"VAR?":"magic"},"?","/ev",[{"->":".^.b","c":true},{"b":["^ โœจ Magic",{"->":".^.^.^.15"},null]}],"nop","\n","ev",{"VAR?":"skills"},{"VAR?":"stealth"},"?","/ev",[{"->":".^.b","c":true},{"b":["^ ๐Ÿฅท Stealth",{"->":".^.^.^.23"},null]}],"nop","\n","ev",{"VAR?":"skills"},{"VAR?":"diplomacy"},"?","/ev",[{"->":".^.b","c":true},{"b":["^ ๐Ÿ’ฌ Diplomacy",{"->":".^.^.^.31"},null]}],"nop","\n",{"->":"sheet.30"},null]}],[{"->":".^.b"},{"b":["\n","^No skills learned yet.","\n",{"->":"sheet.30"},null]}],"nop","\n","^Total skills mastered: ","ev",{"VAR?":"skills"},"LIST_COUNT","out","/ev","\n","done",null],"relationships":["#","^SPECIAL_PAGE: Relationships","/#","^: Character Relationships","\n","^__Friendship with your Companion:__ ","ev",{"VAR?":"friend_relationship"},"out","/ev","^ points","\n",["ev",{"VAR?":"friend_relationship"},80,">=","/ev",{"->":".^.b","c":true},{"b":["\n","^๐Ÿ’ Best Friends Forever - An unbreakable bond!","\n",{"->":".^.^.^.17"},null]}],["ev",{"VAR?":"friend_relationship"},60,">=","/ev",{"->":".^.b","c":true},{"b":["\n","^๐Ÿ˜Š Close Friends - They trust you deeply.","\n",{"->":".^.^.^.17"},null]}],["ev",{"VAR?":"friend_relationship"},40,">=","/ev",{"->":".^.b","c":true},{"b":["\n","^๐Ÿ™‚ Friends - A solid friendship.","\n",{"->":".^.^.^.17"},null]}],["ev",{"VAR?":"friend_relationship"},20,">=","/ev",{"->":".^.b","c":true},{"b":["\n","^๐Ÿ˜ Acquaintances - Still getting to know each other.","\n",{"->":".^.^.^.17"},null]}],[{"->":".^.b"},{"b":["\n","^๐Ÿ˜” Strained - Your relationship needs work.","\n",{"->":".^.^.^.17"},null]}],"nop","\n","#","^STATBAR: friend_relationship \"Friend Relationship\" clamp","/#","done",null],"inventory_page":["#","^SPECIAL_PAGE: Inventory","/#","^: Character Inventory","\n","^In your bag, you have:","\n","ev",{"VAR?":"inventory"},"LIST_COUNT",0,">","/ev",[{"->":".^.b","c":true},{"b":["\n","ev",{"VAR?":"inventory"},{"VAR?":"torch"},"?","/ev",[{"->":".^.b","c":true},{"b":["^ ๐Ÿ”ฆ Torch - Lights the way",{"->":".^.^.^.7"},null]}],"nop","\n","ev",{"VAR?":"inventory"},{"VAR?":"lantern"},"?","/ev",[{"->":".^.b","c":true},{"b":["^ ๐Ÿฎ Lantern - A steady light source",{"->":".^.^.^.15"},null]}],"nop","\n","ev",{"VAR?":"inventory"},{"VAR?":"sword"},"?","/ev",[{"->":".^.b","c":true},{"b":["^ โš”๏ธ Magic Sword - Glows with power",{"->":".^.^.^.23"},null]}],"nop","\n","ev",{"VAR?":"inventory"},{"VAR?":"shield"},"?","/ev",[{"->":".^.b","c":true},{"b":["^ ๐Ÿ›ก๏ธ Shield - Sturdy protection",{"->":".^.^.^.31"},null]}],"nop","\n","ev",{"VAR?":"inventory"},{"VAR?":"potion"},"?","/ev",[{"->":".^.b","c":true},{"b":["^ ๐Ÿงช Potion - Mysterious liquid",{"->":".^.^.^.39"},null]}],"nop","\n",{"->":".^.^.^.15"},null]}],[{"->":".^.b"},{"b":["\n","^Your inventory is empty!","\n",{"->":".^.^.^.15"},null]}],"nop","\n","^__Items carried:__ ","ev",{"VAR?":"inventory"},"LIST_COUNT","out","/ev","^ / 5","\n","done",null],"choices_demo":["^: Choice Customization","\n","^This template gives you control over how choices appear to readers.","\n","^:: Choice Numbering","\n","^By default, choices show keyboard hints (1, 2, 3...) on devices with keyboards. You can control this with:","\n","^`# CHOICE_NUMBERS: auto` โ€” Show on keyboard devices only (default)","\n","^`# CHOICE_NUMBERS: on` โ€” Always show","\n","^`# CHOICE_NUMBERS: off` โ€” Never show","\n","^__Note:__ Players can override this in the Settings menu.","\n","^:: Display Disabled Choices","\n","^You can mark a choice as disabled with the `# UNCLICKABLE` tag:","\n","^`+ # UNCLICKABLE [You're not brave enough...]`","\n","^:: Tone Indicators","\n","^Tone indicators are small icons that appear before choices, hinting at the tone or consequence of a choice.","\n","^To enable them, add these tags at the top of your main `.ink` file:","\n","^> `# TONE_INDICATORS: on` - if you want them on by default (readers can opt-out in Settings)","\n","^> `# TONE_INDICATORS: off` - if you want them enabled but invisible by default (readers can opt-in in Settings)","\n","^Then define the tag and icon pairs you want to use in your choices. You can use emoji or material icon names.","\n","^> `# TONE: flirty ๐Ÿ”ฅ`","\n","^> `# TONE: shy ๐Ÿ’œ`","\n","^> `# TONE: danger warning`","\n","^Accessibility note: Tone indicator labels are read aloud by screen readers. Choose descriptive names like \"warning\", \"flirty\", \"serious\" rather than abstract icon names like \"star_border\".","\n","^Then tag your choices like this:","\n","^`+ [Lean in closer # flirty]`","\n","^`+ #shy [Look away nervously]`","\n","^`+ Keep your distance # danger`","\n","^Note that following Ink's syntax, tags are only recognized if placed before or inside the brackets [].","\n","^You can add multiple tags to a single choice, but only the first icon will display on the left. The rest of the icons display after the choice text.","\n","^To make all tone icons appear after the choice text, add this tag to the beginning of your story:","\n","^> `# TONE_TRAILING`","\n","^A mysterious stranger conveniently materializes for this demo. Your move.","\n",{"->":".^.tone_indicator_menu"},{"tone_indicator_menu":[["ev","str","^Wink and smile ","#","^flirty","/#","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Look away nervously ","#","^shy","/#","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Crack a joke ","#","^bold ","/#","#","^flirty ","/#","#","^danger ","/#","#","^sarcasm","/#","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Keep your distance ","#","^danger","/#","/str","/ev",{"*":".^.c-3","flg":4},["ev",{"^->":"choices_demo.tone_indicator_menu.0.45.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","str","^You're not brave enough to say anything... (Locked choice)","/str","/ev",{"*":".^.^.c-4","flg":6},{"s":["#","^UNCLICKABLE ","/#",{"->":"$r","var":true},null]}],"ev","str","^You're not brave enough to walk away either... (Locked choice) ","#","^DISABLED","/#","/str","/ev",{"*":".^.c-5","flg":4},"ev","str","^Return to choice customization","/str","/ev",{"*":".^.c-6","flg":4},"ev","str","^Return to feature menu","/str","/ev",{"*":".^.c-7","flg":4},{"c-0":["\n","^Bold move! They smile back.","\n",{"->":".^.^.^.^.choices_submenu"},null],"c-1":["\n","^You feel your cheeks flush. They definitely noticed.","\n",{"->":".^.^.^.^.choices_submenu"},null],"c-2":["\n","^They laugh โ€” you're on a roll.","\n",{"->":".^.^.^.^.choices_submenu"},null],"c-3":["\n","^Better safe than sorry.","\n",{"->":".^.^.^.^.choices_submenu"},null],"c-4":["ev",{"^->":"choices_demo.tone_indicator_menu.0.c-4.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.45.s"},[{"#n":"$r2"}],"\n","^Sometimes silence speaks loudest. (You should not have gotten here... If you see this, please submit a bug report!)","\n",{"->":".^.^.^.^.choices_submenu"},null],"c-5":["\n","^Sometimes silence speaks loudest. (You should not have gotten here... If you see this, please submit a bug report!)","\n",{"->":".^.^.^.^.choices_submenu"},null],"c-6":["^ ","\n",{"->":".^.^.^.^"},null],"c-7":["^ ","\n",{"->":"feature_menu"},null]}],null],"choices_submenu":["^Try toggling tone indicators off in the __Settings__ menu above โ€” the icons will disappear in real-time!","\n","^You can also try turning choice numbering on and off in the __Settings__ menu.","\n",{"->":".^.^.tone_indicator_menu"},"done",null]}],"media_demo":["^: Media","\n","^The template includes ways to add media into a passage or special page.","\n","^:: Images","\n","^Background images:","\n","^> `# BACKGROUND: image.jpg` - Set a background image","\n","^> `# BACKGROUND: none` - Remove a background image","\n","^__Note:__ if you set a background image, it will stay unless replaced or removed, even if the story is restarted.","\n","^Inline images:","\n","^> `# IMAGE: image.jpg` โ€” Inline image (centered, natural size)","\n","^> `# IMAGE: image.jpg left` โ€” Float left, text wraps around","\n","^> `# IMAGE: image.jpg right 50px` โ€” Float right at 50px width","\n","^> `# IMAGE: image.jpg \"Description\"` โ€” Alt text for screen readers","\n","^> `# IMAGE: image.jpg caption \"Description\"` โ€” Shows alt text as visible caption","\n","^Alignment defaults to centered.","\n","^Width defaults to the image's natural size, capped at 100% of the text area.","\n","^Alt text improves accessibility for screen reader users.","\n","^:: Audio Support","\n","^> `# AUDIO: sound.mp3` - Play sound effects","\n","^> `# AUDIOLOOP: music.mp3` - Loop background music","\n",{"->":".^.media_submenu"},{"media_submenu":[["ev","str","^View inline image display","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Add background image","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Remove background image","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Ring a bell","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Ring a bell in a loop","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^Stop the ringing!","/str","/ev",{"*":".^.c-5","flg":4},"ev","str","^Back to feature menu","/str","/ev",{"*":".^.c-6","flg":4},{"c-0":["^ ",{"->":".^.^.^.^.add_image_inline"},"\n",null],"c-1":["^ ",{"->":".^.^.^.^.change_background"},"\n",null],"c-2":["^ ",{"->":".^.^.^.^.remove_background"},"\n",null],"c-3":["^ ",{"->":".^.^.^.^.play_sound"},"\n",null],"c-4":["^ ",{"->":".^.^.^.^.play_sound_loop"},"\n",null],"c-5":["^ ",{"->":".^.^.^.^.stop_sound_loop"},"\n",null],"c-6":["^ ",{"->":"feature_menu"},"\n",null]}],null],"change_background":["#","^BACKGROUND: assets/background.jpg","/#","^: Ink Tags","\n","^Called `# BACKGROUND: assets/background.jpg`","\n",{"->":".^.^.media_submenu"},null],"remove_background":["#","^BACKGROUND: none","/#","^: Ink Tags","\n","^Called `# BACKGROUND: none`","\n",{"->":".^.^.media_submenu"},null],"play_sound":["#","^AUDIO: assets/notification-bell.mp3","/#","^: Ink Tags","\n","^Called `# AUDIO: assets/notification-bell.mp3`","\n",{"->":".^.^.media_submenu"},null],"play_sound_loop":["#","^AUDIOLOOP: assets/notification-bell.mp3","/#","^: Ink Tags","\n","^Called `# AUDIOLOOP: assets/notification-bell.mp3`","\n",{"->":".^.^.media_submenu"},null],"stop_sound_loop":["#","^AUDIOLOOP: none","/#","^: Ink Tags","\n","^Called `# AUDIOLOOP: none`","\n",{"->":".^.^.media_submenu"},null],"add_image_inline":["^: Ink Tags","\n","^Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tincidunt scelerisque odio, non luctus turpis volutpat in. Vestibulum dapibus dapibus quam, ac posuere mauris bibendum quis.","\n","^Calling `# IMAGE: assets/background.jpg`","\n","#","^IMAGE: assets/background.jpg","/#","^Sed lorem ligula, elementum blandit tempus id, faucibus ac odio. Etiam at molestie dui, non lobortis nulla. Proin auctor enim a nibh rhoncus, eu lacinia nibh commodo.","\n","^Calling `# IMAGE: assets/background.jpg 50%%","\n","#","^IMAGE: assets/background.jpg 50%","/#","^Calling `# IMAGE: assets/background.jpg left 15%%","\n","#","^IMAGE: assets/background.jpg left 15%","/#","^Cras pretium metus nec nulla varius rhoncus. Duis maximus lorem eget mauris fringilla porttitor. Quisque quam nibh, molestie ac nulla et, porttitor feugiat mi. Praesent viverra feugiat elementum. Quisque id scelerisque est.","\n","^Calling `# IMAGE: assets/background.jpg right 250px caption \"Flowers!\"`","\n","#","^IMAGE: assets/background.jpg right 250px caption \"Flowers!\"","/#","^In hac habitasse platea dictumst. Aliquam erat volutpat. Praesent nec nisi vel mauris feugiat tincidunt et eget dui. Suspendisse at mauris a nulla porta malesuada. Aliquam vitae eros lacinia, gravida tellus in, porttitor libero. Cras molestie diam et facilisis aliquam. Aliquam a porttitor lectus. Maecenas nulla dui, posuere vel ligula sit amet, condimentum ornare lorem. Nunc lacinia nunc sit amet nisl pretium molestie.","\n","^Calling `# IMAGE: assets/background.jpg center 50vw \"Flowers!\"`","\n","^Note: Caption should not show because we didn't put the caption keyword in the tag. \"Flowers!\" will be used as alt text only (for screen readers).","\n","#","^IMAGE: assets/background.jpg center 50vw \"Flowers!\"","/#",{"->":".^.^.media_submenu"},null]}],"input_demo":["^: User Input","\n","^You can ask players for input that will then be stored in a variable of your choice. For this, use the special tag:","\n","^`# USER_INPUT: your_variable_name \"Placeholder text\"`","\n","^Placeholder text is optional. If you want to shorten it you can use `# INPUT` instead!","\n","^Write anything you want below. The story will pause until you input your text.","\n","^`# USER_INPUT: input \"Please input your text here.\"`","\n","#","^INPUT: input \"Please input your text here.\"","/#","^You wrote: \"","ev",{"VAR?":"input"},"out","/ev","^\".","\n",{"->":"feature_menu"},null],"formatting_demo":["^: Text Formatting","\n","^This template uses a markdown-adjacent system. Here's what you can do __without__ touching a single HTML tag:","\n","^:: Basic Text Styling","\n","^Make text __bold__ with double underscores: `__bold__`","\n","^Make text _italic_ with single underscores: `_italic_`","\n","^Combine them: ___bold and italic___ with `___text___`","\n","^Add `inline code` with backticks: %`inline code%`","\n","^:: Headers Work With Colons","\n","^Use colons at the start of lines for headers:","\n","^> `: Header 2` creates the largest header","\n","^> `:: Header 3` creates a medium header","\n","^> `::: Header 4` creates the smallest header","\n","^[---]","\n","^: Header 2","\n","^:: Header 3","\n","^::: Header 4","\n","^[---]","\n","^:: Separators","\n","^You can mark a separator line (like just above) with `[---]`.","\n","^:: Lists Are Easy","\n","^Use `>` at the start of lines for bullet points:","\n","^> First bullet point","\n","^> Second bullet point","\n","^> Third bullet point","\n","^> And so on...","\n","^:: Block Quotes","\n","^Use `>>` for block quotes and emphasis:","\n","^>> \"This template makes interactive fiction look professional without any web development knowledge required.\"","\n","^You can quote dialogue, important notes, or emphasis text this way.","\n","^:: Custom Inline Styles","\n","^The template also supports custom styling with brackets:","\n","^`[highlighted text](highlight)` becomes: [highlighted text](highlight)","\n","^`[important note](important)` becomes: [important note](important)","\n","^`[quiet aside](quiet)` becomes: [quiet aside](quiet)","\n","^:: Links","\n","^`[link text](example.com)` becomes: [link text](example.com)","\n","^`[link text](example.com/page.html)` becomes: [link text](example.com/page.html)","\n","^:: Line Breaks","\n","^End a line with two spaces for a manual line break.","\n","^Like this!","\n","^:: Escaping Characters","\n","^Need to show markdown characters literally? Use the ` % ` character right before:","\n","^`%%_%%_this won't be bold%%_%%_` becomes: %_%_this won't be bold%_%_","\n","^`%%`this won't be code%%`` becomes: %`this won't be code%`","\n","^`%> this won't be a bullet point` becomes: > this won't be a bullet point","\n","^You can also simply start a line with a ` % ` character and markdown processing will be disabled for the entire line.","\n",{"->":"feature_menu"},null],"functions":["^: Functions","\n","^Ink offers a few built-in functions. This template extends that and adds a few more useful ones for string manipulation and math.","\n",{"->":".^.menu_functions"},{"menu_functions":[["ev","str","^See string functions","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^See math functions","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^See fairmath functions","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^See time functions","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Return to feature menu","/str","/ev",{"*":".^.c-4","flg":4},{"c-0":["\n",{"->":".^.^.^.^.string_functions"},null],"c-1":["\n",{"->":".^.^.^.^.math_functions"},null],"c-2":["\n",{"->":".^.^.^.^.fairmath_functions"},null],"c-3":["\n",{"->":".^.^.^.^.time_functions"},null],"c-4":["^ ","\n",{"->":"feature_menu"},null]}],null],"string_functions":["^: String Functions","\n","^Add these `EXTERNAL` delarations to your main .ink file. You only need to add them once in your story to be able to use them anywhere. You can also pick and choose which ones to include.","\n","^`EXTERNAL UPPERCASE(string)`","\n","^`EXTERNAL LOWERCASE(string)`","\n","^`EXTERNAL CAPITALIZE(string)`","\n","^`EXTERNAL TRIM(string)`","\n","^`EXTERNAL LENGTH(string)`","\n","^`EXTERNAL CONTAINS(string, search)`","\n","^`EXTERNAL STARTS_WITH(string, search)`","\n","^`EXTERNAL ENDS_WITH(string, search)`","\n","^`EXTERNAL REPLACE(string, search, replacement)`","\n","^`EXTERNAL REPLACE_ALL(string, search, replacement)`","\n","^Then you can use these functions in your Ink story.","\n","^:: String Function Examples","\n","^`VAR player_name = \" john doe \"`","\n","^`VAR cleaned_name = \"\"`","\n","^`~ cleaned_name = TRIM(player_name)`","\n","ev",{"VAR?":"player_name"},{"x()":"TRIM","exArgs":1},"/ev",{"VAR=":"cleaned_name","re":true},"\n","^`Player name: \"{player_name}\"`","\n","^Player name: \"","ev",{"VAR?":"player_name"},"out","/ev","^\"","\n","^`Cleaned name: \"{cleaned_name}\"`","\n","^Cleaned name: \"","ev",{"VAR?":"cleaned_name"},"out","/ev","^\"","\n","^`Hello, {CAPITALIZE(cleaned_name)}!`","\n","^Hello, ","ev",{"VAR?":"cleaned_name"},{"x()":"CAPITALIZE","exArgs":1},"out","/ev","^!","\n","^`Your name has {LENGTH(cleaned_name)} characters.`","\n","^Your name has ","ev",{"VAR?":"cleaned_name"},{"x()":"LENGTH","exArgs":1},"out","/ev","^ characters.","\n","^`In uppercase: {UPPERCASE(cleaned_name)}`","\n","^In uppercase: ","ev",{"VAR?":"cleaned_name"},{"x()":"UPPERCASE","exArgs":1},"out","/ev","\n","^`In lowercase: {LOWERCASE(cleaned_name)}`","\n","^In lowercase: ","ev",{"VAR?":"cleaned_name"},{"x()":"LOWERCASE","exArgs":1},"out","/ev","\n","^`{CONTAINS(cleaned_name, \"doe\"): You're a Doe!}`","\n","ev",{"VAR?":"cleaned_name"},"str","^doe","/str",{"x()":"CONTAINS","exArgs":2},"/ev",[{"->":".^.b","c":true},{"b":["^ You're a Doe!",{"->":".^.^.^.106"},null]}],"nop","\n","^`{STARTS_WITH(cleaned_name, \"john\"): Your name starts with John.}`","\n","ev",{"VAR?":"cleaned_name"},"str","^john","/str",{"x()":"STARTS_WITH","exArgs":2},"/ev",[{"->":".^.b","c":true},{"b":["^ Your name starts with John.",{"->":".^.^.^.118"},null]}],"nop","\n","^`{ENDS_WITH(cleaned_name, \"doe\"): Your name ends with Doe.}`","\n","ev",{"VAR?":"cleaned_name"},"str","^doe","/str",{"x()":"ENDS_WITH","exArgs":2},"/ev",[{"->":".^.b","c":true},{"b":["^ Your name ends with Doe.",{"->":".^.^.^.130"},null]}],"nop","\n","^`VAR greeting = \"Hello World\"`","\n","^`Greeting: {greeting}`","\n","^Greeting: ","ev",{"VAR?":"greeting"},"out","/ev","\n","^`With replacement: {REPLACE(greeting, \"World\", \"Ink\")}`","\n","^With replacement: ","ev",{"VAR?":"greeting"},"str","^World","/str","str","^Ink","/str",{"x()":"REPLACE","exArgs":3},"out","/ev","\n","^`VAR repeated = \"la la la\"`","\n","^`Repeated: {repeated}`","\n","^Repeated: ","ev",{"VAR?":"repeated"},"out","/ev","\n","^`Replace all: {REPLACE_ALL(repeated, \"la\", \"to\")}`","\n","^Replace all: ","ev",{"VAR?":"repeated"},"str","^la","/str","str","^to","/str",{"x()":"REPLACE_ALL","exArgs":3},"out","/ev","\n",{"->":".^.^.menu_functions"},null],"math_functions":["^: Math Functions","\n","^Add these external functions to your main .ink file. You only need to add them once in your story to be able to use them anywhere. You can also pick and choose which ones to include.","\n","^Math functions:","\n","^`EXTERNAL ROUND(value)`","\n","^`EXTERNAL CLAMP(value, min, max)`","\n","^`EXTERNAL ABS(value)`","\n","^`EXTERNAL PERCENT(value, total)`","\n","^:: Math Function Examples","\n","^`VAR current_health = 150`","\n","^`VAR max_health = 100`","\n","^`Clamped health: {CLAMP(current_health, 0, max_health)} (was {current_health})`","\n","^Clamped health: ","ev",{"VAR?":"current_health"},0,{"VAR?":"max_health"},{"x()":"CLAMP","exArgs":3},"out","/ev","^ (was ","ev",{"VAR?":"current_health"},"out","/ev","^)","\n","^`Rounded: {ROUND(7.6)}`","\n","^Rounded: ","ev",7.6,{"x()":"ROUND","exArgs":1},"out","/ev","\n","^`Absolute damage: {ABS(-25)}`","\n","^Absolute damage: ","ev",-25,{"x()":"ABS","exArgs":1},"out","/ev","\n","^`Progress: {PERCENT(75, 200)}%%","\n","^Progress: ","ev",75,200,{"x()":"PERCENT","exArgs":2},"out","/ev","^%","\n","^[---]","\n","^For reference, the following functions are already built-in to Ink:","\n","^> `RANDOM(min, max)`: Random integer (inclusive)","\n","^> `FLOOR(x)`: Round down","\n","^> `CEILING(x)`: Round up","\n","^> `INT(x)`: Truncate to integer","\n","^> `FLOAT(x)`: Convert to decimal","\n","^> `POW(x, y)`: x to the power of y","\n","^> `MIN(a, b)`: Smaller of two values","\n","^> `MAX(a, b)`: Larger of two values","\n","^[---]","\n",{"->":".^.^.menu_functions"},null],"fairmath_functions":["^: Fairmath Functions","\n","^Fairmath (of ChoiceScript fame) makes stats harder to change the closer they get to 0 or 100. Gains shrink as you approach the cap, losses shrink as you approach zero. Results are automatically kept between 0 and 100. This keeps stats in interesting ranges and prevents runaway values.","\n","^And you can now use fairmath directly in your Ink story!","\n","^To do so, add these external functions to your main .ink file. You only need to add them once in your story to be able to use them anywhere. You can also pick and choose which ones to include.","\n","^Fairmath functions:","\n","^`EXTERNAL FAIRADD(stat, percent)`","\n","^`EXTERNAL FAIRSUB(stat, percent)`","\n","^:: Fairmath Function Examples","\n",{"->":".^.^.fairmath_example"},null],"fairmath_example":[["^Reputation stat is currently ","ev",{"VAR?":"reputation"},"out","/ev","^.","\n","ev","str","^Reset to 50","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Add 10","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Add 20","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Add 50","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Remove 10","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^Remove 20","/str","/ev",{"*":".^.c-5","flg":4},"ev","str","^Remove 50","/str","/ev",{"*":".^.c-6","flg":4},"ev","str","^Return to functions menu","/str","/ev",{"*":".^.c-7","flg":4},{"c-0":["\n","^:: Fairmath Function Examples","\n","ev",50,"/ev",{"VAR=":"reputation","re":true},{"->":".^.^.^"},null],"c-1":["\n","^:: Fairmath Function Examples","\n","^`~ reputation = FAIRADD(reputation, 10)`","\n","ev",{"VAR?":"reputation"},10,{"x()":"FAIRADD","exArgs":2},"/ev",{"VAR=":"reputation","re":true},"\n",{"->":".^.^.^"},null],"c-2":["\n","^:: Fairmath Function Examples","\n","^`~ reputation = FAIRADD(reputation, 20)`","\n","ev",{"VAR?":"reputation"},20,{"x()":"FAIRADD","exArgs":2},"/ev",{"VAR=":"reputation","re":true},"\n",{"->":".^.^.^"},null],"c-3":["\n","^:: Fairmath Function Examples","\n","^`~ reputation = FAIRADD(reputation, 50)`","\n","ev",{"VAR?":"reputation"},50,{"x()":"FAIRADD","exArgs":2},"/ev",{"VAR=":"reputation","re":true},"\n",{"->":".^.^.^"},null],"c-4":["\n","^:: Fairmath Function Examples","\n","^`~ reputation = FAIRSUB(reputation, 10)`","\n","ev",{"VAR?":"reputation"},10,{"x()":"FAIRSUB","exArgs":2},"/ev",{"VAR=":"reputation","re":true},"\n",{"->":".^.^.^"},null],"c-5":["\n","^:: Fairmath Function Examples","\n","^`~ reputation = FAIRSUB(reputation, 20)`","\n","ev",{"VAR?":"reputation"},20,{"x()":"FAIRSUB","exArgs":2},"/ev",{"VAR=":"reputation","re":true},"\n",{"->":".^.^.^"},null],"c-6":["\n","^:: Fairmath Function Examples","\n","^`~ reputation = FAIRSUB(reputation, 50)`","\n","ev",{"VAR?":"reputation"},50,{"x()":"FAIRSUB","exArgs":2},"/ev",{"VAR=":"reputation","re":true},"\n",{"->":".^.^.^"},null],"c-7":["^ ","\n",{"->":".^.^.^.^"},null]}],null],"time_functions":["^: Time Functions","\n","^These functions give your Ink story real-world time awareness. Perfect for session tracking, real-time games, or narratives where you really want to make it feel like everything is happening in real time.","\n","^Add these external declarations to your main .ink file:","\n","^`EXTERNAL NOW()`","\n","^`EXTERNAL SECONDS_SINCE(start)`","\n","^`EXTERNAL MINUTES_SINCE(start)`","\n","^`EXTERNAL TIME_SINCE(start)`","\n","^`EXTERNAL FORMAT_DATE(timestamp, locale)`","\n","^`EXTERNAL FORMAT_TIME(timestamp, locale)`","\n","^`EXTERNAL FORMAT_DATETIME(timestamp, locale)`","\n","^`EXTERNAL OFFSET_DATE(timestamp, years, months, days, hours, minutes)`","\n","^:: Getting the Current Time","\n","^`VAR session_start = 0`","\n","^`~ session_start = NOW()`","\n","^(I called this at demo start!)","\n","^The current timestamp is ","ev",{"VAR?":"session_start"},"out","/ev","^. That's a Unix timestamp (seconds since January 1, 1970).","\n","^:: Formatting Dates and Times","\n","^`VAR locale = \"en-US\"`","\n","^`Today is {FORMAT_DATE(NOW(), locale)}.`","\n","^Today is ","ev",{"x()":"NOW"},{"VAR?":"locale"},{"x()":"FORMAT_DATE","exArgs":2},"out","/ev","^.","\n","^`The time is {FORMAT_TIME(NOW(), locale)}.`","\n","^The time is ","ev",{"x()":"NOW"},{"VAR?":"locale"},{"x()":"FORMAT_TIME","exArgs":2},"out","/ev","^.","\n","^`Full: {FORMAT_DATETIME(NOW(), locale)}`","\n","^Full: ","ev",{"x()":"NOW"},{"VAR?":"locale"},{"x()":"FORMAT_DATETIME","exArgs":2},"out","/ev","\n","^:: Using Different Locales","\n","^The locale parameter determines how to display the date and time. You can find a list of locales at [simplelocalize.io](simplelocalize.io/data/locales/).","\n","^`French: {FORMAT_DATETIME(NOW(), \"fr-FR\")}`","\n","^French: ","ev",{"x()":"NOW"},"str","^fr-FR","/str",{"x()":"FORMAT_DATETIME","exArgs":2},"out","/ev","\n","^`Russian: {FORMAT_DATETIME(NOW(), \"ru-RU\")}`","\n","^Russian: ","ev",{"x()":"NOW"},"str","^ru-RU","/str",{"x()":"FORMAT_DATETIME","exArgs":2},"out","/ev","\n","^`Japanese: {FORMAT_DATETIME(NOW(), \"ja-JP\")}`","\n","^Japanese: ","ev",{"x()":"NOW"},"str","^ja-JP","/str",{"x()":"FORMAT_DATETIME","exArgs":2},"out","/ev","\n","^`Egyptian: {FORMAT_DATETIME(NOW(), \"ar-EG\")}`","\n","^Egyptian: ","ev",{"x()":"NOW"},"str","^ar-EG","/str",{"x()":"FORMAT_DATETIME","exArgs":2},"out","/ev","\n","^`Hindi: {FORMAT_DATETIME(NOW(), \"hi-IN\")}`","\n","^Hindi: ","ev",{"x()":"NOW"},"str","^hi-IN","/str",{"x()":"FORMAT_DATETIME","exArgs":2},"out","/ev","\n","^If you enter an invalid locale it defaults to `en-US` and throws a warning in the browser's console:","\n","^`Invalid locale: {FORMAT_DATETIME(NOW(), \"tada\")}`","\n","^Invalid locale: ","ev",{"x()":"NOW"},"str","^tada","/str",{"x()":"FORMAT_DATETIME","exArgs":2},"out","/ev","\n","^:: Date Math with OFFSET_DATE","\n","^Use `OFFSET_DATE` to create timestamps in the past or future. Parameters are: timestamp, years, months, days, hours, minutes.","\n","^`VAR five_years_ago = 0`","\n","^`~ five_years_ago = OFFSET_DATE(NOW(), -5, 0, 0, 0, 0)`","\n","^`The incident happened on {FORMAT_DATE(five_years_ago, \"en-US\")}.`","\n","ev",{"x()":"NOW"},-5,0,0,0,0,{"x()":"OFFSET_DATE","exArgs":6},"/ev",{"VAR=":"five_years_ago","re":true},"\n","^The incident happened on ","ev",{"VAR?":"five_years_ago"},"str","^en-US","/str",{"x()":"FORMAT_DATE","exArgs":2},"out","/ev","^.","\n","^`VAR next_week = 0`","\n","^`~ next_week = OFFSET_DATE(NOW(), 0, 0, 7, 0, 0)`","\n","^`See you on {FORMAT_DATE(next_week, \"en-US\")}!`","\n","ev",{"x()":"NOW"},0,0,7,0,0,{"x()":"OFFSET_DATE","exArgs":6},"/ev",{"VAR=":"next_week","re":true},"\n","^See you on ","ev",{"VAR?":"next_week"},"str","^en-US","/str",{"x()":"FORMAT_DATE","exArgs":2},"out","/ev","^!","\n","^:: Tracking Elapsed Time","\n","^`You've been exploring this demo for {TIME_SINCE(session_start)}.`","\n","^You've been exploring this demo for ","ev",{"VAR?":"session_start"},{"x()":"TIME_SINCE","exArgs":1},"out","/ev","^.","\n","^For gameplay checks, use the numeric timestamp versions:","\n","^`{SECONDS_SINCE(session_start)} seconds have passed.`","\n","ev",{"VAR?":"session_start"},{"x()":"SECONDS_SINCE","exArgs":1},"out","/ev","^ seconds have passed.","\n","^`{MINUTES_SINCE(session_start)} minutes have passed.`","\n","ev",{"VAR?":"session_start"},{"x()":"MINUTES_SINCE","exArgs":1},"out","/ev","^ minutes have passed.","\n",{"->":".^.^.menu_functions"},null]}],"getting_started":["^: Getting Started Guide","\n","^Using this template is straightforward:","\n","^:: The Process","\n","^1. __Get the template__ from [GitHub](github.com/RemyVim/ink-if-story-template)","\n","^2. __Write__ your story in Ink (like this demo)","\n","^3. __Compile__ it to JSON using Inky or inklecate","\n","^4. __Replace__ the `story.json` file in the template","\n","^5. __Customize__ the CSS if desired (optional)","\n","^6. __Deploy__ anywhere that serves static files","\n","^This template uses vanilla JavaScript - no npm, webpack, or any complex tooling needed. Just write, compile, and deploy.","\n","^Happy writing!","\n",{"->":"feature_menu"},null],"notifications_demo":[["^: Notifications","\n","^This template also supports notifications.","\n","^You can trigger a notification with these custom Ink tags:","\n","^> `# ACHIEVEMENT: You did it!`","\n","^> `# NOTIFICATION: Something happened.`","\n","^> `# ERROR: What just happened?`","\n","^A notification is automatically displayed when the player interacts with the save system. Notifications are also displayed if the template encounters an error.","\n","ev","str","^Trigger a notification","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Trigger an achievement notification","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Trigger a warning notification","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Trigger an error notification","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Back to feature menu","/str","/ev",{"*":".^.c-4","flg":4},{"c-0":["\n","#","^NOTIFICATION: Something happened.","/#",{"->":".^.^.^"},null],"c-1":["\n","#","^ACHIEVEMENT: You did it!","/#",{"->":".^.^.^"},null],"c-2":["\n","#","^WARNING: Uh oh this is not normal.","/#",{"->":".^.^.^"},null],"c-3":["\n","#","^ERROR: What just happened?","/#",{"->":".^.^.^"},null],"c-4":["^ ",{"->":"feature_menu"},"\n",null]}],null],"saves_demo":["^: Save & Load Story Progress","\n","^The saves system works out of the box. Check out the `save` menu above.","\n","^From there, players have 5 slots where they can:","\n","^> Save their current progress","\n","^> Load a previous save","\n","^> Export a save (download a json file of the current story state)","\n","^> Import a save and start playing where they left off on another device for example","\n","^> Delete saves","\n","^You'll also notice the special autosave slot. This automatically saves progress every time a choice is selected. (This behavior can be disabled by the players in the settings menu.)","\n","^Tip: Handy keyboard shortcuts:","\n","^> `ctrl`+`s` opens the save menu (`cmd`+`s` on Mac)","\n","^> `esc` closes the save menu","\n","^> `ctrl`+`r` restarts the game (`cmd`+`r` on Mac)","\n",{"->":"feature_menu"},null],"settings_demo":["^: Settings Menu","\n","^In the `settings` menu above, you will find:","\n","^> Theme switcher (light/dark/auto)","\n","^> Font switcher, including accessibility options such as dyslexia-friendly font, font sizing and spacing options","\n","^> Audio controls (if the story contains audio)","\n","^> Animation control","\n","^> Enable/disable the autosave feature","\n","^You can open the settings menu with `ctrl`+`,` (`cmd`+`,` on Mac) and close it with `esc`.","\n",{"->":"feature_menu"},null],"special_pages_demo":["^: Special Pages System","\n","^You can create special pages that live outside the flow of your story's narrative. These could be anything you can imagine, from a simple credits page to a full character stats page.","\n","^You can mark any Ink knot with the tag `# SPECIAL_PAGE`.","\n","^This will also automatically add the page to the navigation menu above. The \"credits\" and \"content warnings\" pages above were created in this way.","\n","^Special pages do not advance the story and have a built-in \"Return to Story\" button that allows the player to return exactly where they left off.","\n","^Special pages in the menu are ordered alphabetically be default. You can order them via a special tag (using the knot names):","\n","^`#PAGE_MENU:character_sheet,inventory,relationships,,credits,content_warnings`","\n","^The double comma is interpreted as a section separator. Any omitted special pages will appear in a new section, ordered alphabetically.","\n","^Let's test that special pages properly reflect variable changes. Try modifying these values, then check the special pages in the menu above to see them update in real-time.","\n",{"->":".^.special_pages_menu"},{"special_pages_menu":[["^__Current Status:__","\n","^Hero Name: \"","ev",{"VAR?":"hero_name"},"out","/ev","^\"","\n","^Hero Level: ","ev",{"VAR?":"character_level"},"out","/ev","\n","^Friendship: ","ev",{"VAR?":"friend_relationship"},"out","/ev","\n","ev","str","^Level up your hero! (+1 level)","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Decrease hero level (-1 level)","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Change your hero's name","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Change your hero's inventory","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Change your hero's skills","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^Improve friendship (+10 points)","/str","/ev",{"*":".^.c-5","flg":4},"ev","str","^Damage friendship (-10 points)","/str","/ev",{"*":".^.c-6","flg":4},"ev","str","^Return to feature menu","/str","/ev",{"*":".^.c-7","flg":4},{"c-0":["\n","ev",{"VAR?":"character_level"},1,"+",{"VAR=":"character_level","re":true},"/ev","^โš”๏ธ Your hero reached level ","ev",{"VAR?":"character_level"},"out","/ev","^!","\n","^โ†’ Check the \"Character\" page in the menu to see your new level.","\n",{"->":".^.^.^"},null],"c-1":["\n","ev",{"VAR?":"character_level"},1,"-",{"VAR=":"character_level","re":true},"/ev","^๐Ÿ“‰ Your hero dropped to level ","ev",{"VAR?":"character_level"},"out","/ev","^.","\n","^โ†’ Check the \"Character\" page in the menu to confirm the change.","\n",{"->":".^.^.^"},null],"c-2":["\n","^Your hero needs a new identity!","\n",["ev","str","^Name them \"Shadow Walker\"","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Name them \"Dragon Slayer\"","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Keep current name","/str","/ev",{"*":".^.c-2","flg":4},{"c-0":["\n","ev","str","^Shadow Walker","/str","/ev",{"VAR=":"hero_name","re":true},"^โ†’ Your hero is now known as \"","ev",{"VAR?":"hero_name"},"out","/ev","^\"! Check the Character page.","\n",{"->":".^.^.^.^.^"},null],"c-1":["\n","ev","str","^Dragon Slayer","/str","/ev",{"VAR=":"hero_name","re":true},"^โ†’ Your hero is now known as \"","ev",{"VAR?":"hero_name"},"out","/ev","^\"! Check the Character page.","\n",{"->":".^.^.^.^.^"},null],"c-2":["\n",{"->":".^.^.^.^.^"},null]}],null],"c-3":["\n","^Your hero needs items!","\n",["ev","str","^Find a magic sword! (add to inventory)","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Loose your magic sword! (remove from inventory)","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Find a torch (add to inventory)","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Lose your torch (remove from inventory)","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Find a lantern (add to inventory)","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^Find a shield (add to inventory)","/str","/ev",{"*":".^.c-5","flg":4},"ev","str","^Drink your potion (remove from inventory)","/str","/ev",{"*":".^.c-6","flg":4},"ev","str","^Keep current items","/str","/ev",{"*":".^.c-7","flg":4},{"c-0":["\n","ev",{"VAR?":"inventory"},{"VAR?":"sword"},"+",{"VAR=":"inventory","re":true},"/ev","^โš”๏ธ You found a magic sword!","\n","^โ†’ Visit the \"Inventory\" page to see your updated equipment.","\n",{"->":".^.^.^.^.^"},null],"c-1":["\n","ev",{"VAR?":"inventory"},{"VAR?":"sword"},"-",{"VAR=":"inventory","re":true},"/ev","^โš”๏ธ Oh no! You lost your magic sword!","\n","^โ†’ Check the \"Inventory\" page to see what you have left.","\n",{"->":".^.^.^.^.^"},null],"c-2":["\n","ev",{"VAR?":"inventory"},{"VAR?":"torch"},"+",{"VAR=":"inventory","re":true},"/ev","^๐Ÿ”ฆ You found a torch.","\n","^โ†’ Visit the \"Inventory\" page to see your updated equipment.","\n",{"->":".^.^.^.^.^"},null],"c-3":["\n","ev",{"VAR?":"inventory"},{"VAR?":"torch"},"-",{"VAR=":"inventory","re":true},"/ev","^๐Ÿ”ฆ Your torch burned out.","\n","^โ†’ Check the \"Inventory\" page to see what you have left.","\n",{"->":".^.^.^.^.^"},null],"c-4":["\n","ev",{"VAR?":"inventory"},{"VAR?":"lantern"},"+",{"VAR=":"inventory","re":true},"/ev","^๐Ÿฎ You found a lantern.","\n","^โ†’ Visit the \"Inventory\" page to see your updated equipment.","\n",{"->":".^.^.^.^.^"},null],"c-5":["\n","ev",{"VAR?":"inventory"},{"VAR?":"shield"},"+",{"VAR=":"inventory","re":true},"/ev","^๐Ÿ›ก๏ธ You found a shield.","\n","^โ†’ Visit the \"Inventory\" page to see your updated equipment.","\n",{"->":".^.^.^.^.^"},null],"c-6":["\n","ev",{"VAR?":"inventory"},{"VAR?":"potion"},"-",{"VAR=":"inventory","re":true},"/ev","^๐Ÿงช You drank your potion. Yum.","\n","^โ†’ Check the \"Inventory\" page to see what you have left.","\n",{"->":".^.^.^.^.^"},null],"c-7":["\n",{"->":".^.^.^.^.^"},null]}],null],"c-4":["\n","^Your hero needs different skills!","\n",["ev","str","^Gain the combat skill","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Forget the combat skill","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Gain the magic skill","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Forget the magic skill","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Gain the stealth skill","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^Forget the stealth skill","/str","/ev",{"*":".^.c-5","flg":4},"ev","str","^Gain the diplomacy skill","/str","/ev",{"*":".^.c-6","flg":4},"ev","str","^Forget the diplomacy skill","/str","/ev",{"*":".^.c-7","flg":4},"ev","str","^Keep current skills","/str","/ev",{"*":".^.c-8","flg":4},{"c-0":["\n","ev",{"VAR?":"skills"},{"VAR?":"combat"},"+",{"VAR=":"skills","re":true},"/ev","^โš”๏ธ You learned combat!","\n","^โ†’ The \"Character\" page now shows your new skill.","\n",{"->":".^.^.^.^.^"},null],"c-1":["\n","ev",{"VAR?":"skills"},{"VAR?":"combat"},"-",{"VAR=":"skills","re":true},"/ev","^โš”๏ธ You forgot combat...","\n","^โ†’ The \"Character\" page no longer shows your combat skill.","\n",{"->":".^.^.^.^.^"},null],"c-2":["\n","ev",{"VAR?":"skills"},{"VAR?":"magic"},"+",{"VAR=":"skills","re":true},"/ev","^โœจ You learned magic!","\n","^โ†’ The \"Character\" page now shows your new skill.","\n",{"->":".^.^.^.^.^"},null],"c-3":["\n","ev",{"VAR?":"skills"},{"VAR?":"magic"},"-",{"VAR=":"skills","re":true},"/ev","^โœจ You forgot magic...","\n","^โ†’ The \"Character\" page no longer shows your magic skill.","\n",{"->":".^.^.^.^.^"},null],"c-4":["\n","ev",{"VAR?":"skills"},{"VAR?":"stealth"},"+",{"VAR=":"skills","re":true},"/ev","^๐Ÿฅท You learned stealth!","\n","^โ†’ The \"Character\" page now shows your new skill.","\n",{"->":".^.^.^.^.^"},null],"c-5":["\n","ev",{"VAR?":"skills"},{"VAR?":"stealth"},"-",{"VAR=":"skills","re":true},"/ev","^๐Ÿฅท You forgot stealth...","\n","^โ†’ The \"Character\" page no longer shows your stealth skill.","\n",{"->":".^.^.^.^.^"},null],"c-6":["\n","ev",{"VAR?":"skills"},{"VAR?":"diplomacy"},"+",{"VAR=":"skills","re":true},"/ev","^๐Ÿ’ฌ You learned diplomacy!","\n","^โ†’ The \"Character\" page now shows your new skill.","\n",{"->":".^.^.^.^.^"},null],"c-7":["\n","ev",{"VAR?":"skills"},{"VAR?":"diplomacy"},"-",{"VAR=":"skills","re":true},"/ev","^๐Ÿ’ฌ You forgot diplomacy...","\n","^โ†’ The \"Character\" page no longer shows your diplomacy skill.","\n",{"->":".^.^.^.^.^"},null],"c-8":["\n",{"->":".^.^.^.^.^"},null]}],null],"c-5":["\n","ev",{"VAR?":"friend_relationship"},10,"+",{"VAR=":"friend_relationship","re":true},"/ev","^๐Ÿ’ Your friendship grew to ","ev",{"VAR?":"friend_relationship"},"out","/ev","^ points!","\n","^โ†’ See the \"Relationships\" page for your updated bond strength.","\n",{"->":".^.^.^"},null],"c-6":["\n","ev",{"VAR?":"friend_relationship"},10,"-",{"VAR=":"friend_relationship","re":true},"/ev","^๐Ÿ’” Your friendship dropped to ","ev",{"VAR?":"friend_relationship"},"out","/ev","^ points.","\n","^โ†’ Check the \"Relationships\" page to see the current status.","\n",{"->":".^.^.^"},null],"c-7":["^ ","\n",{"->":"feature_menu"},null]}],null]}],"statbars_demo":["^: Stat Bars","\n","^Stat bars display your story variables as visual progress bars โ€” perfect for character sheets, relationships, and any numeric stats.","\n","^:: Basic Stat Bar","\n","^`# STATBAR: health`","\n","#","^STATBAR: health","/#","^[---]","\n","^:: Custom Display Name","\n","^`# STATBAR: health \"Hit Points\"`","\n","#","^STATBAR: health \"Hit Points\"","/#","^[---]","\n","^:: Clamped Value","\n","^By default, stat bars show the real value even if it goes below 0 or above max. This can help you as an author to see the true value of your variables. Add `clamp` to keep it in range. Try decreasing health below 0 to see the difference!","\n","^`# STATBAR: health \"Hit Points (Clamped)\" clamp`","\n","#","^STATBAR: health \"Hit Points (Clamped)\" clamp","/#","^[---]","\n","^:: Custom Range","\n","^Not all stats use 0โ€“100. Set your own min and max:","\n","^`# STATBAR: mana 0 50 \"Magical Energy\"`","\n","#","^STATBAR: mana 0 50 \"Magical Energy\"","/#","^[---]","\n","^:: Opposed Stat Bar","\n","^Two labels create an opposed bar showing both ends of a spectrum. The values show how much you have of each side:","\n","^`# STATBAR: bravery \"Brave\" \"Cowardly\"`","\n","#","^STATBAR: bravery \"Brave\" \"Cowardly\"","/#","^[---]","\n",{"->":".^.statbars_submenu"},{"only_statbars":["^:: Statbars","\n","#","^STATBAR: health \"Hit Points\"","/#","#","^STATBAR: health \"Hit Points (Clamped)\" clamp","/#","#","^STATBAR: mana 0 50 \"Magical Energy\"","/#","#","^STATBAR: bravery \"Brave\" \"Cowardly\"","/#",{"->":".^.^.statbars_submenu"},null],"statbars_submenu":[["ev","str","^Increase health (+20)","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Decrease health (-20)","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Increase mana (+5)","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^Decrease mana (-5)","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Become braver (+15)","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^Become more cowardly (-15)","/str","/ev",{"*":".^.c-5","flg":4},"ev","str","^Back to feature menu","/str","/ev",{"*":".^.c-6","flg":4},{"c-0":["\n","ev",{"VAR?":"health"},20,"+","/ev",{"VAR=":"health","re":true},{"->":".^.^.^.^.only_statbars"},null],"c-1":["\n","ev",{"VAR?":"health"},20,"-","/ev",{"VAR=":"health","re":true},{"->":".^.^.^.^.only_statbars"},null],"c-2":["\n","ev",{"VAR?":"mana"},5,"+","/ev",{"VAR=":"mana","re":true},{"->":".^.^.^.^.only_statbars"},null],"c-3":["\n","ev",{"VAR?":"mana"},5,"-","/ev",{"VAR=":"mana","re":true},{"->":".^.^.^.^.only_statbars"},null],"c-4":["\n","ev",{"VAR?":"bravery"},15,"+","/ev",{"VAR=":"bravery","re":true},{"->":".^.^.^.^.only_statbars"},null],"c-5":["\n","ev",{"VAR?":"bravery"},15,"-","/ev",{"VAR=":"bravery","re":true},{"->":".^.^.^.^.only_statbars"},null],"c-6":["^ ",{"->":"feature_menu"},"\n",null]}],null]}],"styling_demo":["^: Styling & Visual Customization","\n","^The `# CLASS:` tag lets you apply custom CSS classes to any paragraph. Define your styles in `css/custom.css`, then use them in your story.","\n","^:: Custom Classes in Action","\n","^Here's normal text for comparison.","\n","^`# CLASS: dramatic`","\n","#","^CLASS: dramatic","/#","^This text uses the \"dramatic\" class โ€” bold and attention-grabbing!","\n","^`# CLASS: whisper`","\n","#","^CLASS: whisper","/#","^This uses \"whisper\" โ€” perfect for inner thoughts or quiet moments...","\n","^`# CLASS: glowing`","\n","#","^CLASS: glowing","/#","^And this one glows with the \"glowing\" class.","\n","^`# CLASS: old-paper`","\n","#","^CLASS: old-paper","/#","^The \"old-paper\" class is great for letters, journal entries, or ancient texts that need to stand apart from regular narration.","\n","^And now this paragraph is back to normal.","\n","^:: Combining Multiple Classes","\n","^You can stack multiple classes on the same paragraph:","\n","^`# CLASS: dramatic`","\n","^`# CLASS: old-paper`","\n","#","^CSS: dramatic","/#","#","^CSS: old-paper","/#","^This combines both \"dramatic\" and \"old-paper\" for extra emphasis.","\n","^:: How to Use","\n","^In your Ink file, add the tag:","\n","^>> `# CLASS: dramatic`","\n","^Immediately followed by the text where it should be applied:","\n","^>> `The door slammed shut.`","\n","^In `css/custom.css`:","\n","^> `.dramatic { color: red; font-weight: bold; }`","\n","^Aliases: `# CSS:`, `# CSS_CLASS:` and `# STYLE:` work the same way.","\n","^__Note:__ The class only applies to the immediately following paragraph. For multiple styled paragraphs, add the tag before each one. To style all paragraphs globally, override the `p` element in `css/custom.css` instead.","\n","^:: System Commands","\n","^> `# CLEAR` - Clears all text from the screen","\n","^> `# RESTART` - Restarts the story from the beginning","\n",{"->":"feature_menu"},null],"global decl":["ev",0,{"VAR=":"session_start"},1,{"VAR=":"character_level"},"str","^Unnamed Hero","/str",{"VAR=":"hero_name"},50,{"VAR=":"friend_relationship"},{"list":{"inventory.potion":5}},{"VAR=":"inventory"},{"list":{},"origins":["skills"]},{"VAR=":"skills"},50,{"VAR=":"reputation"},75,{"VAR=":"health"},30,{"VAR=":"mana"},50,{"VAR=":"bravery"},"str","^","/str",{"VAR=":"input"},"str","^ john doe ","/str",{"VAR=":"player_name"},"str","^","/str",{"VAR=":"cleaned_name"},"str","^Hello World","/str",{"VAR=":"greeting"},"str","^la la la","/str",{"VAR=":"repeated"},150,{"VAR=":"current_health"},100,{"VAR=":"max_health"},"str","^en-US","/str",{"VAR=":"locale"},0,{"VAR=":"five_years_ago"},0,{"VAR=":"next_week"},"/ev","end",null]}],"listDefs":{"inventory":{"torch":1,"lantern":2,"sword":3,"shield":4,"potion":5},"skills":{"combat":1,"magic":2,"stealth":3,"diplomacy":4}}}