Erannorth Chronicles – Writing new Events and Stories in Ink Script # Hands on Modding

Erannorth Chronicles – Writing new Events and Stories in Ink Script # Hands on Modding 1 - steamlists.com
Erannorth Chronicles – Writing new Events and Stories in Ink Script # Hands on Modding 1 - steamlists.com

Hi folks! In this guide I’ll introduce you to Inkscript and show you how to use to write your own Erannorth Chronicles events, interactions and quests. Let’s get started!
 
 

Editorial

This guide is for the most part similar to the one I wrote a way back for Erannorth Reborn, but more standalone so you won’t have to reference any of the relevant legacy Reborn guide.
 
 
I will barely be scratching the surface of these systems. But hopefully will get you started understanding more the vanilla ink files, and eventually creating your own.
 
 
Let’s get started!
 
 
 

Overview – What is Ink Script

Ink Script was created by Inkle Studios – [inklestudios.com] , the developers of the amazing interactive fiction games like 80 Days and the Sorcery! Series. But as it happens their framework Ink – [inklestudios.com]  is open source and can be used to write all sort of CYOA stories and also integrated in third party (for them) projects, like Erannorth.
 
 
You can write Ink script the visual editor Inklewriter – [inklewriter.com]  which lets you design your Ink story through an UI editor. Add your choices there, the text outcome, even view everything as a diagram to get a better grasp of how your story flows etc.
 
 
Or in any text editor. Like inky editor – [github.com] , which is my personal favorite.
 
 
Whatever method you choose, to create your Ink files, you can then bring them into your Erannorth mod, and have your story playable in Erannorth. Use them as random events, to add interactions with your allies, enrich challenges with more flavor etc.
 
 
The possibilities of what you can do with this robust framework (added on top of our own) are really endless.
 
 
 

Editors – Writing Ink script

You can write Ink script in any text editor. But if you prefer writing your stories in a ‘What you see is what you get’ editor you can use Inklewriter – [inklewriter.com] .
 
 
Erannorth Chronicles - Writing new Events and Stories in Ink Script # Hands on Modding - Editors - Writing Ink script - 9039575
 
 

 
 
Using the visual editor may tempt to you skip on learning Ink script. But I recommend that you do. Otherwise you may not be able to understand what did go wrong (if something goes wrong), or how you can do the many things the visual editor doesn’t support.
 
 
There is already an excellent guide on Ink itself, so no need to recycle the same things here.
 
 
You can find the full documentation here – [github.com] .
 
 

 
 
If you prefer writing directly in Ink Script, I’d recommend to try Inky – [github.com] . It doesn’t have any bells and whistles, but it’s pretty easy to write your Ink script there, and get error messages if you leave any loose ends, empty knots etc. It more than gets the job done 😉
 
 
 

Integrating your Ink story with Erannorth’s Event system

You wrote a story in Ink. Excellent! And now wonder how you can make it run in Erannorth?
 
 
(Pro Tip: don’t leave that part to the end)
 
 
You’ll need:
 
 
1) A json file in ‘Mod Name’/Tales/ to act as the entry point to your Event.
 
 
That’s not the json compilation of your ink file. We don’t need our Ink files to be exported as jsons. They are compiled on runtime. What we do need is an Erannorth event json file to connect your ink file with our event system.
 
 
Let’s assume that my mod is called “Chronicles of Oakstead”.
 
 
And I want my event to be called ‘A Decayed Corpse’. I need two files:
 
 
A Decayed Corpse.ink
 
A Decayed Corpse.json
 
 
I place my ink file in:
 
Mods/Chronicles of Oakstead/Inklets/A Decayed Corpse.ink
 
 
I place my json file in:
 
