API Changes

  • Added Property::getOwningLogicNode to query which logic node the propery belongs to

  • Added Property::getIncomingLink, Property::getOutogingLinksCount and Property::getOutogingLink to query which properties are linked to it

  • Added LogicEngine::getPropertyLinks to collect and retrieve all existing links between properties

  • Added static LogicEngine::GetFeatureLevelFromBuffer which can parse a rlogic data buffer and detect its feature level without having to instantiate LogicEngine first.

General Changes

  • ramses-logic-viewer: added --exec-lua cli to execute lua code (after the lua configuration file was executed)

  • ramses-logic-viewer: added --headless cli to run the viewer without renderer and display (e.g. in CI environments)


General Changes

  • Upgrade ramses from 27.0.119 to 27.0.121 (patchfix)

  • LuaInterface will not fail to be created if it does not have a unique name anymore, however validation (LogicEngine::validate) will produce warning if two or more interfaces share same name

  • ramses-logic-viewer: improved command line interface

    • new --help message and error handling

    • renamed --multi-sample to --msaa

    • added --write-config option to save default lua configuration

    • added --log-level-console option. Enable error log level by default

API Changes

  • Added new constructor for LogicEngine where a feature level can be specified, see LogicEngine::LogicEngine(EFeatureLevel) and EFeatureLevel for details

  • Added static LogicEngine::GetFeatureLevelFromFile which can parse a rlogic file and detect its feature level without having to instantiate LogicEngine first.


  • ramses-logic-viewer: use 1-based indices for accessing children of Array properties in lua configuration (previous versions used 0-based indices)

  • ramses-logic-viewer: fixed content of default lua configuration file


  • Added new Feature Level 02 with following features:

    • Added rlogic::AnchorPoint to help tracking a 3D node in 2D coordinates

    • Added rlogic::RamsesRenderPassBinding allowing control of ramses::RenderPass states from logic nodes

    • Added ‘enabled’ input property to RamsesNodeBinding to be able to control also 3rd state of Ramses Node visibility mode to turn it Off (in addition to Visible/Invisible).

    • Lua scripts and modules are serialized as pre-compiled binaries instead of source code.

    • Added LogicEngine::createRamsesCameraBindingWithFrustumPlanes which allows also perspective camera binding to have a full set of frustum planes properties


General Changes

  • ramses-logic-viewer: added support for lua interfaces

API Changes

  • Added rlogic::Property::hasIncomingLink()

  • Added rlogic::Property::hasOutgoingLink()


  • Remove subtle behavior differences in Lua script between Debug/Release builds

  • Fixed API documentation for rlogic::Property::isLinked()

  • ramses-logic-viewer: fixed property access in lua configuration file



  • Fixes more crashes with large interface objects

  • Produces CMake error if compiled with Clang++ < 10.0.0 (older versions don’t support C++17 fully)



  • Fixes exotic crash when creating complex nested interfaces

  • LuaInterface objects can be retrieved via LogicEngine::findByName, LogicEngine::findLogicObjectById and can be cast using LogicObject::as()

  • Fixed assert when logging a script error which contains curly braces conflicting with internal Fmt formatter


General changes

  • Version bump to 1.0!

    • From now on, any API, ABI or content-breaking change will result in major version bumps

    • New APIs or non-breaking features will result in minor version bumps

    • Binary file compatibility is explicitly documented in, as before

  • Not backwards compatible

    • Binary files need re-export

  • Updated Ramses to 27.0.119

    • Fixes bugs

    • Adds custom logger


  • Objects created after loading from binary data/file will also receive unique id’s

  • Can’t overwrite the IN and OUT globals in the interface() function any more

  • RamsesLogic::saveToFile produces the same file content when called twice

  • Mismatching rotation conventions don’t cause warnings any more if the rotation values are (0, 0, 0)

  • Modules cost less memory in binary files

  • Bindings are not dirty unless their inputs changed. Fixed wrong warning associated to that.

  • Reading and writing global variables in modules now reports a verbose error

