Lua: message dispatching API design for the engine
I am making a Lua API for the engine and wonder how messaging (noscripts can exchange messages by the engine design) API should be exposed.
In C#, it would look like this:
...
class SomeEvent {
public int value;
}
...
Subscribe<SomeEvent>(msg => {
var s = msg.value;
});
...
Dispatcher.Send(new SomeEvent {value = "42"});
...
How should this look in Lua?
The most canonical version seems to be:
...
SomeEvent = {}
SomeEvent.index = SomeEvent
...
subscribe(SomeEvent, function(msg)
local s = msg.value
end)
...
dispatcher:send(setmetatable({value = "42"}, SomeEvent))
...
And its runtime implementation on the binding side is quite convenient.
However, I have two concerns:
1. Assigning the metatable to each message seems boilerplate-heavy. Even if it's moved to the "constructor," it doesn't help much, as many messages will still be created only in a few places.
Moreover, it's unlikely that messages will have any methods, so using metatables doesn't seem very appropriate.
1. To describe engine types and methods, I used Lua Annotations (https://luals.github.io/wiki/annotations/), which is extremely convenient for simulating OOP, allowing the IDE to correctly suggest methods and types, as well as enabling almost complete static analysis of the game code if rules are followed. However, the constructs in the "canonical" style above don't fit into Lua Annotations without boilerplate.
Here's how it looks:
---@generic T
---@param classid `T`
---@param callback fun(msg: T)
function Subscribe(classid, callback)
end
---@param m any
function Send(m)
end
---@class SomeEvent
---@field value string
SomeEvent = {}
SomeEvent.index = SomeEvent
Subscribe('SomeEvent', function (msg)
local s = msg.value
end)
--- Here "value" is outside the IDE analysis
Send(setmetatable({ value = "42"}, SomeEvent))
--- But this works fine, although it's more boilerplate
local a = setmetatable({}, SomeEvent)
a.value = "42"
Send(a)
--- The constructor makes usage cleaner when sending, but sending the same type of message will only happen in a few places. This makes the constructor unnecessary boilerplate.
---@param value string
---@return SomeEvent
function SomeEvent:new(value)
local a = setmetatable({}, SomeEvent)
a.value = value
return a
end
Send(SomeEvent:new("42"))
In general, I see the message system design without crossing into the type system. As boilerplate-free as possible, but support for IDE message dispatching is lost.
SomeEventId = ...
...
subscribe(SomeEventId, function(m)
local s = m.value
end)
...
dispatcher:send(SomeEventId, { value = "42"})
...
Or even this (easier to integrate with the current engine integration code than the previous example):
SomeEventId = ...
...
subscribe({type = SomeEventId }, function(m)
local s = m.value
end)
...
dispatcher:send({type = SomeEventId, value = "42"})
...
Do we even need to pursue type support in the IDE? Or is it enough to just provide suggestions for the engine API itself, and forget about IDE assistance in user code, since Lua programmers generally don't care about such things?
What do you recommend?
https://redd.it/1l7tdmn
@r_lua
I am making a Lua API for the engine and wonder how messaging (noscripts can exchange messages by the engine design) API should be exposed.
In C#, it would look like this:
...
class SomeEvent {
public int value;
}
...
Subscribe<SomeEvent>(msg => {
var s = msg.value;
});
...
Dispatcher.Send(new SomeEvent {value = "42"});
...
How should this look in Lua?
The most canonical version seems to be:
...
SomeEvent = {}
SomeEvent.index = SomeEvent
...
subscribe(SomeEvent, function(msg)
local s = msg.value
end)
...
dispatcher:send(setmetatable({value = "42"}, SomeEvent))
...
And its runtime implementation on the binding side is quite convenient.
However, I have two concerns:
1. Assigning the metatable to each message seems boilerplate-heavy. Even if it's moved to the "constructor," it doesn't help much, as many messages will still be created only in a few places.
Moreover, it's unlikely that messages will have any methods, so using metatables doesn't seem very appropriate.
1. To describe engine types and methods, I used Lua Annotations (https://luals.github.io/wiki/annotations/), which is extremely convenient for simulating OOP, allowing the IDE to correctly suggest methods and types, as well as enabling almost complete static analysis of the game code if rules are followed. However, the constructs in the "canonical" style above don't fit into Lua Annotations without boilerplate.
Here's how it looks:
---@generic T
---@param classid `T`
---@param callback fun(msg: T)
function Subscribe(classid, callback)
end
---@param m any
function Send(m)
end
---@class SomeEvent
---@field value string
SomeEvent = {}
SomeEvent.index = SomeEvent
Subscribe('SomeEvent', function (msg)
local s = msg.value
end)
--- Here "value" is outside the IDE analysis
Send(setmetatable({ value = "42"}, SomeEvent))
--- But this works fine, although it's more boilerplate
local a = setmetatable({}, SomeEvent)
a.value = "42"
Send(a)
--- The constructor makes usage cleaner when sending, but sending the same type of message will only happen in a few places. This makes the constructor unnecessary boilerplate.
---@param value string
---@return SomeEvent
function SomeEvent:new(value)
local a = setmetatable({}, SomeEvent)
a.value = value
return a
end
Send(SomeEvent:new("42"))
In general, I see the message system design without crossing into the type system. As boilerplate-free as possible, but support for IDE message dispatching is lost.
SomeEventId = ...
...
subscribe(SomeEventId, function(m)
local s = m.value
end)
...
dispatcher:send(SomeEventId, { value = "42"})
...
Or even this (easier to integrate with the current engine integration code than the previous example):
SomeEventId = ...
...
subscribe({type = SomeEventId }, function(m)
local s = m.value
end)
...
dispatcher:send({type = SomeEventId, value = "42"})
...
Do we even need to pursue type support in the IDE? Or is it enough to just provide suggestions for the engine API itself, and forget about IDE assistance in user code, since Lua programmers generally don't care about such things?
What do you recommend?
https://redd.it/1l7tdmn
@r_lua
luals.github.io
Lua Language Server | Wiki
Lua Language Server uses the Language Server Protocol to offer a better Lua development experience for your favourite editors.
no, the moon (a love letter to lua)
https://if-not-nil.github.io/no-the-moon/
https://redd.it/1l8zjh9
@r_lua
https://if-not-nil.github.io/no-the-moon/
https://redd.it/1l8zjh9
@r_lua
if-not-nil.github.io
no, the moon | if err != nil
a love letter to lua
What is this error?
Error
library/sti/init.lua:94: STI does not support external Tilesets.
You need to embed all Tilesets.
Traceback
[love "callbacks.lua"\]:228: in function 'handler'
[C\]: in function 'assert'
library/sti/init.lua:94: in function 'init'
library/sti/init.lua:49: in function 'sti'
main.lua:12: in function 'load'
[love "callbacks.lua"\]:136: in function <[love "callbacks.lua"\]:135>
[C\]: in function 'xpcall'
[C\]: in function 'xpcall'
https://redd.it/1l9b0dx
@r_lua
Error
library/sti/init.lua:94: STI does not support external Tilesets.
You need to embed all Tilesets.
Traceback
[love "callbacks.lua"\]:228: in function 'handler'
[C\]: in function 'assert'
library/sti/init.lua:94: in function 'init'
library/sti/init.lua:49: in function 'sti'
main.lua:12: in function 'load'
[love "callbacks.lua"\]:136: in function <[love "callbacks.lua"\]:135>
[C\]: in function 'xpcall'
[C\]: in function 'xpcall'
https://redd.it/1l9b0dx
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
should i learn lua ?
hello there , is it a good idea to start learning lua knowing only python?
https://redd.it/1l9it6j
@r_lua
hello there , is it a good idea to start learning lua knowing only python?
https://redd.it/1l9it6j
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
How do I see what I'm doing? (Coordinates)
No matter who I ask or what I search I get something totally irrelevant or literally nothing I need to write some screen coords but i can't see it so i have to make a wild guess to save close run guess again and just hope I find the right thing
https://redd.it/1l9wufx
@r_lua
No matter who I ask or what I search I get something totally irrelevant or literally nothing I need to write some screen coords but i can't see it so i have to make a wild guess to save close run guess again and just hope I find the right thing
https://redd.it/1l9wufx
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
What and is there a difference between the following?
I am learning lua for love2d, and I am wondering if and if so, what the difference is between writing:
Thank you for your time.
https://redd.it/1lc30tb
@r_lua
I am learning lua for love2d, and I am wondering if and if so, what the difference is between writing:
setmetatable(b, a),a.index = b, anda = b:new(<params>).Thank you for your time.
https://redd.it/1lc30tb
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
Need help rotating one object to look at another object
I have two objects in 3D space, I need a way to find a quaternion to point one objects -Z face towards another.
Each object is represented by a 'Transform' with X, Y and Z information. They also have Vector3 and Quaternion rotation.
The function that I am using to rotate the objects uses Quaternions, so I need it in that format.
I have tried looking elsewhere, but have found nothing that uses Quaternions for this purpose.
For additional context:
This code is part of a modification for the game "Teardown"
There is a function in "Teardown" called "QuatLookAt". this function doesn't work for my purposes since it always expects to be upright
My noscript is a global noscript that pulls transforms from vehicles. this means that the noscripts orientation is different to the orientation of the objects its modifying.
Thus, when the vehicle flips its vertical orientation is the opposite of what the function expects, causing it to break.
Thank you for any help
https://redd.it/1lc9of8
@r_lua
I have two objects in 3D space, I need a way to find a quaternion to point one objects -Z face towards another.
Each object is represented by a 'Transform' with X, Y and Z information. They also have Vector3 and Quaternion rotation.
The function that I am using to rotate the objects uses Quaternions, so I need it in that format.
I have tried looking elsewhere, but have found nothing that uses Quaternions for this purpose.
For additional context:
This code is part of a modification for the game "Teardown"
There is a function in "Teardown" called "QuatLookAt". this function doesn't work for my purposes since it always expects to be upright
My noscript is a global noscript that pulls transforms from vehicles. this means that the noscripts orientation is different to the orientation of the objects its modifying.
Thus, when the vehicle flips its vertical orientation is the opposite of what the function expects, causing it to break.
Thank you for any help
https://redd.it/1lc9of8
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
How to make a lua noscript that activates a key when two other keys are pressed?
I've spent like 5 hours trying to do this and I think I'm out of ideas someone please help.
I'm just trying to make a lua noscript for G Hub where if I hold down right click and my side button then my dpi will go down and then return if one of the buttons is released.
I found this noscript and was trying to add a second button into it but I couldn't get it to work:
function OnEvent(event, gkey, family)
if event == "MOUSEBUTTONPRESSED" and gkey == 2 then
PlayMacro("DPI Down")
elseif event == "MOUSEBUTTONRELEASED" and gkey == 2 then
PlayMacro("DPI Up")
end
end
This noscript works but it only works for the one button - I want to press two mouse buttons to activate the DPI change.
https://redd.it/1lco88w
@r_lua
I've spent like 5 hours trying to do this and I think I'm out of ideas someone please help.
I'm just trying to make a lua noscript for G Hub where if I hold down right click and my side button then my dpi will go down and then return if one of the buttons is released.
I found this noscript and was trying to add a second button into it but I couldn't get it to work:
function OnEvent(event, gkey, family)
if event == "MOUSEBUTTONPRESSED" and gkey == 2 then
PlayMacro("DPI Down")
elseif event == "MOUSEBUTTONRELEASED" and gkey == 2 then
PlayMacro("DPI Up")
end
end
This noscript works but it only works for the one button - I want to press two mouse buttons to activate the DPI change.
https://redd.it/1lco88w
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
Yet Another Lua5.1 UTF8 library
I was writing a parser and found all the UTF8 support libraries for Lua are not up to my very high standards /hj. Sooo... I made my own. https://gitlab.com/cinntoast/lutf8
It's on the larger side after compilation because it includes the whole utf8proc database inside of it, but that's a trade off. For now it's just for iterating and identifying unicode codepoints, but I plan to add the utf8 regex capabilities in the few coming days.
Features (and plans):
\- Identifying properties of codepoints (implemented)
\- Validating utf8 sequences (implemented)
\- Mapping/Casefolding/Decomposing/etc sequences (implemented)
\- Bitwise options for lua5.3+ (implemented)
\- Meta file included for people using sumneko language server (wip)
\- POSIX Regex Patterns (planned)
Note: It's still largely untested, and a WIP
https://redd.it/1ldy89z
@r_lua
I was writing a parser and found all the UTF8 support libraries for Lua are not up to my very high standards /hj. Sooo... I made my own. https://gitlab.com/cinntoast/lutf8
It's on the larger side after compilation because it includes the whole utf8proc database inside of it, but that's a trade off. For now it's just for iterating and identifying unicode codepoints, but I plan to add the utf8 regex capabilities in the few coming days.
Features (and plans):
\- Identifying properties of codepoints (implemented)
\- Validating utf8 sequences (implemented)
\- Mapping/Casefolding/Decomposing/etc sequences (implemented)
\- Bitwise options for lua5.3+ (implemented)
\- Meta file included for people using sumneko language server (wip)
\- POSIX Regex Patterns (planned)
Note: It's still largely untested, and a WIP
https://redd.it/1ldy89z
@r_lua
GitLab
Cinnamon / lutf8 · GitLab
Personal standard - top level expression is =<exp>
How bad of it is me to just use \= as my universal top level expression trick. No one's going to be using _ as variable.
I come from C. We do this hacky shit 24/7. But I wonder how it is by lua standards lol.
https://redd.it/1ldyx8k
@r_lua
How bad of it is me to just use \= as my universal top level expression trick. No one's going to be using _ as variable.
I come from C. We do this hacky shit 24/7. But I wonder how it is by lua standards lol.
https://redd.it/1ldyx8k
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
how to use lua-compat-5.3 in C ?
Hello,
What is the proper way to use lua-compat-5.3 from C ?
I did a
luarocks install compat53
but it seems it only installed Lua part (some
thanks
https://redd.it/1ldywz9
@r_lua
Hello,
What is the proper way to use lua-compat-5.3 from C ?
I did a
luarocks install compat53
but it seems it only installed Lua part (some
.so in luarocks' tree), but no compat-5.3.h anywhere ?thanks
https://redd.it/1ldywz9
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
I'm writing a custom lua interpreter with modified semantics, I need your feedback
I'm currently making a custom lua interpreter, with a few behavioural changes to the language, and would like to get some feedback before I release the interpreter.
The main differences are with how "nil"-s are handled:
* Setting a field to "nil" doesn't delete it. It simply holds the value of "nil"
* Consequently, an array may contain a "nil" value
* Getting a field that doesn't exist throws an error, instead of returning "nil"
* Coroutines are symmetric, but that doesn't matter much, since there will be assymetric coroutines, using the built-in symmetric ones
Of course, treating "nil" as any other value means that we need a "del" function to delete fields of tables, and since getting a field that doesn't exist is an error, we need a "has" function that checks if a table contains a field.
It goes without saying that this will break quite a lot of existing lua code, but my main argument is that each minor release of lua so far has included a lot of breaking changes.
Aditionally, the built-in compiler will have some extended syntax, but the compiler is completely interchangeable, so a basic lua compiler without all the bells and whistles can be used instead.
Still, the syntax features I have implemented (and plan to implement) so far are the following:
**Procedure literals:**
same as function literals, but are declared as `begin statements... end`, and may be used in a parenthesis-less calls - `my_func begin end`
**While-local and if-local:**
allows the condition of a while or an if to be a declaration. The value of the first declared variable will be used as the condition, the rest will be accessible in the body of the statement
local function split_file(path)
if local basename, ext = path:match "^([^%.]+)%.(.-)$" then
return basename, ext;
else
return path, nil;
end
end
**Methods in table literals:**
Self explanatory imho
local obj = {
a = 1,
b = 2,
function test(self) return self.a + self.b end,
}
print(obj:add());
**Template literals:**
Haven't gotten around to it, but something like JS's template literals:
local world = "Josh";
local str = `Hello, ${world}`;
-- Or alternatively
local str = $"Hello, ${world}";
local str2 = $'Hello, ${world}';
local str3 = $[[
This is quite a long string.
Hello, ${world}
]];
Do the syntactical features look ok, and more importantly, are the behavioral changes I have made worth it or should I keep the original lua specifications (or maybe enable my semantics with a special comment, like `--# use strict`?)
I'm open to critique and ideas.
(Also, don't get the impresssion the compiler requires semicolons, I just prefer writting them...)
https://redd.it/1le9x04
@r_lua
I'm currently making a custom lua interpreter, with a few behavioural changes to the language, and would like to get some feedback before I release the interpreter.
The main differences are with how "nil"-s are handled:
* Setting a field to "nil" doesn't delete it. It simply holds the value of "nil"
* Consequently, an array may contain a "nil" value
* Getting a field that doesn't exist throws an error, instead of returning "nil"
* Coroutines are symmetric, but that doesn't matter much, since there will be assymetric coroutines, using the built-in symmetric ones
Of course, treating "nil" as any other value means that we need a "del" function to delete fields of tables, and since getting a field that doesn't exist is an error, we need a "has" function that checks if a table contains a field.
It goes without saying that this will break quite a lot of existing lua code, but my main argument is that each minor release of lua so far has included a lot of breaking changes.
Aditionally, the built-in compiler will have some extended syntax, but the compiler is completely interchangeable, so a basic lua compiler without all the bells and whistles can be used instead.
Still, the syntax features I have implemented (and plan to implement) so far are the following:
**Procedure literals:**
same as function literals, but are declared as `begin statements... end`, and may be used in a parenthesis-less calls - `my_func begin end`
**While-local and if-local:**
allows the condition of a while or an if to be a declaration. The value of the first declared variable will be used as the condition, the rest will be accessible in the body of the statement
local function split_file(path)
if local basename, ext = path:match "^([^%.]+)%.(.-)$" then
return basename, ext;
else
return path, nil;
end
end
**Methods in table literals:**
Self explanatory imho
local obj = {
a = 1,
b = 2,
function test(self) return self.a + self.b end,
}
print(obj:add());
**Template literals:**
Haven't gotten around to it, but something like JS's template literals:
local world = "Josh";
local str = `Hello, ${world}`;
-- Or alternatively
local str = $"Hello, ${world}";
local str2 = $'Hello, ${world}';
local str3 = $[[
This is quite a long string.
Hello, ${world}
]];
Do the syntactical features look ok, and more importantly, are the behavioral changes I have made worth it or should I keep the original lua specifications (or maybe enable my semantics with a special comment, like `--# use strict`?)
I'm open to critique and ideas.
(Also, don't get the impresssion the compiler requires semicolons, I just prefer writting them...)
https://redd.it/1le9x04
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
Bitwise operators in LuaJIT
I'm making a Lua interpreter using LuaJIT (for performance), and would like to know if there's any way to implement bitwise operators to LuaJIT. They're in Lua >=5.3 and would like to know if anybody would make a patch for LuaJIT that implemented these. I know about the
https://redd.it/1lekabq
@r_lua
I'm making a Lua interpreter using LuaJIT (for performance), and would like to know if there's any way to implement bitwise operators to LuaJIT. They're in Lua >=5.3 and would like to know if anybody would make a patch for LuaJIT that implemented these. I know about the
bit library but I don't really like it. I want true bitwise operators. I also want compound operators and the continue statement, and I found this: https://github.com/SnapperTT/lua-luajit-compound-operatorshttps://redd.it/1lekabq
@r_lua
GitHub
GitHub - SnapperTT/lua-luajit-compound-operators: Compound Operators patch for lua/luajit
Compound Operators patch for lua/luajit. Contribute to SnapperTT/lua-luajit-compound-operators development by creating an account on GitHub.
I'm doing this video, can anyone support me?
https://youtu.be/Szfnm\_ZJ980
Here is the link, I'm work so hard for this
https://redd.it/1lf5q20
@r_lua
https://youtu.be/Szfnm\_ZJ980
Here is the link, I'm work so hard for this
https://redd.it/1lf5q20
@r_lua
YouTube
Lua Tutorial - Part 1(in 110 second)
Lua is a lightweight, fast, and embeddable noscripting language created in Brazil in 1993. It was designed to be simple, efficient, and flexible.
Background music: https://youtu.be/FezNgPThD3M?si=mp2HXa-wN-MBZHub
Timestamps:
0:00 Intro
0:03 What is Lua?
0:14…
Background music: https://youtu.be/FezNgPThD3M?si=mp2HXa-wN-MBZHub
Timestamps:
0:00 Intro
0:03 What is Lua?
0:14…
how can i learn luau?
well i want to learn luau to make a roblox game. does anyone know a website that is really good for learning luau?
https://redd.it/1lf89xx
@r_lua
well i want to learn luau to make a roblox game. does anyone know a website that is really good for learning luau?
https://redd.it/1lf89xx
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
Learning Lua from an older version
I'm totally new to Lua or any programming language. I'm trying to learn this language from a YouTube course. Is it ok to learn Lua if the tutor of the course is using an older version and I'm using a more recent one?
https://redd.it/1lffqkb
@r_lua
I'm totally new to Lua or any programming language. I'm trying to learn this language from a YouTube course. Is it ok to learn Lua if the tutor of the course is using an older version and I'm using a more recent one?
https://redd.it/1lffqkb
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
Can someone help me?
Can someone take the time to help me obfuscate this noscript?
There is the link: https://pastefy.app/MgYbfktM/raw
Thank you if you help me 🙏.
https://redd.it/1lfhj9r
@r_lua
Can someone take the time to help me obfuscate this noscript?
There is the link: https://pastefy.app/MgYbfktM/raw
Thank you if you help me 🙏.
https://redd.it/1lfhj9r
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
Can someone help me learn lua?
I'm new to coding and have more or less no idea how to noscript. If anyone could help me it would be greatly appreciated
https://redd.it/1lgpqmv
@r_lua
I'm new to coding and have more or less no idea how to noscript. If anyone could help me it would be greatly appreciated
https://redd.it/1lgpqmv
@r_lua
Reddit
From the lua community on Reddit
Explore this post and more from the lua community
Can someone please help me if they know how the heck I can find this issue with my code for a mod im making for balatro? (the most coding experience i have is Scratch so bear with me lol) Code is below
https://redd.it/1lhlfwy
@r_lua
https://redd.it/1lhlfwy
@r_lua