Mods/Chronicles of Oakstead/Tales/A Decayed Corpse.json
 
 
Which has these as contents:
 
 
{
 
“ID”:”A Decayed Corpse”,
 
“Requirements”: “”,
 
“Unique”: false,
 
“AutoIncludeInEventNode”: true,
 
“MainGraphic”: “Corpse4”,
 
“Title”: “You find the remains of a dead adventurer”,
 
“Inklet”:”Chronicles of Oakstead/Inklets/A Decayed Corpse”
 
}
 
 
Here we basically just need an ID & the Inklet path and probably a graphic. Optionally we can include it in Random Events or not, make it Unique or have requirements to show up.
 
 
2) Empty & false fields (Requirements,Unique etc.) can be safely ommited. The “Inklet” field is what makes things kick. ‘A Decayed Corpse’ refers to my Ink story .ink file, while Chronicles of Oakstead/Inklets is the folder it’s in (My Mod/Inklets)
 
 
Cleaning that up, for our needs, we could go with:
 
 
{
 
“ID”:”A Decayed Corpse”,
 
“AutoIncludeInEventNode”: true,
 
“MainGraphic”: “Corpse4”,
 
“Title”: “You find the remains of a dead adventurer”,
 
“Inklet”:”Chronicles of Oakstead/Inklets/A Decayed Corpse”
 
}
 
 
With our .json file done. We need a .ink file, which is just a plain text file ending with .ink.
 
 
3) You can create .ink files either in a text editor using a very easy scripting language – [github.com]  or with this visual tool Inklewriter – [inklewriter.com]  but export as ink rather as a json. Their Unity plugin generates different .json files out of the ink files, than the online visual tool.
 
 
This alone will make your Event playable, so you can play the story from start to finish, but of course as is it has no way of interacting with your Character. At this point you should probably want to integrate it further with Erannorth and make your story interact with your Character more.
 
 
 

Hiding Choices, Passing Requirements, Giving Rewards and Triggering Encounters

