Hi everyone, I’ve been working on a small Defold library that generates tile maps from LDtk files (I’ve tested it in a game jam already!) and would like some tips and help on the solutions I came up with.
Currently you can right-click and select “Generate Tilemaps” to generate a .tilemap file for each level from LDtk, all layers get generated with a Z order based on the order of the layers on LDtk.
You can also set a custom string property called “tile_set” in your LDtk levels that holds the path for the corresponding .tilesource file in your Defold project.
basically, what is being done is grabbing the LDtk JSON, saving the data from the levels to a Lua table then formatting it to a string that looks like the text format (protobuf?) used by .tilemaps in Defold like this:
local cells_data = string.format([[
cell {
x: %i
y: %i
tile: %i
%s
}]], x_value, y_value, cell.t, flip_values)
return cells_data
And recursively to the layers too:
local layer_data = string.format(
[[layers {
id: %q
z: %.2f
%s
}]], string.lower(layer.__identifier or "layer1"), z_counter, cells_data)
return layer_data
This works perfectly fine, I’ve tested it a bit by generating some 160x160 (grid size of 16 so 2560px) levels, and it takes a few seconds for sure but all tile maps are generated correctly.
But I’m sure there are better methods for doing something like this?
Entities layer
I also started implementing a way to convert Entity layers that can hold information of LDtk levels to Lua modules so it can be used on the Defold project too.
For every Entity layer it generates a new Lua module (named after the layer), inside will be the information of the layer for EVERY level in the game.
I also transform all the JSON information from this to a Lua table and then a formatted string that I write to a file:
if type(v) == "table" then
if type(k) == "number" then
table.insert(result, indent .. "{")
else
table.insert(result, indent .. string.format("%s", k) .. " = {")
end
serialize(v, next_indent)
table.insert(result, indent .. "},")
elseif type(v) == "string" then
table.insert(result, indent .. k .. " = " .. string.format("%q,", v))
else
table.insert(result, indent .. k .. " = " .. tostring(v) .. ",")
end
So I definitely don’t think this is the best way to create and write a Lua module to a file right?
And also would Lua modules work and scale fine for Entity layers? Or maybe should I look into other solutions?
For example, you create entities in your levels to hold the spawn position of enemies, if you have a lot of levels (and of course the bigger they are and the more entities they have, the more data there is) you would have to check a huge module file to get the info you need for a specific level, I know that there’s no way to avoiding having a huge file (or having a lot of files), after all the information has to exist somewhere to be used, but are Lua modules the solution for this?
I think I’ll be posting the library in a few days, at least the tilemap generation side since I think it that works fine and could be useful for some people like me who enjoy using LDtk.
Thanks everyone for reading this and of course any help, guidance, feedback is appreciated!!