Lua gamedev libraries
There are great libraries of gamedev focused Lua functions:
Lume:
Knife:
Lua gamedev libraries
There are great libraries of gamedev focused Lua functions:
Lume:
Knife:
Defold Github repos
If you want to find people who already contributed to Defold and made a lot of libraries and extensions, hereâs the github topic:
small tip:
upper and lower cases donât work in Lua with cyrillic characters, so instead of :upper
of Lua to use the method utf8.upper
from extension defold-utf8 made by @d954mas (same with lower
case)
Weighted random.
Usage:
local items_and_weights = {
weapon = 2,
armour = 1,
health = 3,
money = 7
}
local loot_items = weighted_random(items_and_weights, 2)
--> { 'money', 'health' }
local loot_item = weighted_random(items_and_weights)
--> 'weapon'
Code:
local function shallow_copy(orig) -- or your own shallow copying function
local copy = { }
for key, value in pairs(orig) do
copy[key] = value
end
return copy
end
local function random(x, y) -- or your own random function
math.randomseed(os.clock() * 10000000)
_ = math.random()
_ = math.random()
_ = math.random()
if x and y then
return math.random(x, y)
else
return math.random()
end
end
local function weighted_random(weights, results_count)
local results_count = results_count or 1
local weights = shallow_copy(weights)
local results = { }
for _ = 1, results_count do
local pool = { }
for key, weight in pairs(weights) do
for _ = 1, weight do
table.insert(pool, key)
end
end
local index = math.random(1, #pool)
local result = pool[index]
table.insert(results, result)
weights[result] = nil
end
return #results > 1 and results or results[1]
end
You can also require lume.lua for similar method:
When working with sprite cursor animations it can be useful to know what frame is showing by range in normalized cursor values.
Code:
local function frames_to_cursor_range(total_frames)
local frame = 1 ; local max = total_frames ; local min = 0.0
for i = frame, max, 1 do
local range_min = ((frame - 1) - min) / (max - min) + 0.001
local range_max = (frame - min) / (max - min)
if i == 1 then
range_min = 0.000
end
print("Frame_"..i.." Range( start:"..string.format("%.3f",range_min).." , end:"..string.format("%.3f",range_max),")")
frame = frame + 1
end
end
Usage:
12 total frames of sprite animation would print.
frames_to_cursor_range(12)
As pre-hashing is highly recommended, instead of defining local variables for hashed values, you can utilize an amazingly clever solution by @sergey.lerg:
local hashed = require('hashed')
print(hashed.hello_world)
print(hashed.any_compatible_string)
print(hashed['any string with any characters'])
If you require it in one script, you can use the same values everywhere, so it is very convenient for example for animations or messages:
In one.script:
msg.post("#two", hashed.my_message, message)
in two.script:
if message_id == hashed.my_message then
--do stuff
end
Regarding optimizations (but rather micro-optimizations) it is good to localize as much as possible. I saw in some Lua libraries localized versions of used globals and this is pretty clever, especially when it comes to some commonly used ones or ones used in update() functions!
local table_insert = table.insert
local table_remove = table.remove
or even only table:
local table = table
local pairs, ipairs, print = pairs, ipairs, print
for i,v in pairs(some_table) do
table.insert(i)
print(v)
end
etc.
So when you actually overwrite the global with your local, you donât need to change each call in your code then
I like one idea from Monarch for logging handling, so when you have disabled debugging, the log function looks like this:
local function log(...) end
But when you enable debug, by calling monarch.debug(), you change the function to:
function M.debug()
log = print
end
So you basically only then assign any function to log()
This way, anywhere in the module you write:
log("something to print")
You print it only after enabling debug, otherwise it is just a very quick, almost neglectable call to empty function
Usually we use several fonts in our games to nicely display different numerical information (damage value, speed dial and so on). And Defold includes all ASCII characters in fonts. However, for this case, it doesnât make sense to store unused glyphs in the fonts . Especially if itâs a web game where the download size matters.
We deal with this by using FontForge, leaving only the necessary glyphs in the font. And, to simplify the task, I made a small online tool - https://jsbin.com/molahek
So, how to keep only the necessary glyphs in the font:
The difference in file size will be approximately like that:
Tip: do this only at the final stages of the project development.