Importer for LDtk level editor

In the past few days, I've been working on a library to use levels made with the level editor LDtk

This is the level editor created by Sebastien Benard which was the main game designer behind Dead Cells. https://ldtk.io/

This is really a convenient Level editor that let you create interconnected levels, place entities, and build level really fast especially if you use auto tiling.

ldtk3

I tried to support as many feature as possible:

  • create playdate tilemap
  • get a list of entities in a level
  • custom entities properties
  • create collisions
  • tile flipping
  • levels saved in separate files

The Code!

https://github.com/NicMagnier/PlaydateLDtkImporter

A small platform sample is also included in the project to see how it is used in practice.
platformer

LDtk.lua.zip (5.9 KB)
LDtk example.zip (203.1 KB)

Flipping tiles
The SDK doesn't support flipped tiles for tilemaps and it is a very convenient feature in LDtk so to emulate the feature I had to find an alternative.
If your tilemap uses flipped tiles, you need to create an additional tileset with flipped tiles. The original tileset will still be used by LDtk but at runtime if a tilemap use flipped tiles I will load the other one instead.
This is not ideal if you keep editing your tileset but I made it relatively easy to make the flipped version. This is just the whole tileset flipped vertically and horizontally.

bw_tiles-table-8-8 flipped-bw_tiles-table-8-8

Fast loader
One of the challenge was that parsing the file was relatively slow on the console so I implemented a solution where you can export the levels as lua files when you run the game.
So you can decide to enable fast loading, you will simply have to copy the lua files in you project folder. The level handling functions will stay the same.

Collisions
In theory there is different ways to define collisions in LDtk, I support only a specific one. You have to flag the tiles in your tileset with an enum to give properties to the tiles. In the game you simply request the tileIDs for the level. Easy Peasy.

playdate.graphics.sprite.addWallSprites( game.tilemap, LDtk.get_empty_tileIDs( level_name, "Solid") )


I hope that would be useful!

48 Likes

First of all. This project is super awesome! Thank you for making this.

Unfortunately though I get an error during compiling it. I get the following error

error: source/main.lua:2: No such file: CoreLibs/utilities/printer

When running pdc source ldtk.
I can compile without the printer import line though. Is it necessary? Or any idea if I'm doing something wrong?

Also: adding new tiles,saving, and them compiling does not make them visible in the game. Are there any extra steps to be taken?

I need to update the example. printer was used in previous SDK but now you have to import CoreLibs/object instead.

Also the example by default will cache the result of the import. It supposed to show how to use it but I think that might be confusing so I will also disable it by default.

You can comment out these lines in main.lua

if playdate.isSimulator then
	LDtk.export_to_lua()
end

I will try to fix these issues in the future and to put everything on GitHub. I'll update the thread when this

Cool. I'll try that!

K so as you can see CoreLibs/object was already included underneath. So I'm just gonna remove the line.
Screenshot 2022-05-17 at 20.03.48

As for the playdate.isSimulator code above, commenting it out wasn't enough. I also had to move the LDtk_lua_levels folder out of the Source folder which seemed a bit weird to me for people not used to the project.

So I made a small code change for you which just adds a variable to live.lua called use_fast_loader
because apparently you already had the option to give the fastloader as second var :slight_smile:
Doing this (LDtk.load( "levels/world.ldtk" , live.use_fast_loader)) then made the fastloading easily changeable + defaulted it to being off.

Here's to updated project to save you some time. :slight_smile: Don't worry. Nothing else is changed.

LDtk example.zip (215.3 KB)

3 Likes

@Nic I'm working on creating a Lua project framework/development stack to make it easier for Pulp users to jump to Lua, and your project example is was a perfect base for it. I've already got a great POC right now so asking for your permission if I can continue working on that :slight_smile:

1 Like

Yeah sure no problem. Take anything you want, no credit required (except
for the tiles that was created by Adam Saltsman Monochrome Caves by Adam Saltsman)

1 Like

Thank you so much for this! Going to be a huge, huge help for me while building my game.

I did run into one issue when trying to use this library; I'm relatively new to Lua and LDtk so not sure if this is my own fault or what, but "out of the box" I was seeing this error:

LDtk.lua:337: bad argument #1 to 'floor' (number expected, got nil)

It looks like line 337 is attempting to floor the value of tiles_list[id], but the id value itself appears to be a float. If I add a print(id) after line 315, I'm seeing values like 195.0, 200.0, etc. Perhaps the floor should be done to the id itself, and not the value returned by the table? Refactoring to this resolves the error:

table.insert(layer.tiles, tiles_list[math.floor(id)] or 1)

But, again, been programming for a while but definitely new to Lua, LDtk, and this library, so forgive me if I'm approaching this incorrectly! :sweat_smile:

Ah yes someone had reported this issue before but I didn't publish the fix yet.

Here it is:
LDtk.lua.zip (5.0 KB)

You were on the right track. The fix is a bit different and set the tileID to 0 because we cannot assume the first tile in the tileset is empty.

The issue if caused by some tiles that are not set in your tilemap. With the fix, it should work and display the tilemap properly, however you might have a problem if you create collision with your tilemap because all the tiles are are not set will be solid with the current SDK

1 Like

Woke up this morning thinking 'I NEED TO USE LDTK IN MY PLAYDATE PROJECT" and I'm very glad you already did all the hard work!

Thanks a lot <3

Cheers!

PS: I think your latest version has a missing lib ref ("lieb/writelua")

ok I finally put the importer on GitHub.

I also included writeLua directly in the importer to reduce dependencies.

5 Likes

Awesome work Nic! Thanks for the great library. The project I talked about earlier has now launched and is called Cotton.
I did a couple of improvements to your library to make it even more awesome. If you want I can offer pull request for them. Again thanks for all the help!

5 Likes

Thank you for making this tool, Nic! Being able to use LDtk greatly speeded up the development for me.

1 Like

Why is there a guard against having imagetable tilesets in other folders? I tried to run it without that check and it worked fine on simulator but then crashed on device because the imagetable came back nil. Not hard to work around but I cant find any information on why that would be happening and I'm really curious if you know.

That's a good question and I couldn't remember why I've put this path check in the first place.

In short, LDtk is saving the image path relative to the ldtk file. So when you load an image in a different folder the path of the image looks like that "your_ldtk_folder/../your_image_folder/image".
Windows, MacOS or Linux can resolve this type of path but no the playdate system (I guess because this is an embedded system).

1 Like

Is there no way to re-interpret the file path?
So that when it loads the imagetable source property it will re-write that property to what's needed on the PlayDate instead.

So in principle I don't like to do stuff that should be handheld by the OS especially things related to file path because this is often more complicated that it seems. You might write something that work in most case but there is always a weird edge case that create an issue. And if a future version of the OS fix the issue, it can be overlooked and you still have some glue code on your library.

But I can see that the limitation can be a pain so I added some glue code to go around the problem.
The latest version on GitHub should support loading tilesets in any folder of your project.

2 Likes

Just wanted to share my gratitude for this importer project! It's already saving me a ton of time building out levels.

1 Like

Some people in the community were asking me questions about how we use LDtk with our game Comet.

When I got into LDtk there weren't many youtube videos that actually showed people using the tool.
Just general hey look at this thing. Let me read the website and play with it for a few min.

So I decided to make a video.

My not so secret plan is to make it the defacto level editor for Playdate devs so I encourage you to check it out.

Hopefully this helps with that goal.

6 Likes

Just came here to say: Thank you. Such a powerful addition to the playdate toolkit! Amazing job <3