Arcscript interpreters
The arcscript-interpreters repository contains the supported interpreters for Arcscript, the scripting language of Arcweave. They evaluate conditions, update variables, and render Arcscript output in your own applications and game engines.
| Implementation | Runtime | Used by |
|---|---|---|
| TypeScript | ES2022 with browser DOM APIs | The Arcweave app and JavaScript or TypeScript applications |
| C# | .NET 6 | The Unity and Godot Engine plugins |
| C++ | C++17 and CMake 3.10 or newer | The Unreal Engine plugin and other native applications |
Each implementation's folder contains a guide with setup instructions, API examples, and tests.
The interpreters are built using ANTLR 4, a parser generator for reading, processing, executing, or translating structured text or binary files.
Why a parser generator?
In order to support updating game data from Arcweave that uses Arcscript during runtime in game engines, we had to find a way to interpret it without having to rebuild the game. This led us to use a parser generator. ANTLR 4 is a great option for that, since it can create parsers for multiple languages from the same grammar, including C++ (which we use for Unreal), C# (for Unity and Godot), and TypeScript (for our frontend).
Our implementation
In the grammar folder, you can find the files ArcscriptLexer.g4 and ArcscriptParser.g4, the grammar files for the lexer and the parser, respectively.
Script input
The interpreters read Arcscript as HTML, the way Arcweave stores it. Each Arcscript segment is a <pre><code>…</code></pre> block, as in element content and connection labels in the Arcweave JSON:
<pre><code>health -= 10</code></pre>
<pre><code>show(health)</code></pre>Branch condition scripts are stored without this wrapper. Wrap a condition's script in <pre><code> and </code></pre> before you run it; the interpreter then returns the condition's boolean result.
Generate parsers
Parser generation regenerates the TypeScript, C#, and C++ ANTLR sources from the shared grammar. It is separate from building and testing each interpreter.
Prerequisites:
- Java 11 or newer, to run the ANTLR tool
- Python 3
curlon Linux and macOS, ifantlr4.jarisn't in the repository root yet- PowerShell on Windows
From the repository root, run generate.sh on Linux or macOS:
sh generate.shOn Windows, run generate.ps1:
.\generate.ps1The script:
- Downloads the
antlr4.jarfile, if it isn't already present. - Generates the parsers for each language.
To build and test an interpreter, follow the guide in its folder.
Variable scopes and runtime state
All three interpreters support global variables and variables backed by String Field, Boolean, Integer, or Float board/component attributes:
health = 100
castle.health = 10
hero.health = 20Unqualified names resolve global variables only. A qualified name uses the owning board or component custom ID as its scope and the attribute custom ID as its member name.
Runtime integrations keep the mutable current value separate from the project-authored default. This allows reset and resetAll to restore the original value after any number of interpreter calls. Stable Arcweave variable or attribute IDs identify changes and reset exclusions even when different scopes use the same member name.
When updating an interpreter integration:
- C# project models (
IProjectimplementations) must provide a component collection.GetAllVariables()enumerates the global, board, and component variables. - C++ consumers must use the current
UVariableheader, marshal both current and default values, and rebuild their native libraries because the scoped-variable update changes the ABI. - Null or missing runtime values are rejected instead of being treated as valid variable state.
TypeScript
We are using the TypeScript interpreter to interpret Arcscript in our Arcweave app. It is also available as the @arcweave/arcscript package, built from the generated files in the TypeScript folder, along with a custom ANTLR visitor that interprets the parse tree.
npm install @arcweave/arcscriptThe package uses browser DOM APIs, including document and DOMParser. In Node.js, provide a compatible DOM implementation.
import { Interpreter } from '@arcweave/arcscript';
const interpreter = new Interpreter({
state: {
health: {
id: 'health',
name: 'health',
type: 'integer',
defaultValue: 100,
},
},
});
const { changes, output } = interpreter.runScript(
'<pre><code>health -= 10</code></pre><pre><code>show(health)</code></pre>'
);
// changes: { health: 90 }
// output: '<p>90</p>'The state object is keyed by variable ID, and changes reports new values by variable ID. Add a scope to a variable for board and component variables. For persisting values between runs, conditions, and error handling, see the TypeScript guide.
C# & C++
The C# interpreter's entry point is AwInterpreter, which runs scripts against an Arcweave project model. The C++ interpreter provides the Arcweave::ArcscriptTranspiler class for C++ applications, and runScriptExport() for integrations that load the shared library. Both return rendered output and variable changes keyed by stable variable ID.
For setup and examples, see the C# guide and the C++ guide.