Home

Awesome

Godot Lua PluginScript

<img src="extras/icon.png" alt="Lua PluginScript icon" width="128" height="128"/>

Godot Asset Library Icon Pluginscript Lua

WARNING

This does not work with Godot 4.X, since it relies on GDNative, a Godot 3.X only technology.

GDNative + PluginScript library that adds support for Lua as a scripting language in Godot 3.X

Being a GDNative library, recompiling the engine is not required, so anyone with a built release copied to their project can use it. Being a PluginScript language, Lua can seamlessly communicate with scripts written in GDScript / C# / Visual Script and vice-versa. Since the Godot object model is dynamic at runtime, any Godot objects' properties/methods can be accessed from Lua, including singletons like OS, ClassDB and custom singleton nodes. This way, one can use the language that best suits the implementation for each script and all of them can understand each other.

This plugin is available in the Asset Library as Lua PluginScript.

For some usage examples, check out plugin/lua_repl.lua and plugin/export_plugin.lua.

Currently, only LuaJIT is supported, since the implementation is based on its FFI library.

Installing

Either:

Documentation

Goals

Non-goals

Articles

  1. Designing Godot Lua PluginScript
  2. Implementing the library's skeleton
  3. Integrating LuaJIT and FFI
  4. Initializing and finalizing scripts (TODO)

Script example

This is an example of how a Lua script looks like.

-- Class definitions are regular Lua tables, to be returned from the script
local MyClass = {}

-- Optional: set class as tool, defaults to false
MyClass.is_tool = true

-- Optional: set base class by name, defaults to 'Reference'
MyClass.extends = Node

-- Optional: give your class a name
MyClass.class_name = 'MyClass'

-- Declare signals
MyClass.something_happened = signal()
MyClass.something_happened_with_args = signal("arg1", "arg2")

-- Values defined in table are registered as properties of the class
-- By default, properties are not exported to the editor
MyClass.some_prop = 42

-- The `property` function adds metadata to defined properties,
-- like setter and getter functions
MyClass.some_prop_with_details = property {
  -- ["default_value"] or ["default"] or [1] = property default value
  5,
  -- ["type"] or [2] = variant type, optional, inferred from default value
  -- All Godot variant type names are defined globally as written in
  -- GDScript, like bool, int, float, String, Array, Vector2, etc...
  -- Notice that Lua <= 5.2 does not differentiate integers from float
  -- numbers, so we should always specify `int` where appropriate
  -- or use `int(5)` in the default value instead
  type = int,
  -- ["get"] or ["getter"] = getter function or method name, optional
  get = function(self)
    return self.some_prop_with_details
  end,
  -- ["set"] or ["setter"] = setter function or method name, optional
  set = 'set_some_prop_with_details',
  -- ["usage"] = property usage, from `enum godot_property_usage_flags`
  -- optional, default to `PropertyUsage.NOEDITOR`
  usage = PropertyUsage.NOEDITOR,
  -- ["hint"] = property hint, from `enum godot_property_hint`
  -- optional, default to `PropertyHint.NONE`
  hint = PropertyHint.RANGE,
  -- ["hint_string"] = property hint text, only required for some hints
  hint_string = '1,10',
  -- ["rset_mode"] = property remote set mode, from `enum godot_method_rpc_mode`
  -- optional, default to `RPCMode.DISABLED`
  rset_mode = RPCMode.MASTER,
}
-- The `export` function is an alias for `property` that always exports
-- properties to the editor
MyClass.exported_prop = export { "This property appears in the editor" }
MyClass.another_exported_prop = export {
  [[This one also appears in the editor,
now with a multiline TextArea for edition]],
  hint = PropertyHint.MULTILINE_TEXT,
}

-- Functions defined in table are public methods
function MyClass:_ready()  -- `function t:f(...)` is an alias for `function t.f(self, ...)`
  -- Singletons are available globally
  local os_name = OS:get_name()
  print("MyClass instance is ready! Running on a " .. os_name .. " system")

  -- There is no `onready` keyword like in GDScript
  -- Just get the needed values on `_ready` method
  -- Also, Lua doesn't have the `$child_node` syntax, use `get_node` instead
  self.some_grandchild_node = self:get_node("some/grandchild_node")
end

function MyClass:set_some_prop_with_details(value)
    self.some_prop_with_details = value
    -- Indexing `self` with keys undefined in script will search base
    -- class for methods and properties
    self:emit_signal("something_happened_with_args", "some_prop_with_details", value)
end

function MyClass:get_some_prop_doubled()
  return self.some_prop * 2
end

-- In the end, table with class declaration must be returned from script
return MyClass

Status

Third-party software

This project uses the following software:

Other projects for using Lua in Godot