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>
15 files changed
tree: 2d143b0d694450ddb4b6971247b3bca24b4af452
  1. .github/
  2. .vscode/
  3. build/
  4. cg_renderer/
  5. decoders/
  6. dependencies/
  7. dev/
  8. include/
  9. renderer/
  10. rivinfo/
  11. scripting/
  12. skia/
  13. src/
  14. tests/
  15. utils/
  16. .dockerignore
  17. .gitattributes
  18. .gitignore
  19. .lua-format
  20. .rive_head
  21. .version
  22. Dockerfile
  23. Doxyfile
  24. dummy.cpp
  25. LICENSE
  26. premake5_v2.lua
  27. README.md
  28. runtime.natvis
README.md

Build Status Discord badge Twitter handle

rive-runtime

Rive hero image

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:

  • Loading artboards and their contents from .riv files.
  • Querying state machines from artboards.
  • Mutating the artboard hierarchy (the same mechanism used by state machines) and efficiently solving those changes via Artboard::advance.
  • A state-of-the-art vector renderer for Metal, Vulkan, D3D12, D3D11, and OpenGL/WebGL.
  • An abstract Renderer interface for hooking up an external vector renderer.

Prerequisites

  • A C++17 toolchain:
    • macOS: clang from Xcode Command Line Tools (xcode-select --install).
    • Linux: clang from your distro (e.g. apt install clang).
    • Windows: Visual Studio 2022 with the C++ Clang Compiler for Windows and MSBuild support for LLVM (clang-cl) toolset individual components.
  • git — the build script clones a pinned 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.
  • Platform SDK for the renderer you're targeting:
    • macOS / iOS: Xcode.
    • Windows: Windows SDK (for D3D).
    • Linux: a Vulkan or OpenGL development environment.
    • Vulkan: the Vulkan SDK.

Build

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.

macOS / Linux

git clone https://github.com/rive-app/rive-runtime.git
cd rive-runtime/tests
../build/build_rive.sh release

Windows

git clone https://github.com/rive-app/rive-runtime.git
cd rive-runtime\tests
..\build\build_rive.ps1 release

Common variants

(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.

Build outputs

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.
ArtifactDescription
librive.a / rive.libCore runtime library.
librive_pls_renderer.a / rive_pls_renderer.libGPU renderer.
player / player.exeSample app — loads and renders a .riv file.
out/<config>/goldens, out/<config>/gms, out/<config>/benchTest harness binaries (regression, golden-image, benchmarking).
librive_decoders.a, librive_harfbuzz.a, …Supporting libraries.

Testing

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.

Code formatting

rive-runtime uses clang-format.

  • macOS: brew install clang-format.
  • Windows: already installed if you have the prerequisites — VS 2022's C++ Clang Compiler component ships 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.
  • Linux: install via your distro's package manager (e.g. apt install clang-format).

Memory checks (macOS only)

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.

Disassembly explorer (macOS / Linux)

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"
    }
]