LDtk

  • docs/archives/**, tests/, app/extraFiles, .ldtk, .md, .map, .js, .cpp, .cs, .go, .py, .rs, .log, .css, .scss, .gitignore,

About
  • LDtk .

  • LDtk .

  • Open-source.

  • Made in Haxe.

  • "From the director of DeadCells".

  • Formerly 'LEd'.

Impressions
  • Initially the app is intimidating with the amount of information, giving the impression that it is quite bloated. However, if you ignore the examples and create a blank project, the app becomes much simpler and more pleasant.

  • There is no customization of shortcuts or interface customization.

  • The button to create an entity, resize an entity and select an entity is the same (MB1) and cannot be changed.

    • This is annoying, many times I create an entity when I only wanted to move the existing one.

  • The exported data is considerably more complex than Tiled's data.

    • This is not necessarily a problem, since it is still a json file.

  • (2025-03-06)

    • The issue tracker  has several bug reports, but it is quite abandoned.

    • There are basically no PRs.

    • Both Issues and PRs receive no response or comment.

    • The last update was 1 year and 2 months ago.

    • The last commit was 4 months ago.

Compile

Setup
  • haxe setup.hxml

    • Install required Haxe libs, listed in the file setup.hxml .

  • cd app  -> npm i

    • Install Electron locally and other dependencies through NPM.

Compile
  • haxe main.debug.hxml

  • haxe renderer.debug.hxml

  • cd app  -> npm run start

  • The app/package.json  contains a list of other commands to use with npm run _command_

Change entries
  • In LDtk :

    • Add the entry in the class by changing the entries in:

      • new

      • toJson

      • fromJson

    • Visually:

      • related .html  file.

        • Makes things appear in the interface, but nothing is saved when making any change.

      • ui/modal/panel/_related_script_/updateForm()

        • Used to save the changes made in the interface. Without this, opening and closing a tab in the app loses the information.

        • References:

          • zindex .

          • ysort .

          • colWidth .

          • colMode .

  • In ldtk-haxe-api (Schema) :

    • About :

      • It is necessary to change the ldtk-haxe-api , because it is there that the json schemas are obtained.

      • The classes ldtk.Json , etc, come from that lib.

      • It is not necessary to change docs/JSON_SCHEMA.json  or docs/MINIMAL_JSON_SCHEMA.json .

      • It is not necessary to change the version of ldtk-haxe-api  before running the haxelib git ldtk-haxe-api ... etc  command.

    • Change the files of the ldtk-haxe-api .

      • I believe the only important file is src/json.hx

    • COMMIT the modifications to the remote.

      • You need to do this every time you change the ldtk-haxe-api .

    • Run LDtk - Fetch Schema .

      • Runs this in the background: haxelib git ldtk-haxe-api https://github.com/caioraphael1/ldtk-haxe-api.git caio

      • You need to do this every time you change the ldtk-haxe-api .

  • Finally :

    • Run LDtk - Compile & Run .

  • My post:

      1. I figured it out: I had to fork https://github.com/deepnight/ldtk , make my changes in the src/ldtk/Json.hx  file, push to remote, and run inside the ldtk root folder haxelib git ldtk-haxe-api https://github.com/caioraphael1/ldtk-haxe-api.git caio , which refers to my github fork and branch caio .

    • I have no idea if this is the "right way" to do it, but it works.

    • I didn't have to alter the setup.hxml  file, but I had to make sure to run the haxelib  with the correct path to my fork. Placing a reference to my fork inside the setup.hxml  file and running haxe setup.hxml  didn't work, for some reason, so I ended up just ignoring the setup.hxml  file.

Dissatisfactions

Editor

  • Does not support placing images in the world well.

    • It is always necessary to use a TileSet.

      • Use a tile that composes the entire image, or multiple smaller tiles that together compose the entire image.

  • LDtk's YSort is not done across different layers.

    • Severity :

      • It's just a visual inconvenience in LDtk, it doesn't break the data.

    • "A layer with YSort enabled should interact with the tiles contained in itself and with other layers that also have YSort enabled".

      • In other words, it's like adding itself to a pool to perform ordering.

  • LDtk changes casing and removes characters, even in the most "liberal" case.

  • There is no grouping of Layers.

    • This would be useful to organize the Floors of my game.

    • Not gamebreaking or anything. I use IntGrid to make the separation.

  • Does not allow Isometric or Hexagonal Grids.

Entities

  • Entity placement tool :

    • EntityLayer entities cannot be flipped.

      • Tiles can be flipped with the X or Y button, but entities cannot.

    • Does not allow deleting entities in bulk with Shift MB2.

    • Does not allow selecting entities in bulk with Shift MB1.

  • Entities are not drawn with YSort.

    • I felt this was a problem when drawing trees as Entities.

Tileset

  • tile_size is always square; the TileSet does not allow editing tile width and height.

    • I felt this was a problem when drawing the cliff_32x16x16.

      • This made me have to edit the tile to be 48x48 instead of 16x48.

  • Padding and spacing of tiles are also square, not per axis.

  • Collision definition :

    1. ~ Each tile has a metadata field that accepts a polygon to represent collision.

    2. The TileSet has an Enum with 3 fields; each field shows the following options below when selected:

      • Impressions :

        • (2025-06-11) Does not solve basically any problem. Works for some extremely specific cases, but it's not a good solution.

      • "I place the pivot at the base of the tree trunk and associate a capsule-shaped collision enum".

      • Box.

        • width.

        • height.

      • Capsule (box with trimmed edges).

        • width.

        • height.

      • Circle.

        • radius.

    3. The TileSet has a single collision editor, so you can draw 1 polygon that represents the collision for ALL tiles.

  • Pivot Point :

    1. ~ Each tile has its own custom Origin (former pivot-point), measured in px, not %.

    2. It is necessarily a TileSet characteristic.

      • Impressions :

        • (2025-06-11) Although useful, it's much better to have a pivot associated with each tile, instead of the tileset, because it's annoying to deal with varied tilesets.

      • This makes it consistent with Entities.

      • This causes only a single Pivot editor to be implemented, valid for:

        • TileLayer.

          • Makes total sense, since TileLayer can only have 1 TileSet anyway.

        • InGrid / Auto-Layer.

          • Doesn't even have a PivotPoint, it makes sense to have it on the TileSet since IntGrid also can only have 1 TileSet.

    • It is not allowed to specify the tile's origin point.

      • This can be solved in IntGrid or in TileSet.

        • I must evaluate which of the two options makes more sense, considering TileLayer, IntGrid AND Auto-Layer problems.

      • This ends up being a bigger problem for Tibia-style cases.

      • It's also annoying when you want to place a simple decoration element, but it occupies a non-conventional space in the tile.

        • It's just an inconvenience, but not a big deal.

      • It is not possible to specify the YSort origin point of each tile.

        • This is solved with the ability to change the tile's origin while using that origin as the YSort Origin.

      • Useful :

        • The EntityLayer allows a nice customization of the PivotPoint; I should evaluate if that is valid for other cases.

        • The TileLayer allows changing the origin.

        • IntGridLayer and Auto-Layer do not allow changing the origin

          • This hinders drawing autotiles.

          • I felt this was a problem when drawing the cliff_32x16x16.

IntGrid

  • IntGridLayer tiles cannot be flipped.

  • IntGridLayer's YSort is buggy.

    • This is the YSort of a single layer with itself.

    • It's clearly buggy, draw the image below and play with it to understand.

    • .

  • RulesWizard flips tiles automatically, greatly disrupting setting different tiles.

TileLayer

  • Tile preview for TileLayer is quite confusing, resulting in a strange offset.

  • When flipping a Tile on any axis, it's confusing where the tile will be placed.

    • If the Tile had a preview like the EntityLayer this would be much better.

Features

  • Super simple export .

    • Saves a composite of the data, without saving any metadata or tiles.

    • When enabling this option, the software "crashed" 2 times, having to restart.

      • Since then, the project became corrupted and I couldn't save progress anymore.

      • When disabling this option, I was able to save the file again.

    • .

Non-features
  • No Isometric, no plans for it.

External

Zig
Godot
  • ldtk-importer .

    • Inspired by Amano's addon.

    • .

    • .

      • EntityLayer is just a Node2D.

    • Tiles in the tilemaps are split the same as in LDtk, so the ysort problem happens depending on how tiles were defined in LDtk.

    • Impressions :

      • (2025-03-15)

        • I had problems when:

          • If the tileset has a cell_size, but the TileLayer has another, importing with this addon everything breaks, so the texture is loaded into the wrong TileMapLayer node in Godot.

            • In short, everything explodes. Some nodes end up with 2 textures while others end up with none.

            • This is important to support cases where "trees are a large 100x100 tile positioned on a 16x16 grid", for example.

            • When I had this problem, the error in Godot's terminal was ultra confusing, even in verbose error mode (import option).

        • I felt quite insecure, as it's an abstraction of the process, obviously.

        • I prefer to simply make my own importer...

  • amano-ldtk-importer .

    • 2 years without updates.

    • Demo .

    • 'new inherited scene', from the .ldtk  file.

      • .

      • Reminiscent of the .gltf workflow.