You can pass rewards, quests states and encounter triggers as tags in Ink script and Erannorth engine will recognize them and treat them accordingly.
 
 

  • You can define rewards, pass quest states, trigger encounters etc. directly inside the inklet as tags [# TAG # TAG # TAG] i.e like so:
     

     
    # Grant:Rewards # XP:4 # AP:-4 # Encounter:Large Spider – Lv 1 # Encounter:Large Spider – Lv 2

  • You can put the above the text or next to the text as per Ink Script syntax
  • To have the tags parsed as Rewards and not as normal tags, we always start with # Grant:Rewards
  • You can use any reward string the vanilla Event system supports. We’ll some of the most popular examples below. And you can always read the vanilla event ink files to see more examples of Ink/Erannorth integration.

 
Basic Rewards
 
 
You can give the following basic rewards:
 
 

  • LP:x, you can give x Level up Points to the PC. ie. LP:1
  • PP:x, you can give x Perk Points to the PC. ie. PP:30
  • AP:x, you can give or take AP from the PC. ie. AP:3
  • HP:x, you can give or take HP from the PC. ie. HP:-5, if their HP drop to 0, they’ll die.
  • Farthings:x, you can give or take Farthings from the PC. ie. Farthings:5
  • Rations:x, you can give or take Rations from the PC. ie. Rations:-1
  • Karma:x, you can increase or reduce Karma by x and use it to track how good or evil is the PC. ie. Karma:3
  • Order:x, you can increase or reduce Order by x and use it to track how lawful or unlawful is the PC. ie. Order:-3
  • [Attribute]:x, you can increase that attribute ie. Strength:2.
  • Expertise[Expertise]:x, you increase that expertise ie. ExpertiseAlchemy:1
  • Cast:[Card Name], you can can cast a specific card. ie. Cast:Curse of Enfeeblement.
  • QuestState[State]:[status] & Influence[Person/Loc]:x (See below).

 
Recipes
 
 
You can make use of the recipe system to allow the player craft things. i.e # Grant:Rewards # Recipe:CRAFT Steel Ingot # XP:6? # AP:-5 # Hours:3
 
 
CRAFT Steel Ingot, is a recipe that is defined in the RecipesDB file.
 
 
Changing the Event Cover according based on a choice
 
 

  • You can change the Background & Main graphic of an Event after the event is created at any time using ChangeCover:Graphic & ChangeBackdrop:Graphic as a ‘Reward’.
  • i.e as an inklet – # Grant:Rewards # ChangeCover:Anticipate
  • i.e as a reward in Event field – ChangeCover:Anticipate
  • Ink Script tag to display images isn’t supported.

 
Displaying stuff about the player in the Ink Story
 
 
You can print out the following game-specific variables in your story and choices:
 

  • name, gender, race, class, location, area, organization, weapon, offhand, armor, cloak
  • Syntax: ‘>ER>variable’ ie. >ER>name – this gets replaced with the PC name once the story executes. etc. These aren’t Ink Script variables so they can’t be used in checks using the Ink language.

 
Hiding Choices, Passing Requirements
 
 
You can check for any of the usual requirements directly in your Ink script and show or not certain choices based on the check outcome. That is in addition to what you can do with Ink itself, and should be used if you want your Story “talk” with your Character.
 

  • Syntax: Choice Text@IF:Requirements
  • ie. * [Talk with the Seer…@IF: AP:10, Race:Human]
  • In the above example * & [] are standard ink script definition of choice, Talk with the Seer… is what the player sees as choice and @IF: AP:10, Race:Human our requirements. The player will see this choice if they are both Human & Have 10 AP at that moment.
  • ie. * [Explore the Dungeon…@IF: Rations:1, QuestStateDungeon Entry:Found] etc.
  • (I added an extra space before AP & Rations because Steam tries to replace them with icons. The correct syntax is without a space there!)
  • If there aren’t any valid choices the ‘Continue’ button is shown instead.

 
Triggering Encounters
 
 

  • You can use Encounter:[Enemies] as a node (in custom stages, challenges, event rewards etc.)
  • i.e # Grant:Rewards # Encounter:Con Artist – Lv 1 # Large Spider – Lv 2, will trigger an Encounter with those two enemies.
  • You can also use factions and wildcards: # EncounterFaction:Order of Flame # Encounter:Order Seeker – Lv 4?, here the Order seeker’s level is 4+.

 
Combat Integration
 

  • Story will resume automatically after triggering an Encounter through Ink Script. The Event UI is hidden and the Encounter text instead appears in a different dialog box. If you end your turn after all enemies are dead the Event UI will reappear again and you can resume the story. Trying to open a different event will tell you it’s not possible and also resume from where you left things in your story.
  • You can (optionally) pass a Victory Text along the rewards that will display after the Event UI reappears with # PassVictoryText:[Text]
  • i.e #PassVictoryText:You wipe the blood from your >ER>weapon and look around…

 
Let’s see a full example:
 
 
== Fight ==
 
You don’t think of it twice. Time is of an essence here.
 
You take the executioner by surprise and disarm him of the torch he is holding.
 
With it you burn the ropes holding the man captive.
 
In the ensuing chaos the mob disperses. That leaves you with the Inquisitor and her squad, who swiftly surround you with swords at the ready.
 
‘I want both heretics in the pyre NOW!’, she screams at her squad. And they zealously charge at you. The man you freed, now armed with the torch, stands to fight by your side.
 
# Grant:Rewards # Order:-1 # ChooseOne:Novice Warlock>>Gentleman Thief>>Gravedigger>>Plague Doctor # EncounterFaction:Order of Flame # Encounter:Order Seeker – Lv 4? # PassVictoryText:’Thanks for saving my life.’, he starts after defeating the Inquisition squad.<br><br>’Mind if I tag along till we leave this accursed place behind us for good?’, he suggests.
 
-> Victory

 
 
Executing Functions
 

  • You can execute some modder exposed ‘function’ using ExecuteFunc:[function], (that’s a different thing fron Ink Script function, and doesn’t interfere with them in any way.)
  • i.e ExecuteFunc: Store:Witch, will open a Witch Store. (I added an extra space before Store because steam tries to replace it with an icon. The correct syntax is without a space there!)
  • i.e ExecuteFunc:Chest, will trigger the Chest function etc.
  • You can execute only one function per choice.
  • Note, that it’s possible to Execute a function that in turn triggers an Event. But be mindful, as it will replace your current event with the one you are calling.

 
LootOne, ChooseOne and StashX
 
 
ChooseOne:[Card]>>[Card]…>>[Card]
 
 
ie. ChooseOne:Novice Warlock>>Gentleman Thief>>Gravedigger>>Plague Doctor, lets the player pick and draw (in your hand) one of these cards out of 4 random options. Unlike the two options below, players don’t get to keep this card.
 
 
LootOne:[Card]>>[Card]…>>[Card]
 
 
ie. LootOne:Novice Warlock>>Gentleman Thief>>Gravedigger>>Plague Doctor, lets the player draft 1 of these cards out of 4 random options. Player can decide if they’ll add this card to their deck, collection or simply draw a temp copy.
 
 
StashX2,3,4:[Card]>>[Card]…>>[Card]
 
 
ie. StashX2:Longsword#Leather Armor#Mace#Order of the Rose Pin, lets the player draft 2 of these cards out of up to 4 random options. (Similar with StashX3 & StashX4)
 
 
Resetting Turns & Reinforcements
 

  • You can reset the Turns Encounter Lasted & Reinforcement Arrived counters as an Event reward using ResetTurns:x, ResetReinforcements:x
  • if you plan on having lots of Encounters in the same node, you should probably reset these before each Encounter.
  • ie. # Grant:Rewards # ResetTurns:0 # ResetReinforcements:0 #Encounter:Random

 
 
 

Quest States, Expertise and Influence

Quest states and Influence can be used to set to and to track if the player have made certain things, across multiple events or stories in the same session. That’s how the game can know that you purchased for example Ravensburg Manor and did the kitchen upgrade.
 
 
Let’s have a quick Primer on these 3 mechanics. Before moving on.
 
 
Quest States
 

  • Modders can define & check quest states to determine if certain events or options can/should appear to the player
  • States are saved in the player’s save file and will persist across sessions/will only reset during an Ascension (or a Redemption)
  • You can Set/Update states using QuestState[State Name]:[State] as Event Reward
  • You can set any string you find convienient as state name & state
  • ie: QuestStateThe Poet and the Pond:Met
  • ie: QuestStateThe Poet and the Pond:Left to Die (This will replace the previous state)
  • ie: QuestStateThe Poet and the Pond Resolution:Left to Die (while this will coexist along with the first state)
  • You can check if a Quest state has reached with the same check:
  • ie: QuestStateThe Poet and the Pond:Met, QuestStateThe Poet and the Pond Resolution:Left to Die (will only return true if the player has both states)

 
Persistent Influence with NPC, Locations or Factions
 

  • You now can check / set the Player’s influence with factions, npcs, locations etc through events
  • This influence is persistent across sessions like quest states & is saved in Player’s save file. Will only resets if the player Ascends or starts a new character.
  • Unlike Quest states though Influence is represented by numerical values. If the value exists it increases or decreases by x. If not is set to x.
  • As Event reward: Influence[Key]:x, will set or increase/decrease Key by x.
  • i.e InfluenceGrysbog:3, could represent Player’s fame in Grysbog and set value at 3. Then the player does something bad there InfluenceGrysbog:-1, new Influence becomes 2. etc.
  • As Event requirement: Influence[Key][Comparison]:x where comparison is <,<=,> & >= or ==
  • i.e InfluenceGrysbog<=-3, will check if Grysbog influence is <= 3

 
Expertise System
 

  • Expertise represents various Skills your Character has and can use during certain Events. For instance to Pick a Lock, Gather Herbs, Survive in a Hostile environment and more. Your Expertise rank determines if you can do something or not, and there are no dice rolls involved. If for example a Lock requires Lock Pick Expertise 3, but you have only 2 then you simply can’t pick it. No matter how hard you try.
  • Expertise is persistent and won’t reset during Ascensions.
  • Expertise can be granted through the Event system using Expertise[Skill Name]:x (or -x), this will set or increase/decrease the player’s Expertise by +/- x.
  • ie. ExpertiseGather Herbs:1, sets (or increases) the player’s Gather Herbs expertise to (by) +1
  • Additionally Expertise can be granted through the Perks system using the same syntax.
  • Expertise can be checked through the Event system using Expertise[Skill Name][OP]:x where OP is one of: >=,>,<=,<,==
  • i.e ExpertiseGather Herbs>=:2, this will return true only if the player has Gather Herbs >= 2.
  • Expertise can also be checked through the OnCasterStatus effect. i.e OnCasterStatusGather Herbs:2, ContingencyEffectInvoke:1

 

So how can we check for them and set them through ink?

 
 
Let’s analyze a bit some parts of the Ravensburg Manor interaction, which you can use as boilerplate to create your own player homes.
 
 
== Headquarters
 
You are in Ravensburg Manor.
 
->HeadquarterChoices

 
 
== HeadquarterChoices ==
 
You consider your next move.
 
+ [(Info) Purchase Ravensburg Manor@IF:Not:QuestStatePurchasedRavensburgManor:true]
 
->PurchaseInfo

 
 
I am using @IF:Not:QuestStatePurchasedRavensburgManor:true to determine if the player has purchased the property. QuestStatePurchasedRavensburgManor:false wouldn’t work because this isn’t really a boolean comparison but a text state. Could have been Not:QuestStatePurchasedRavensburgManor:No the PC Didn’t, for all the engine cares. Not: is used to reverse the result. So If the PC hasn’t this quest state, they didn’t purchased the manor, and they can perhaps purchase it.
 
 
== PurchaseInfo ==
 
Would you like to Purchase Ravensburg Manor?
 
<b>Unlocks:</b> Chambers
 
<b>Cost:</b> 2000 Farthings
 
* [Purchase Ravensburg Manor.@IF:Not:QuestStatePurchasedRavensburgManor:true, Farthings:2000]
 
# Grant:Rewards # QuestStatePurchasedRavensburgManor:true # Farthings:-2000
 
-> HeadquarterChoices
 
+ [(Back) Not now.]
 
-> HeadquarterChoices

 
 
If they purchase the manor then I am setting the QuestStatePurchasedRavensburgManor:true
 
 
+ [(Enter) Private Chambers@IF:QuestStateRavensburgManorChambers:true, QuestStatePurchasedRavensburgManor:true]
 
->ExpansionChambers

 
 
To enter their chambers, they must first purchase it and of course have the chambers upgrade quest state etc./b]
 
 
Similarly I can set and check for Influence. Influence can be used to see if NPCs likes you and even to Unlock settlements or upgrade their merchant tiers. ie.
 
 
* [(Build) Serf Quarter.@IF:Not:QuestStateRavensburgManorSerfs:true, Nobility:3, Farthings:2000]
 
# Grant:Rewards # QuestStateRavensburgManorSerfs:true # Farthings:-2000 # InfluenceRavensburg Manor:195
 
-> HeadquarterChoices

 
 
 

Hands on Example: Overriding the vanilla Draft Event

In this simple example we’ll be overriding the vanilla Draft event. Let’s say we want the option to Draft 60 cards. Because why not? As you can see below that would be mostly a copy/paste change 2 values regardless the text wall below. The take away is this structure:
 
 
Let’s call our mod ‘Draft Override’. We need 2 files:
 
 
Mods/Draft Override/Inklets/Draft.ink
 
Mods/Draft Override/Tales/Draft.json
 
 
Everything else is fluff:
 
 

Draft.ink

 
 
VAR CardsPicked = 0
 
VAR DraftPicks = 0
 
 
-> DraftSetup
 
== DraftSetup ==
 
How many cards do you want to Draft?
 
+ [Draft 20 Cards@IF:MinDeck:0-20]
 
~ DraftPicks = 20
 
-> Start
 
+ [Draft 24 Cards@IF:MinDeck:20-24]
 
~ DraftPicks = 24
 
-> Start
 
+ [Draft 30 Cards@IF:MinDeck:24-30]
 
~ DraftPicks = 30
 
-> Start
 
+ [Draft 36 Cards@IF:MinDeck:30-36]
 
