All Versions
Latest Version
Avg Release Cycle
54 days
Latest Release

Changelog History
Page 1

  • v1.12.0 Changes

    Net features


    • Engine::call_fn_raw is deprecated in favor of Engine::call_fn_with_options which allows setting options for the function call.
    • The options are for future-proofing the API.
    • In this version, it gains the ability to set the value of the custom state (accessible via NativeCallContext::tag) for a function evaluation, overriding Engine::set_default_tag.

    โœจ Enhancements

    • CallableFunction is exported under internals.
    • The TypeBuilder type and CustomType trait are no longer marked as volatile.
    • FuncArgs is also implemented for arrays.
    • Engine::set_XXX API can now be chained.
  • v1.11.0 Changes

    Speed improvements

    • ๐Ÿ”จ Due to a code refactor, built-in operators for standard types now run even faster, in certain cases by 20-30%.

    ๐Ÿ› Bug fixes

    • ๐Ÿ“œ Engine::parse_json now returns an error on unquoted keys to be consistent with JSON specifications.
    • import statements inside eval no longer cause errors in subsequent code.
    • Functions marked global in imported modules with no alias names now work properly.
    • ๐Ÿšš Incorrect loop optimizations that are too aggressive (e.g. unrolling a do { ... } until true with a break statement inside) and cause crashes are removed.
    • Dynamic::is now works properly for shared values.

    ๐Ÿ’ฅ Breaking changes

    • ๐Ÿ—„ NativeCallContext::new is completely deprecated and unimplemented (always panics) in favor of new API's.

    ๐Ÿ†• New features

    Dynamic detection API

    • New methods are added to Dynamic in the form of is_XXX() where XXX is a type (e.g. is_int, is_unit, is_bool, is_array).
    • This new API is to make it easier to detect the data type, instead of having to call is::<XXX>().

    Loop expressions

    • Loops (such as loop, do, while and for) can now act as expressions, with the break statement returning an optional value.
    • Normal loops return () as the value.
    • ๐Ÿ‘ Loop expressions can be enabled/disabled via Engine::set_allow_loop_expressions

    Static hashing

    • ๐Ÿ‘€ It is now possible to specify a fixed seed for use with the ahash hasher, via a static function rhai::config::hashing::set_ahash_seed or an environment variable (RHAI_AHASH_SEED), in order to force static (i.e. deterministic) hashes for function signatures.
    • This is necessary when using Rhai across shared-library boundaries.
    • A build script is used to extract the environment variable (RHAI_AHASH_SEED, if any) and splice it into the source code before compilation.

    no_time for no timestamps

    • ๐Ÿ‘ A new feature, no_time, is added to disable support for timestamps.
    • ๐Ÿ— This may be necessary when building for architectures without time support, such as raw WASM.

    Serializable Scope

    • Scope is now serializable and deserializable via serde.

    Store and recreate NativeCallContext

    • A convenient API is added to store a NativeCallContext into a new NativeCallContextStore type.
    • This allows a NativeCallContext to be stored and recreated later on.

    Call native Rust functions in NativeCallContext

    • NativeCallContext::call_native_fn is added to call registered native Rust functions only.
    • NativeCallContext::call_native_fn_raw is added as the advanced version.
    • This is often desirable as Rust functions typically do not want a similar-named scripted function to hijack the process -- which will cause brittleness.

    Custom syntax improvements

    • The look-ahead symbol for custom syntax now renders a string literal in quotes (instead of the generic term string).
    • ๐Ÿ“œ This facilitates more accurate parsing by separating strings and identifiers.

    Limits API

    • Methods returning maximum limits (e.g. Engine::max_string_len) are now available even under unchecked.
    • This helps avoid the proliferation of unnecessary feature flags in third-party library code.

    โœจ Enhancements

    • ๐Ÿ“œ parse_json function is added to parse a JSON string into an object map.
    • Error::ErrorNonPureMethodCallOnConstant is added which is raised when a non-pure method is called on a constant value.
  • v1.10.1 Changes

    ๐Ÿ› Bug fixes

    • Compiling on 32-bit architectures no longer cause a compilation error.
    • ๐Ÿ›  Fix type-size test for 32-bit architectures without the decimal feature.

    Custom syntax with state

    • [Engine::register_custom_syntax_with_state_raw] is added. The custom syntax parser and implementation functions take on an additional parameter that holds a user-defined custom state which should substantially simplify writing some custom parsers.
    • [Engine::register_custom_syntax_raw] is deprecated.
  • v1.10.0 Changes

    This version introduces Fast Operators mode, which is turned on by default but can be disabled via a new options API: Engine::set_fast_operators.

    Fast Operators mode assumes that none of Rhai's built-in operators for standard data types are overloaded by user-registered functions. In the vast majority of cases this should be so (really, who overloads the + operator for integers anyway?).

    This assumption allows the Engine to avoid checking for overloads for every single operator call. This usually results in substantial speed improvements, especially for expressions.

    Minimum Rust Version

    The minimum Rust version is now 1.61.0 in order to use some const generics.

    ๐Ÿ› Bug fixes

    • API for registering property getters/setters and indexers to an Engine now works with functions that take a first parameter of NativeCallContext.
    • Missing API function Module::set_getter_setter_fn is added.
    • To avoid subtle errors, simple optimization is used for rhai-run; previous it was full optimization.

    ๐Ÿ—„ Deprecated API

    • All versions of the Engine::register_XXX_result API that register a function returning Result<T, Box<EvalAltResult>> are now deprecated. The regular, non-result versions handle all functions correctly.

    ๐Ÿ†• New features

    Fast operators

    • 0๏ธโƒฃ A new option Engine::fast_operators is introduced (default to true) to enable/disable Fast Operators mode.

    Fallible type iterators

    • For very special needs, the ability to register fallible type iterators is added.


    • if-expressions are allowed in Engine::eval_expression and Engine::compile_expression provided that both statement blocks each contain at most a single expression.
    • switch-expressions are allowed in Engine::eval_expression and Engine::compile_expression provided that match actions are expressions only.

    โœจ Enhancements

    • is_empty method is added to arrays, BLOB's, object maps, strings and ranges.
    • StaticModuleResolver now stores the path in the module's id field.
    • Engine::module_resolver is added to grant access to the Engine's module resolver.
    • Constants and variables now have types in generated definition files.
  • v1.9.1 Changes

    ๐Ÿ›  This is a bug-fix version that fixes a bug.

    Accessing properties in Strict Variables Mode no longer generates a variable not found error.

  • v1.9.0 Changes

    The minimum Rust version is now 1.60.0 in order to use the dep: syntax for dependencies.

    ๐Ÿ› Bug fixes

    • โšก๏ธ switch cases with conditions that evaluate to constant () no longer optimize to false (should raise a type error during runtime).
    • ๐Ÿ›  Fixes concatenation of BLOB's and strings, where the BLOB's should be interpreted as UTF-8 encoded strings.
    • Capturing an unknown variable in a closure no longer panics.
    • ๐Ÿ›  Fixes panic in interpolated strings with constant expressions.
    • Using call_fn_raw on a function without evaluating the AST no longer panics on namespace-qualified function calls due to import statements not run.
    • ๐Ÿ›  Some reserved tokens (such as "?", "++") cannot be used in custom syntax; this is now fixed.

    ๐Ÿ’ฅ Breaking changes

    • The first closure passed to Engine::register_debugger now takes a single parameter which is a reference to the current Engine.

    ๐Ÿ†• New features

    ๐Ÿ†• New feature flags

    • 0๏ธโƒฃ A new feature flag, std, which is enabled by default, is added due to requirements from dependency crates.
    • A new feature flag, no_custom_syntax, is added to remove custom syntax support from Rhai for applications that do not require it (which should be most).

    ๐Ÿ“š Module documentation

    • ๐Ÿ“š Comment lines beginning with //! (requires the metadata feature) are now collected as the script file's module documentation.
    • ๐Ÿ“š AST and Module have methods to access and manipulate documentation.

    Output definition files

    • ๐Ÿ”ง An API is added to automatically generate definition files from a fully-configured Engine, for use with the Rhai Language Server.

    Short-hand to function pointers

    • Using a script-defined function's name (in place of a variable) implicitly creates a function pointer to the function.

    Top-level functions

    • Crate-level functions rhai::eval, rhai::run, rhai::eval_file, rhai::run_file are added as convenient wrappers.

    CustomType trait and TypeBuilder

    • ๐Ÿ— A new volatile API, Engine::build_type, enables registration of the entire API of a custom type in one go, provided that the custom type implements the CustomType trait (which uses TypeBuilder to register the API functions).

    ๐Ÿ“ฆ Simpler Package API

    • It is now easier to register packages via the Package::register_into_engine and Package::register_into_engine_as API.
    • ๐Ÿ“ฆ Defining a custom package with base packages is also much easier with a new syntax - put the new base packages after a colon.

    โœจ Enhancements

    switch statement

    • switch cases can now include multiple values separated by |.
    • Duplicated switch cases are now allowed.
    • ๐Ÿ‘€ The error ParseErrorType::DuplicatedSwitchCase is deprecated.
    • Ranges in switch statements that are small (currently no more than 16 items) are unrolled if possible.


    • EvalContext::eval_expression_tree_raw and Expression::eval_with_context_raw are added to allow for not rewinding the Scope at the end of a statements block.
    • A new range function variant that takes an exclusive range with a step.
    • as_string is added to BLOB's to convert it into a string by interpreting it as a UTF-8 byte stream.
    • FnAccess::is_private, FnAccess::is_public, FnNamespace::is_module_namespace and FnNameSpace::is_global_namespace are added for convenience.
    • ๐Ÿ“‡ Iterator<Item=T> type for functions metadata is simplified to Iterator<T>.
    • ๐Ÿšš Scope::remove is added to remove a variable from a Scope, returning its value.
    • The code base is cleaner by running it through Clippy.
    • ๐Ÿ‘€ ParseError::err_type and ParseError::position are added for convenience.
    • The source of an AST compiled from a script file is set to the file's path.
    • |> and <| are now reserved symbols.
  • v1.8.0 Changes

    ๐Ÿ› Bug fixes

    • Self-contained AST now works properly with Engine::call_fn.
    • Missing to_int from Decimal is added.
    • ๐Ÿ“œ Parsing of index expressions is relaxed and many cases no longer result in an index-type error to allow for custom indexers.
    • ๐Ÿ”€ Merging or combining a self-contained AST into another AST now works properly.
    • ๐Ÿ”Œ Plugin modules/functions no longer generate errors under #![deny(missing_docs)].
    • Calling a property on a function call that returns a shared value no longer causes an error.
    • Strict Variables Mode now checks for module namespaces within functions as well.
    • Module defined via Engine::register_static_module are now checked in Strict Variables Mode.

    Reserved Symbols

    • ?, ??, ?., ?[ and !. are now reserved symbols.

    ๐Ÿ—„ Deprecated API's

    • ๐Ÿ—„ FnPtr::num_curried is deprecated in favor of FnPtr::curry().len().

    ๐Ÿ†• New features

    • The Elvis operators (?. and ?[) are now supported for property access, method calls and indexing.
    • The null-coalescing operator (??) is now supported to short-circuit () values.

    โœจ Enhancements

    • Indexing and property access are now faster.
    • EvalAltResult::IndexNotFound is added to aid in raising errors for indexers.
    • ๐Ÿท Engine::def_tag, Engine::def_tag_mut and Engine::set_tag are added to manage a default value for the custom evaluation state, accessible via EvalState::tag() (which is the same as NativeCallContext::tag()).
    • Originally, the debugger's custom state uses the same state as EvalState::tag() (which is the same as NativeCallContext::tag()). It is now split into its own variable accessible under Debugger::state().
    • Non-borrowed string keys can now be deserialized for object maps via serde.
    • Scope::get is added to get a reference to a variable's value.
    • Variable resolvers can now return a shared value which can be mutated.
  • v1.7.0 Changes

    ๐Ÿ› Bug fixes

    • Compound assignments now work properly with indexers.
    • Cloning a Scope no longer turns all constants to mutable.

    Script-breaking changes

    • Strict Variables Mode no longer returns an error when an undeclared variable matches a variable/constant in the provided external Scope.

    Potentially breaking API changes

    • The Engine::on_var and Engine::on_parse_token API's are now marked unstable/volatile.
    • The closures passed to Engine::on_var, Engine::on_def_var and Engine::register_debugger take EvalContext instead of &EvalContext or &mut EvalContext.
    • ๐Ÿ“‡ The following enum's are marked non_exhaustive: AccessMode, FnAccess, FnNamespace, FnMetadata, OptimizationLevel

    ๐Ÿ†• New API

    • Module::eval_ast_as_new_raw is made public as a low-level API.
    • format_map_as_json is provided globally, which is the same as to_json for object maps.
    • Engine::call_fn_raw_raw is added to add speed to repeated function calls.
    • Engine::eval_statements_raw is added to evaluate a sequence of statements.

    ๐Ÿ†• New features

    • A custom state is provided that is persistent during the entire evaluation run. This custom state is a Dynamic, which can hold any data, and can be accessed by the host via EvalContext::tag, EvalContext::tag_mut, NativeCallContext::tag and GlobalRuntimeState.tag.

    โœจ Enhancements

    • ๐Ÿ“œ Improper switch case condition syntax is now caught at parse time.
    • ๐Ÿ“œ Engine::parse_json now natively handles nested JSON inputs (using a token remap filter) without needing to replace { with #{.
    • ๐Ÿ‘ to_json is added to object maps to cheaply convert it to JSON format (() is mapped to null, all other data types must be supported by JSON)
    • FileModuleResolver now accepts a custom Scope to provide constants for optimization.
    • ๐Ÿ†• New variants, Start and End, are added to DebuggerEvent triggered at the start/end of script evaluation.
  • v1.6.1 Changes

    ๐Ÿ› Bug fixes

    • Functions with Dynamic parameters now work in qualified calls from imported modules.
    • rhai-repl now compiles with the new patch version of rustyline.
    • rhai_codegen dependency is now explicitly 1.4 or higher.

    Script-breaking changes

    • split now splits a string by whitespaces instead of splitting it into individual characters. This is more in line with common practices.
    • A new function to_chars for strings is added to split the string into individual characters.

    โœจ Enhancements

    • Strings are now directly iterable (via for .. in) yielding individual characters.
  • v1.6.0 Changes

    ๐Ÿ”Œ This version, in particular, fixes a plugin macro hygiene error for the nightly compiler:

    error[E0425]: cannot find value `args` in this scope

    Compiler version

    • Minimum compiler version is now 1.57 due to smartstring dependency.

    ๐Ÿ› Bug fixes

    • ๐Ÿ›  Fixed macro hygiene error with nightly compiler.
    • Invalid property or method access such as a.b::c.d or a.b::func() no longer panics but properly returns a syntax error.
    • Scope::is_constant now returns the correct value.
    • Exporting a variable that contains a local function pointer (including anonymous function or closure) now raises a runtime error.
    • Full optimization is now skipped for method calls.

    ๐Ÿ†• New features

    • ๐Ÿ”Œ Type aliases in plugin modules are now used as friendly names for custom types. This makes plugin modules more self-contained when they are used to define a custom type's API.

    โœจ Enhancements

    • โšก๏ธ Variable definitions are optimized so that shadowed variables are reused as much as possible to reduce memory consumption.
    • FnAccess and FnNamespace now implement Ord and PartialOrd.
    • ๐Ÿ– The event_handler_map example is enhanced to prevent shadowing of the state object map.
    • ๐ŸŽ Separation of constants in function calls is removed as its performance benefit is dubious.
    • A function sleep is added to block the current thread by a specified number of seconds.
    • Scope::set_alias is added to export a variable under a particular alias name.
    • starts_with and ends_with are added for strings.
    • Variables in modules registered via register_global_module can now be accessed in the global namespace.
    • Dynamic::into_read_only is added to convert a Dynamic value into constant.
    • Module now holds a collection of custom types with an API.