So for the past several months I’ve been sketching out, and eventually working on, a language and runtime meant to essentially implement StoryNexus-like semantics but in a more flexible way (where “flexible” means “you can run it in more different scenarios”). I’m building this mainly for my own use, but even so it’s useful to do so in the open and share what I’m doing, so this is the first I’m talking publicly about it; a proper public release will come down Soon (ie, this year).
I have a long blog post with proper details. But in short, lyre is…
- Narrative middleware in the vein of Ink or Yarn, not necessarily a full script-to-game authoring system;
- Designed to be easy to port to different environments, but currently exists as a compiler, a reference javascript runtime, and a GDScript runtime;
- Designed for quality-based narratives: storylets as the central type of narrative node, all state and state changes can be made visible to the player, stories can grow organically (ie, you can add more material and make it accessible from existing material without having to explicitly change old material to hook it up; branches can be created from the place they point to);
- Heavily influenced by StoryNexus, but designed with more elegant semantics and for a broader range of use cases;
- Aimed at solving different problems from the ones Ink or Yarn are meant to solve
- Very much an opinionated thing that exists to satisfy the specific shape of my brain, but I think those kinds of tools are often very interesting to people other than their creator
- Yes, obviously, written without the use of LLMs, while that’s still legal
I really have no idea how useful this will ever be to people who are not me or how much interest there even is in a system like this. But I’m already using lyre to write something relatively substantial.[1] And I think getting some early impressions might be useful in helping shape the language going forward.
Here’s a little sample of what the language looks like; more in the blog post, along with more explanatory comments.
storylet anchor start "Forest Clearing"
"""
You stand before a crossroads that splits to the left and right. A man
stands next to the path on the right, wearing a large black velvet cloak.
{
if scarf_color then
// You can even nest interpolated text inside other interpolated text.
`Your { scarf_color } scarf is reassuringly warm.`
else
"You are wearing a warm scarf." }
"""
branch "Examine your scarf"
"""
What color was it again?
"""
show ( scarf_color == "" )
-> select_scarf_color
branch "Talk to the man"
"""
He looks *trustworthy.*
"""
req ( social_anxiety < 7 )
-> conversation
/* ... */
quality cloak_knowledge: boolean "Examined the Cloak"
"""
You've taken a closer look at the Cloak of Darkness.
"""
describe_change: () => "You add your observations to your mind palace."
Though expect it to be much shorter than Kinophobia—which to be fair was a six hour game. ↩︎