API Changes

  • !!BREAKING Lua syntax!! Reworked Lua type system

    • See LuaScript docs for details

    • Replaces “TYPENAME” (all uppercase) with “Type:TypeName()” (in camel case), e.g., “INT32” becomes “Type:Int32()”

    • We provide a Python migration script you can use to update existing content (tools/migration/

    • Int is only available as Int32 or Int64, have to select bit-ness explicitly now (previous INT corresponds to Int32)

    • IN and OUT global varaibles are now passed as params to run() and interface() functions

      • IN and OUT are not reserved keywords anymore and do not carry special semantics

      • Params declared in run() and interface() functions do not have to be called IN and OUT, but they can be. Most importantly the order needs to be maintained, i.e., the 1st param represents inputs and the 2nd param represents outputs

      • root properties (returned by LogicNode::getInputs/getOutputs) have empty names now, instead of “IN”/”OUT”

  • Possible to create multidimensional arrays, e.g. “IN.matrix3d = Type:Array(3, Type:Array(3, Type:Float()))” will create a 3x3 float matrix

  • ErrorData holds an enum to distinguish the type of errors

    • Use this to handle specific errors, e.g. file operations or Lua runtime errors, differently

  • Majorly simplified AnimationNode control interface

    • Removed ‘timeDelta’, ‘play’, ‘loop’, ‘rewindOnStop’, ‘timeRange’ inputs and ‘progress’ output

    • Instead the animation is now controlled directly by setting its progress via new input ‘progress’

    • Removed AnimationNode::getDuration and added new ‘duration’ output property instead (due to this channel outputs are shifted by 1 if accessed by index!)

    • Removed ‘timeDelta’ output from TimerNode as the time delta concept is not used on rlogic level, but can be done fully on application side if desired (due to this ticker_us output is shifted by 1 if accessed by index!)

    • Added a new example which demonstrates how to implement an ‘animateTo’ functionality using Lua script (8b_dynamic_animation)

  • Added LogicEngine::createLuaInterface

    • Creates a LuaInterface object based on Lua script that implements only “interface” function, and defines only IN variables.

    • More information can be found in the API docs

    • Interfaces have to have a non-empty and unique name

    • LogicNode::setName() can fail now if the node is a LuaInterface - can’t change the name of interface objects

    • An interface with unlinked outputs issues a warning on validation

  • If validation is enabled and warnings were found, saveToFile will not write files

    • Override with FileSaveConfig::setValidationEnabled(false) (see section below about LogicEngine::validate())


  • Added LogicEngine::validate() which collects content warnings and reports them as a list of WarningData

    • By default, saveToFile performs validation and issues warning logs for each issue

    • This behavior can be altered by calling FileSaveConfig::setValidationEnabled(bool)

  • Added possibility to assign and retrieve user IDs to any logic object, see LogicObject::setUserId and LogicObject::getUserId



  • Multiple features, bugfixes and more strict sandboxing

  • New Ramses (27.0.116)

  • Not backwards compatible

    • binary files need re-export


  • Added possibility to modify AnimationNode timestamps and keyframes on the fly

    • See AnimationNodeConfig::setExposingOfChannelDataAsProperties which exposes the channel data as node properties which can be set or linked as any other logic node properties.

  • Can optionally supply asset metadata when saving content


  • Type definitions declared in modules also work when the data is not wrapped in a function (example from docs works now)

    • Fixes

  • Catches error correctly when returning any value from the main Lua script source code

  • Fixed memory leak when re-creating LuaScripts (previously, creating above 1000 scripts caused Lua stack overflow)

  • Correctly catches writing of global variables everywhere except when using the dedicated GLOBAL table

    • This may break existing Lua code which relied on the lack of checks!

    • Global variable access will be also caught and causes errors - use this to fix such assets

  • Correctly catches error when declaring any function other than the predefined ones (init, interface, run)

    • Use syntax like ‘GLOBAL.myFunc = function () … end’ inside the init() function to declare global functions

    • Declaring functions twice will result in error

  • Improves quality of error messages related to sandbox violations

  • Nodes linked to TimerNode’s timeDelta will now be always updated (also when timeDelta stays constant)

API Changes

  • Added AnimationNodeConfig which has to be used when creating AnimationNode (LogicEngine::createAnimationNode)

    • Animation channels are now provided to the config first, where also their validity is checked


Fully compatible to Logic Engine 0.14.0.


  • Weak links - ability to form a cycle in node dependency graph, see LogicEngine::linkWeak.

  • Updates inline Ramses version to 27.0.115 (fully backwards compatible)


Fully compatible to Logic Engine 0.14.0.


  • Prebuilt packages for Windows and Debian available with each release from now on


  • Package generation for Debian works correctly



  • Fixed clang-tidy jobs for older clang-tidy versions

  • File compatible, but ABI-incompatible to v0.13.0

API Changes

  • [[nodiscard]] properly applied to pure const API getters


  • Logic engine viewer supports TimerNodes

  • Added LogicEngine::setStatisticsLoggingRate and LogicEngine::setStatisticsLogLevel which periodically logs statistics about updated nodes.


  • Improved error message when assigning structs with less than required number of fields

  • Fixed potential stack overflow problem when assigning large structs

  • Reading VECxF and VECxI values from modules works (was broken in 0.13.0 because of read-only protection)



  • Major performance improvement for large scenes with lots of links alongside few bugfixes

  • New Ramses (27.0.114)

  • Not backwards compatible

    • binary files need re-export

API Changes

  • Removed LuaScript::overrideLuaPrint

    • Logic engine has better means for debugging since this was introduced

    • Overriding built-in Lua print was a security threat and also violated sandboxing

    • If you still want to get string data out of scripts, just create a string property and read it out

  • Can’t modify module data any more (this was a technical debt which was fixed in this release)

  • Added a built-in methods to make it easier to work with custom types from C++

    • ‘rl_len’ to get the size of ramses logic built-in types and modules from inside Lua

    • ‘rl_next’ to create and increment stateless iterators for custom types similar to standard next()

    • ‘rl_pairs’ and ‘rl_ipairs’ to iterate custom types similar to standard pairs() and ipairs()

    • See the Lua docs for more info

  • Added unique (in the scope of one Logic Engine) and immutable Logic Object Id that will be automatically assigned on object creation. *Object Ids start at 1 and are counted upwards for new objects.

  • Added convenience method LogicEngine::findLogicObjectById(id) to find object with id regardless of its type

  • Added LogicEngineReport, LogicEngine::enableUpdateReport, LogicEngine::getLastUpdateReport which collects statistics about updated nodes.

  • Added PropertyEnumToType traits to be able to obtain a C++ data type of a property (inverse of EPropertyTypeToEnum)

  • Added TimerNode which is a new logic node to handle timing information for AnimationNode and scripts

  • All LogicEngine collection getters and finders were replaced with templated versions:

    • LogicEngine::scripts() -> LogicEngine::getCollection LogicEngine::ramsesNodeBindings() -> LogicEngine::getCollection() …

    • LogicEngine::findScript(name) -> LogicEngine::findByName(name) LogicEngine::findNodeBinding(name) -> LogicEngine::findByName(name) …


  • Added EPropertyType::Int64 (INT64 in Lua) property type to represent 64bit signed integer in logic network

    • Also added INT32 Lua interface property which is equivalent to INT (INT is kept and act as alias for INT32)

  • Animation begin and end can be modified by setting AnimationNode ‘timeRange’ input property.

  • Added Update Report (statistics about updated nodes) to ramses-logic-viewer

  • Large scenes with many links now don’t cause unnecessary CPU usage when input data didn’t change

  • Link updates are generally faster after major rework of link handling


  • Fixed bug where ramses bindings re-applied their values to ramses when linked, even though the value didn’t change

  • It’s now possible to access array elements by index in interface()

  • Improved error messages when converting numeric types. Errors now contain info why the conversion failed, i.e. because of numeric rounding, silent truncation, negative numbers etc.. Also works for arrays and VECx types

  • Fixed bug in the viewer program where default settings were not exported correctly

  • Property::isLinked() works for outputs too, not just inputs

  • Linking/unlinking errors contain more useful information


API Changes

  • Re-implemented Lua environment sandboxing

    • This is a safety feature which was temporarily reverted to allow usage of global variables

    • This version reintroduces it - there are now better alternatives:

    • Docs for new behavior: see Lua docs


  • Added a new tool - a viewer binary which can load, show and configure binary ramses/logic scenes

    • For more info, read the docs



  • Global variables can now be declared in a new function init() in Lua scripts using the GLOBAL table

    • See docs or example for more info and exact usage


  • Logic also builds a Ramses renderer now

    • Builds a default renderer for the host system

    • Affected by setting -Dramses-logic_PLATFORM

    • Can still build custom Ramses and inject as target, or find from system

    • See build docs for more details and options

  • Added Iterator and collection for LogicObjects to LogicEngine

  • Added convenience method LogicEngine::findLogicObject(name) to find object with name regardless of its type

  • Added convenience method LogicObject::as that returns the logic object cast to given concrete type

  • Updates Ramses to 27.0.113



  • Updates Ramses to 27.0.112



  • Restore access to global data from the interface() function

    • This was a hardening measure which turned out to be breaking user projects

    • Will be re-introduced after we have added proper support for global variables


API Changes

  • Added LuaModule that can be used to load Lua source code to be shared in one or more Lua scripts

    • LogicEngine::createLuaScriptFromSource and LogicEngine::createLuaScriptFromFile have new optional argument to provide list of module dependencies and access alias for each of them

    • Modules can use other modules recursively

  • Reworked API for creating scripts (accepts an optional configuration object which can be used to refer to modules)

    • Old API methods (createLuaScriptFromSource and createLuaScriptFromFile) are not available any more

    • New API createLuaScript accepts Lua source code, and optionally configuration object and a name

    • File handling is expected to be performed outside the Logic Engine

      • Rationale: text file loading is not considered a core functionality of the logic engine

    • Also removed corresponding LuaScript::getFilename() method

    • Standard modules must be loaded explicitly via the LuaConfig object

      • When loading older binary files, standard modules are implicitly loaded for compatibility

      • New code should request standard modules explicitly and only where needed


  • Property::isLinked() is correctly exported in the shared library

  • LogicEngine move constructor and assignment are correctly exported in the shared library


Summary: update Ramses to version 27.0.111


  • Node scaling is applied before rotation in Ramses now (see Ramses 27.0.111 changelog)

    • Attention: if your nodes combine scaling and rotations, upgrade to Ramses 27.0.111 in your runtime or use the built-in ramses shipped with v0.9.1. Otherwise the scene may look wrong!



  • New major feature (Animations)

  • Not backwards compatible

    • binary files need re-export

    • minimal API changes (see note on RamsesNodeBinding below)

  • More small fixes and quality of life changes

API Changes

  • Added AnimationNode, a logic node that can animate properties

    • Added new entity DataArray for storage of various types of immutable data arrays used in AnimationNode

  • RamsesNodeBinding accepts a new enum value which configures how rotations should work

    • Supports multiple Euler angle conventions (a subset of the ones offered by Ramses)

    • Has an option for Quaternion. In this case, the ‘rotation’ property input is of type vec4f, not vec3f

    • Rotation convention is statically configured in RamsesNodeBinding and can’t be changed dynamically any more

    • Rotation values in RamsesNodeBinding are imported from the bound Ramses node if the conventions match, otherwise initialized with zero and a warning is issued. Quaternions are always initialized with zero

    • Default rotation convention is Euler XYZ rotation (corresponds to ramses::ERotationConvention::ZYX)

  • Added a base class LogicObject for all rlogic objects that can be created from LogicEngine

    • ErrorData now holds pointer to LogicObject, not LogicNode, so that more errors can be reported with pointer to the error object


  • LogicEngine can be move constructed and move assigned using std::move semantics now

  • Added the function Property::hasChild that checks whether the Property has a child with the given name

  • Can check if property input is linked to an output (new method Property::isLinked)


  • Improve error message when trying to assign individual components of Lua script output vector types (VEC3F etc.)



  • Internal Release


API Changes

  • Fixed constness of LogicEngine::find* methods


  • Allow file compatibility loading, i.e. loading binary file exported with v0.7.0 using runtime v0.8.0

  • Added missing size() method for object collections

  • Update ramses to 27.0.110


  • Numeric checks are applied correctly to primitive types (FLOAT, INT)

  • Sol Lua numeric safeties are always active (also in non-debug builds). This ensures consistent behavior for user

  • Can’t access ARRAY() from within the run() method in Lua anymore

  • Can’t access global symbols from the interface() function anymore (this blocks the implementation of modules)



  • Struct properties from Lua are now sorted in ascending lexicographic order

  • Loading from file or buffer data handles most error cases gracefully, and handles more error cases

    • Ramses object type mismatches after loading result in errors

    • Appearances must be from the same base effect after loading

    • Corrupted data results in graceful errors, not in crashes and undefined behavior

Breaking changes

  • Ramses Bindings are now statically attached to their Ramses object

    • Ramses object is provided as reference during construction of the binding

    • Can’t be changed or set to nullptr

    • Fixes bug when ramses object was re-set and links were not automatically removed (can not happen now by design)

    • Binding input values are initialized with the values from the bound ramses object (all except appearance)

    • See reworked documentation for more details

  • Renamed Camera binding inputs to have shorter names

    • See class docs for new names

    • Reason: shorter strings are faster to resolve and easier to read

  • Bindings receive their input values from Ramses (after construction and after loading from file/memory)

    • This is more consistent and eliminates data race conditions

  • New serialization format (must re-export binary files to use this version of the logic engine)

    • This is a preparation for the first LTS version of the logic engine (API, ABI and file format)



  • Invalid access to properties generate error logs in addition to returning ‘false’ and ‘nullopt’

  • Update ramses to 27.0.105


  • Setting an input value in Lua results in error, instead of triggering an assert



  • All numeric errors are hard-checked, except rounding of double to float. Added a section in the Lua user docs with details

  • Update ramses to 27.0.103


  • Fix conversion of very large numbers to int32 when crossing the Lua to C boundary (used to clamp them wrongly)

  • Correctly catch and report error when setting negative or zero camera viewport sizes to RamsesCameraBindings


This release contains minor API improvements and a new feature (RamsesCameraBinding), which requires a change in the serialization format. Therefore it is not API and binary compatible with 0.5.3!


  • [API break!] Log message types are consistent with those of Ramses and DLT. Existing ones are the same (but camel-case instead of upper case). New log levels added (Off, Fatal, Debug and Trace)

  • Update ramses to 27.0.102

  • Add RamsesCameraBinding to control RamsesCamera

  • Setting output and linked input Properties with Property::set<T> is now treated as an error

  • [API breaking!] LogicEngine::getErrors() returns a vector of structs holding additional error information.


  • Fix exotic bug where loading from file/buffer silently ignores ramses objects with mismatched types



  • Possible to load from memory buffer instead of file

  • Bindings’ name is empty string by default

  • Upgrade ramses to 27.0.101

  • Possible to rename objects after their creation


  • LogicEngine::loadFromFile() and loadFromBuffer() check for data corruption by default (possible to disable)

  • LogicEngine::saveToFile() fails if target is a folder; loadFromFile() does not crash when giving folder as a path



  • Upgraded Ramses that ships with the logic engine from 27.0.5 to 27.0.100 (backwards compatible)


This version is API-compatible to v0.4.2, but the file-format is not backwards compatible. Please re-export all binary content when switching to v0.5.0!


  • Upgraded Ramses that ships with the logic engine from 27.0.2 to 27.0.5 (backwards compatible)

  • Added support for the ‘#’ operator on non-primitive properties. Semantics is same as for Lua tables - returns the number of elements in the array/struct. Also works for vec2/3/4 (returns 2/3/4)

  • RamsesAppearanceBinding supports uniform arrays

  • Possible to set log verbosity to dynamically adjust how much is being logged

  • Added convenience methods find<Object>(name) in LogicEngine

  • Can set rotation convention on RamsesNodeBinding. Default is still euler XYZ.

  • RamsesNodeBinding’s visibility and scaling inputs have the same values like Ramses after initialization

  • Possible to build with ramses renderer

Semantic changes

  • Changed behavior of RamsesBinding. See binding docs for details. See data flow docs for general overview how data flow works in the logic engine.


  • LogicEngine::saveToFile() correctly reports error if two or more different Ramses scenes are being referenced by binding objects

  • Logic engine crashes no more when nodes with nested links (script, array) are destroyed

  • LogicEngine::unlink() will correctly report error when called with non-primitive properties

  • LogicEngine::isLinked() returns consistent results for nested links (any link, also nested, will cause a node to be reported as linked)

  • Fixed a bug where LogicNode update order was not correctly adjusted when removing and adding links to its properties

  • Reports error when a cycle of links is created (update() and saveToFile() will fail until the cycle is resolved)



  • Added benchmarks for basic functionality. Enabled when unit tests are enabled, works based on google-benchmark. To run them, execute the benchmarks executable after having built the project in release mode for maximum accuracy.


  • Fixed an exotic bug related to links and deserialization. Used to trigger when deserializing twice from file which had links.

  • Does not wrongly create array properties out of GLSL uniforms arrays in RamsesAppearanceBinding. Array feature not supported there yet!

  • Does not wrongly create LogicNode inputs out of semantic uniforms in RamsesAppearanceBinding.




  • Fix bug which broke links created between complex data objects


  • Added missing error reporting when trying to link arrays directly


  • Added new dependency: google benchmarks, a library for benchmarking


New Features

  • Support arrays of complex types

  • Added more logging

  • Upgrade Ramses to v27.0.2

    • Uses correct rotation semantics fixed in Ramses 27.0.1

    • Currently hardcoded right-handed XYZ Euler rotation (same as Blender default)


  • Added [[nodiscard]] attribute to API methods where it makes sense, mostly getter Methods This will trigger compiler warnings if you call these methods but don’t use the result

  • New CMake option ‘ramses-logic_FOLDER_PREFIX’ to set custom folder prefix for MSVS

  • Restructured folders for easier source redistributions. See docs for more info



  • Fixed a bug which caused a crash when unlinking and destroying nodes

  • Upgrade ramses from 26.0.4 -> 26.0.6 (fixes important resource creation bug)


  • Property::set<T> and Property::get<T> trigger a static assert when used with the wrong type T

  • Add a few debug logs, mainly aimed at debugging if/when logic nodes are updated based on their input changes (only published on custom logger)

  • Errors are now also logged in the order of their appearance, both in console logger and in custom logger


  • Updated googletest to a newer version (fixes some clang-tidy issues)


New Features

  • Optimization to only execute LogicNodes with changed inputs

  • Support arrays of primitives


  • Const-iterators can be initialized from non-const iterators


  • Check Ramses version during build time to ensure compatibility

  • loadFromFile() checks ramses version for compability

  • Lua Scripts have all standard Lua modules by default (see docs for details)

  • Currently supports ramses >= 26.0.4 and < 27

Build system

  • Provides version info as CMake Cache variable

  • Fails build if ramses version is not compatible



  • Fixed a bug with recent sol and Visual Studio 16.7.4

    • Only a workaround, until properly fixed in sol + MSVS

    • Results in minor mismatch in reported errors when using VECx types

    • Errors are still readable and have a stack trace, just the message is different


  • Improved class hierarchy:

    • All binding-classes inherit from RamsesBinding

    • Scripts and RamsesBinding inherit from LogicNode

    • Can call destroy(LogicNode&) for all object types now

  • RamsesAppearanceBinding class for manipulation of RAMSES appearances.

  • Linking of outputs of LogicNodes to inputs of other LogicNodes, with some limitations:

    • No checks for cycles yet

    • Must link struct properties one-by-one

    • Some error checks missing (see API docs of link())

    • LogicNode has “isLinked” function for checking if a LogicNode is linked

  • Iterators and collections to iterate over objects of LogicEngine class

  • Saving and loading of LogicEngine to and from files

  • Upgrade to Ramses v.26.0.4 (from v25.0.6)

  • Added API to obtain version of ramses logic

  • Added CMake option to disable installation of Ramses Logic

    • Does not affect ramses installation (Ramses has no such option yet)

    • Sol doesn’t support disabling of installation - Sol headers are still installed

  • Improved documentation


  • Remove flatbuffers targets from build


First version published on Github

Initial features

  • Script loading and execution

  • Script input/output access from C++

  • Supported property types: bool, string, float, integers, vec[2|3|4][f|i]

  • Basic debugging support

    • error handling support with full lua stack information and human-readable error descriptions

    • override print() method in Lua

    • default logger with different log levels

    • option to override default logging with custom logger

  • RamsesNodeBindings to control ramses node properties (visibility, transformation)


RamsesNodeBindings still can’t be linked to script outputs, this feature is coming soon

  • Code examples with description of API usage and semantics

  • Documentation based on sphinx

  • Possible to build as a static and dynamic library

  • Possible to install, package, or build standalone using CMake

  • Embeddable to other projects via CMake add_subdirectory()