feat(rasc): document the AnimaScript std and close its gaps with the Luau API (#14524) b80a7fc662 * fix(rasc): one static closure per plain function so references compare equal, and reject a second operator per symbol * feat(runtime): wasm host ops for transitions, path effect nodes, pointer stamps, artboard paths and gamepads, and test blobs * feat(rasc): document std/rive with /// and close its gaps with the Luau API * fix(scripting): Luau docs and declarations match the runtime, translator color setters and path effect nodes * feat(scripting_workspace): /// docs in AnimaScript hovers and the API docs generator * docs(cli): regenerate the Luau API bundle from the corrected builtins * fix(runtime): bound gamepad payload counts one at a time so they cannot wrap * docs(rasc): fence AnimaScript examples as as, with the grammar registered under that alias * docs(cli): animascript protocols guide and generated std api reference * feat(scripting_workspace): translate Transition, Mat4 and every string.format specifier to AnimaScript * docs(cli): regenerate the AnimaScript API bundle with as fences * feat(lsp): completion items carry kind, signature and docs for Luau and AnimaScript * fix(rasc): print floats with schubfach shortest digits and drop formatNumber's exact search * feat(rasc): infer type arguments from a callback's return and parameter types * docs(cli): regenerate the AnimaScript API bundle for the promise docs * fix(rasc): class errors reach the real sink from peeks and callback annotations, duplicate operators report once in source spelling * fix(rasc): a callback's own type never binds a type parameter positionally, and the hint names parameter annotations when only they would bind it * refactor(rasc): static closures share one empty closure class * perf(rasc): call umul128 instead of inlining it eight times into schubfach * fix(wasm): scope path effect nodes to their update and wire the shim's artboard ops * refactor(rasc): drop Pattern.match and captures, gsub copies text in runs * fix(rasc): unwatched properties leave their owner so listen cycles stop growing * fix(rasc): saturate buffer and date integer conversions like Luau, trim buffer allocations * fix(rasc): keep host composed geometry when a path is released * perf(rasc): skip bounds checks on fixed Mat4 entries * fix(rasc): raise Luau's GPU constructor argument errors instead of a silent null handle * fix(rasc): match Luau's Vector lerp and normalized bit for bit * test(cli): GPUBuffer data length guard on both lanes * refactor(cli): share the api bundle writer between the Luau and AnimaScript generators * fix(cli): keep operator[]= and generic defaults in the AnimaScript api bundle * docs(cli): note AnimaScript gamepad indices are 0 based * ci: test the AnimaScript bundle generator and run rive-cli checks on std changes * fix(scripting): document a Luau completion or hover only from the --- block directly above it * perf(scripting): fill Luau completion details only for the entries the filter keeps * fix(lsp): badge types as structs, enum values as enum members and overloads as methods * fix(scripting): keep a one line enum's values from inheriting the enum's /// comment * docs(scripting): AnimaScript API overview, module Functions pages, member anchors and no unsafe in signatures * ci: check the AnimaScript bundle publishes what the site reference does * docs(cli): regenerate both api bundles after the review fixes * refactor(rasc): spell our std and fixture nullable types T?, with ?. and ?? where clearer * fix(scripting_workspace): emit and document nullable types as T? * test(lsp): completion after ?. carries the member's docs * docs(cli): regenerate the AnimaScript api bundle for T? Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>

Rive's C++ runtime — the lowest-level Rive runtime. Loads .riv files, advances state machines and animations, and draws via the abstract Renderer interface. The built-in GPU renderer (RiveRenderer) has RenderContextImpl backends for Metal, Vulkan, D3D11, D3D12, and OpenGL/WebGL.
Rive's Apple, Android, Flutter, Unity, Unreal, and web runtimes all wrap this library.
Features:
.riv files.Artboard::advance.Renderer interface for hooking up an external vector renderer.xcode-select --install).apt install clang).premake5 on first run. On Windows, install Git for Windows and during setup pick “Use Git and optional Unix tools from the Command Prompt” so that sh.exe ends up on PATH.The build is driven by premake5 wrapped by a helper script:
build/build_rive.sh — macOS / Linux (bash) / Windows (MinGW).build/build_rive.ps1 — a PowerShell convenience wrapper for Windows; it shells out to the bash script, so a bash environment (Git for Windows / MinGW, see Prerequisites) must still be on PATH.The helper self-installs the pinned premake version on first run and dispatches to the right build system for your platform (gmake2 on macOS/Linux, MSBuild on Windows). It must be run from a directory that contains a premake5.lua — typically tests/, which builds the core library, the GPU renderer, and the player sample app.
git clone https://github.com/rive-app/rive-runtime.git cd rive-runtime/tests ../build/build_rive.sh release
git clone https://github.com/rive-app/rive-runtime.git cd rive-runtime\tests ..\build\build_rive.ps1 release
(On Windows, substitute build_rive.ps1 for build_rive.sh.)
build_rive.sh (no args) — debug build for the host.build_rive.sh release clean — clean then build release.build_rive.sh ninja release — use Ninja instead of make/MSBuild.build_rive.sh ios release — cross-compile for iOS.build_rive.sh android release — cross-compile for Android (defaults to arm64).build_rive.sh ninja release wasm — cross-compile for WebAssembly.build_rive.sh --toolset=msc release (Windows) — build with MSVC's cl.exe instead of clang-cl. The build supports both toolchains; the lua warning suppressions cover MSVC too.See the comment header at the top of build/build_rive.sh for the complete flag reference.
Artifacts land in out/<config>/ relative to the directory you built from (typically tests/). The config directory encodes any OS/arch flags you passed:
out/release, out/debug — host build.out/ios_release, out/android_arm64_release, out/wasm_release — cross-compile builds.| Artifact | Description |
|---|---|
librive.a / rive.lib | Core runtime library. |
librive_pls_renderer.a / rive_pls_renderer.lib | GPU renderer. |
player / player.exe | Sample app — loads and renders a .riv file. |
out/<config>/goldens, out/<config>/gms, out/<config>/bench | Test harness binaries (regression, golden-image, benchmarking). |
librive_decoders.a, librive_harfbuzz.a, … | Supporting libraries. |
The runtime's primary form of testing is golden testing — rendering known scenes and diffing the output against checked-in reference images via the goldens and gms test harness binaries (built into out/<config>/goldens and out/<config>/gms). See tests/ for how to run and rebaseline goldens.
Unit tests are secondary and use the Catch2 framework. From the repo root:
cd tests/unit_tests ./test.sh
Unit tests live in tests/unit_tests/runtime/ (core runtime) and tests/unit_tests/renderer/ (renderer). To add a test, create an xxx_test.cpp file in the appropriate directory — the harness picks it up automatically.
rive-runtime uses clang-format.
brew install clang-format.clang-format.exe alongside clang-cl.exe at C:\Program Files\Microsoft Visual Studio\2022\<edition>\VC\Tools\Llvm\x64\bin\. You can also install LLVM standalone from llvm.org or via winget install LLVM.LLVM.apt install clang-format).To run the tests under macOS's built-in leaks tool:
cd tests/unit_tests ./test.sh memory
This wraps the test binary with leaks --atExit, which ships with macOS — no install required. The memory flag is ignored on Linux and Windows.
To inspect generated assembly per cpp file, install the Disassembly Explorer VSCode extension. A disassemble task is provided in .vscode/tasks.json. The underlying gen assembly task invokes clang++ directly, so it needs clang++ on PATH — works out of the box on macOS (Xcode CLI tools) and most Linux distros, but not on a default Windows + VS install (which provides clang-cl.exe, not clang++.exe).
Reach the task from Tasks: Run Task, or bind a key in keybindings.json:
[ { "key": "cmd+d", "command": "workbench.action.tasks.runTask", "args": "disassemble" } ]