Skip to content

Advanced lua Integration

Thertzlor edited this page Sep 12, 2026 · 2 revisions

Although Revenant mostly aims at cutting out the need for lua programming, it would be a shame to disadvantage people with lua skills.
The framework offers multiple of ways of integrating custom additions with its general event processing logic.

Accessing the Revenant class inside a Profile

For anyone implementing their own logic within their profiles Revenant exposes a multitude of modules and functions that should help communicating with the logitech lua API and the inner logic of the framework itself.
Accessing Revenant from your profile is easy:
Any external profile is loaded via the loadfile function, injecting the Assignment object as its first parameter. The Revenant class itself is passed as the second parameter, although it is not assigned to a variable in the default profile preset:

-- How the default profile import looks like:
---@type ProfileTemplate, Revenant
local profile = ... 

You might have already noticed that there is a second type definition at the very end of the docstring. To access all Revenant modules and functions with full intellisense simply add a second variable to the assignment:

-- initialization with Revenant class made accessible
---@type ProfileTemplate, Revenant
local profile,rv = ... 

The full power of Revenant is now at your disposal.
All methods and properties exported by Revenant's various modules are documented in the source code, Visual Studio Code with the Lua language server installed will provide comprehensive intellisense.

Activating Developer Mode (For libraries and globals)

By default Profile definitions run in a sandboxed lua context that disables all the built in global variables and functions.
This is done to prevent anyone building profiles without lua knowledge from accidentally referencing a variable, triggering a function or otherwise interacting with lua in a way they did not intend while building the assignment table.
To regain access the profile needs to enable "developer mode" which is accessible through the utils module of the Revenant class:

---@type ProfileTemplate, Revenant
local profile,rv = ... 

rv.utils.developerMode()
-- from THIS point on, the usual global lua libraries and variables can be used.

After invoking this function in the top level of the file, the core lua libraries (that is, to the subset included in Logitech's lua engine) can now be used.

Working with Hooks

The core of Revenant involves intercepting and processing the Logitech button events. A natural way to extend or modify is through hooks which allow you to run your logic just when Revenant triggers its own.

Six types of hooks are provided: onEventHook, onEventHookAsync, onInitHook,onInitHookAsync,onPollHook and onRandom.

All can be accessed through the hooks property of the ProfileTemplate object.

Tip

Only use hooks if you're really need to. Consider if a function for the onEvent hook could be put on a function macro instead.

onEventHook

Define a function that runs every time Revenant receives a non-polling event. Triggers before any macro run and regardless if any macro is assigned for this particular event.

This hook receives three arguments which are identical to the ones received by the Logitech OnEvent function: The type of the event, the number of the key and the family of the device. For more details about those parameters you can consult the Logitech API documentation.

onEventHookAsync

Async version of the onEventHook, for use in cases where the computation could take some time but we don't want to block the execution of any other macros.

onInitHook

Here you can define a function that runs right after the profile has been loaded.
At this point all options and macros have been parsed, inheritance is resolved, polling has just started, but no macro has run yet, not even the start macro.

Note

If you do not plan on modifying Revenant's core functionalities your logic would probably better stored in a Function Macro on the profile's start binding.

onInitHookAsync

Async version of the onInitHook, for use in cases where the computation could take some time but we don't want to block the execution of any other macros.

onPollHook

A function invoked on every poll event. If anything slow or complex runs here, there's risk of slowing down macro execution and general responsiveness, so handle with care.

There is no async version of the onPollHook because the polling itself defines the scheduling logic through which async tasks are managed.

onRandom

This hook is invoked whenever Revenant requests a random number such as for actionVariation and keyVariation The output of this function will be used in place of the generic logic utilizing lua's math.random.
This hook receives no arguments and must return a number between 0 and 1.

Clone this wiki locally