~ DraftPicks = 36
 
-> Start
 
+ [Draft 45 Cards@IF:MinDeck:36-45]
 
~ DraftPicks = 45
 
-> Start
 
+ [Draft 50 Cards@IF:MinDeck:45-50]
 
~ DraftPicks = 50
 
-> Start
 
+ [Draft 55 Cards@IF:MinDeck:50-55]
 
~ DraftPicks = 55
 
-> Start
 
+ [Draft 60 Cards@IF:MinDeck:55-60]
 
~ DraftPicks = 60
 
-> Start

 
+ [Cancel Draft]
 
-> Confirm
 
 
== Start ==
 
Before starting your adventure, you need to Draft your Starting Deck.
 
→ Don’t miss a pick!<br>→ Avoid single use Consumables!<br>→ Especially if you need all {DraftPicks} cards for a valid deck.
 
-> NextPick
 
=== NextPick ===
 
{ CardsPicked < DraftPicks:
 
+ [Pick a Card ({CardsPicked}/{DraftPicks})]
 
Pick your next card…
 
# Grant:Rewards # LootOne:Random Card>>Random Card>>Random Card>>Random Card>>Random Card
 
~ CardsPicked++
 
-> NextPick
 
+ [Cancel Draft]
 
-> Confirm
 
– else:
 
* [Done]
 
All done! You can now start your adventure. Good luck!
 
-> END
 
}
 
 
== Confirm ==
 
This will invalidate your deck! Choose this option only if you want to use the menu to restart!
 
+ [(Resume) I changed my mind!]
 
{ DraftPicks > 0:
 
-> NextPick
 
– else:
 
-> DraftSetup
 
}
 
+ [(Exit Draft) Yes, cancel the draft!]
 
->END
 
 

Draft.json

 
 
{
 
“ID”:”Draft”,
 
“MainGraphic”: “Fate”,
 
“Title”: “Draft your Starting Deck”,
 
“Inklet”:”Draft Override/Inklets/Draft”
 
}
 
 
 

Where to go from here?

If you need more help, jump into our Discord – [discord.gg]  #modding channel! I’ll be happy to help and welcome you, as you embark in your magical modding journey. And of course if you come into any issues, or have suggestions on improving Ink integration, I am all ears 😉
 
 
See you there!
 
 

Written by [ER] Raven

 
 
Hope you enjoy the Guide about Erannorth Chronicles – Writing new Events and Stories in Ink Script # Hands on Modding, if you think we should add extra information or forget something, please let us know via comment below, and we will do our best to fix or update as soon as possible!
 
 


Be the first to comment

Leave a Reply

Your email address will not be published.


*