展示 HN:Loreline,一种通过 Haxe 转换的叙事语言:C++/C#/JS/Java/Py/Lua
Show HN: Loreline, narrative language transpiled via Haxe: C++/C#/JS/Java/Py/Lua

原始链接: https://loreline.app/en/docs/technical-overview/

## Loreline:一种叙事脚本语言 – 幕后原理 Loreline旨在弥合创意作家和软件工程师之间的差距,提供一种简单的叙事脚本语言,并具有强大的底层实现。它通过平衡对作家友好的语法和强大的软件架构来实现这一目标。 Loreline主要用Haxe构建,利用**转译**——将代码转换为多种语言(C#、JavaScript、Java等)的单一代码库——确保了跨游戏引擎、Web平台和工具的可移植性。这避免了维护单独的实现,并保证了行为的一致性。 处理流程包括一个**词法分析器**(将文本分解为标记,区分叙事和指令)、一个**解析器**(创建具有稳定ID的抽象语法树 – AST – 以实现可靠的保存状态)和一个**解释器**(通过延续传递风格执行AST,并暂停以供宿主应用程序控制)。 重要的是,Loreline脚本直接从纯文本执行,无需预编译步骤。 跨所有目标语言的全面自动化测试套件确保了稳健性并促进了更新,允许对Haxe源代码的更改无缝传播到所有平台。 本质上,Loreline通过将其高效的多平台核心抽象化,优先考虑作家的体验。

Hacker News 新闻 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 展示 HN: Loreline,通过 Haxe 转换的叙事语言:C++/C#/JS/Java/Py/Lua (loreline.app) 5 分,jeremyfa 1 小时前 | 隐藏 | 过去 | 收藏 | 1 条评论 帮助 jeremyfa 1 小时前 [–] 大家好,我是 Loreline 的作者。我分享了 Loreline 的技术概述,这是一种用于编写互动小说和游戏对话的叙事语言,因为它展示了 Haxe 如何被用于创建可以在许多其他平台上作为库运行的软件。 你可以在这里直接尝试语言语法:https://loreline.app/en/playground/ 并查看代码:https://github.com/jeremyfa/loreline 欢迎提出任何问题/反馈! 回复 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

How does Loreline work under the hood? This article provides some answers, though not everything can be covered in detail here!

A language shaped by two disciplines

Building a narrative scripting language requires two very different skill sets working together.

Screenshot of the Loreline extension for VS Code

On one side, there is narrative language design: the syntax must feel natural to writers, get out of the way of creativity, and provide the right mechanics for expressing narrative intent (branching, variations, characters, state) in a readable and intuitive way.

On the other side, every simplification, every design choice in the language requires real software engineering effort: the fewer symbols the writer has to type, the more the parser needs to understand the intent behind what is written. All of this must work identically across a wide range of platforms and game engines, while also providing editing tools (syntax highlighting, automatic suggestions, real-time diagnostics) that support the writer throughout the process.

Loreline reflects this dual nature at every level. The language looks simple on the surface because the underlying implementation absorbs the complexity so writers do not have to.

Written in Haxe, to transpile them all

Loreline is primarily written in Haxe, a strictly-typed programming language that transpiles to multiple targets from a single codebase.

The principle of transpilation is to convert code from one language to another. Haxe specializes in this type of operation: you can transpile Haxe to many other languages, making the code you write highly portable.

This choice was driven by a core requirement: Loreline needs to run everywhere. Game engines use C#, C++, GDScript, Java, or Lua. Web projects use JavaScript and TypeScript. Tooling scripts might use Python. Rather than maintaining separate implementations that would inevitably diverge and require enormous maintenance effort, Haxe lets the entire interpreter, parser, and runtime be written once, then transpiled and compiled natively for each platform.

The result: one set of tests, one parser, one interpreter, all generating target-specific code that runs with native performance.

Processing pipeline

To be able to play an interactive story, Loreline takes source text as input and transforms it through several stages in order to execute it:

Source TextLexerParserInterpreterAST Interactive Story

Lexer: Turns the source text into tokens. One of its most complex tasks is determining whether a line is narrative text or a language instruction: this is what lets writers write dialogue without explicit delimiters.

Parser: Consumes the token stream and produces an AST (Abstract Syntax Tree) representing the full structure of the script: beats, dialogue, choices, alternatives, conditionals, expressions, and more. Each node receives a unique 64-bit ID encoding its position in the hierarchy, designed to remain stable when the script is modified: a save based on a previous version remains valid even if lines of dialogue are added or removed.

Interpreter: Walks the AST at runtime and calls handler callbacks when dialogue or choices need to be presented. The host application provides these callbacks and controls when execution resumes.

With Loreline, there is no need to "pre-compile" .lor scripts into an intermediate format. The runtime can directly read, parse, and execute a script in plain text. This is a deliberate choice that simplifies integration and opens the door to more varied use cases. The Lexer is particularly optimized for performance, making it entirely viable to load many files on the fly.

Execution model

Interpreter Host Application Display dialogueMake a choiceEnd execution dialoguechoicefinishcontinuechoice number

When the interpreter reaches a dialogue line or a choice point, it pauses and lets the host application (game, web app, tool) decide when to resume. This continuation-passing style (CPS) model works equally well with synchronous and asynchronous callbacks, and integrates naturally into any game loop or event system.

Internally, a stack of runtime scopes tracks the current position in the script, active variables, and nested beats. This stack is what makes precise save and restore of execution state possible at any point.

Compilation targets

Loreline covers a wide range of languages and platforms, thanks to a shared codebase that guarantees identical behavior everywhere.

A thin wrapper layer is added on top of the Haxe-transpiled code, so that Loreline, as a library, feels natural to use in each target language. Someone using the C# or Java version of Loreline does not need to know anything about Haxe. Using Loreline with Godot is done simply with GDScript, etc.

Loreline (Haxe)JavaScript / TypeScriptC#C++PythonLuaJVMJavaScalaKotlinlibGDXiOSAndroidLÖVEGodot / GDScriptUnityWeb / HTML5PC / Mac

This software architecture makes it possible to modify the language (to fix a bug, add an improvement...) simply by changing the Haxe source code, and deploy that change across all targets automatically: this saves a considerable amount of maintenance effort for Loreline over time!

Hundreds of automated tests

To ensure the language's robustness and prevent any regression when it is modified, hundreds of tests are run for each target language (JS, Java, C#, C++, ...) to cover every feature: alternatives, beats, characters, choices, dialogue, expressions, functions, conditionals, imports, insertions, localization, save/restore, state management, syntax, tags, and visit counting.

These tests are crucial to verify that the language behaves correctly, and to confidently build tooling and narratives with Loreline.

Digging deeper

To learn more about how Loreline works, you can also explore its source code on GitHub.

联系我们 contact @ memedata.com