Using external tilemaps?

Hello! I’m making a game that uses many different tilemaps, and right now I have all of them in my Defold project. However, I would like others to be able to create new tilemaps (using Tiled) without having access to the Defold project. I want something like a tilemap folder next to my executable, so that a user can put a tilemap in that folder and when the game is launched that tilemap is loaded and can be used. Ideally, all my tilemaps should be in that folder so users can modify already existing tilemaps as well.

Is there any way of doing this? I’ve been searching for a while and couldn’t find any solutions. I thought bundle_resources was the solution at first, but I can’t get it to work correctly (not getting the bundle folder when I bundle my project). Can anyone point me in the right direction?

Thanks a lot!


Interesting, I don’t know of any Defold game that has support for custom user content yet, I think it sounds like a cool idea! :slight_smile:

I would suggest that your users create their own levels(?) in for example Tiled and export to an easy-to-parse format like JSON (I believe Tiled can export JSON). You should be able to read the custom “tilemap”/levels using Lua io.* functions, and parse the JSON data into Lua tables using Defolds json module.

Then internally in your game you setup an empty tilemap that you at runtime can modify based on the custom user level data.

I don’t think there is any need to use either bundle_resources or custom_resources since with the io.* functions you can read files from anywhere.


Sven gives an excellent answer. The only missing piece in the puzzle is how to read new maps, not previously known to the game. The io.* functions and Lua in general has no notion of a file system with folders and there’s no way to iterate over all files in a folder in Lua. This is no oversight by the creators of Lua but rather a side effect of Lua being so extremely portable and thus limited in it’s features.

You have at least three solutions to this problem:

  1. Create a native extension wrapping Lua File System
  2. Use io.popen() and call platform specific shell functions such as ls and dir
  3. Use LuaJIT’s FFI system to call C functions to perform the tasks

Thanks to both of you for very good answers! I just tried the io.* functions and they seem to work perfectly. The only problem now is the one @britzl wrote about. I think I will solve this temporarily by having a known “index file” which contains paths to all the tilemaps. The user can then create new tilemaps and write the path to the tilemaps in the index file, which is then read at runtime so the game knows where the tilemaps are located. It’s a bit sloppy but it’s good enough for now.

It would however be really cool to have a built-in function in Defold to access custom content from a folder. It could open up a game to easy modding as well if you have all assets in a folder that the user can modify.

1 Like

FYI: I created an LFS wrapper as a native extension


@britzl @sven But if one has tiled tileset in .lua or .json file, wouldn’t one need to set a tilemap.bounds first? Is there a way to load a tilemap from file without pre-difined bounds?

1 Like

Currently, you need to set the bounds at edit time in the editor.

@Mathias_Westerdahl so in case I have 4 maps I want to load before the game starts I would need to make them all the same size?

What I mean is that you cannot set a tile at runtime (on a tilemap) outside of the precreated bounds of that tilemap.

If you have precreated levels in tilemaps, they can be of different sizes.

If you are using an “empty” tilemap as a generic tilemap, by filling in the tiles at runtime (e.g. with data from a .json file), then you cannot set tiles outside of the bounds.


Thanks for the clarification @Mathias_Westerdahl . It would be really cool if one would not even need to define bounds in the first place tho or change them at runtime. Would it be a quick fix to add this feature or does it dig much deeper into engine design?

Things are rarely quick fixes :slight_smile: There’s a feature request here: