mapeditor/tiled

Do you want to work on this issue?

You can request for a bounty in order to promote it!

TileMap.autoMap() does not have a default search path, and/or could be helped by tiled.scriptPath #3485

juanitogan posted onGitHub

Is your feature request related to a problem? Please describe.

TileMap.autoMap() is difficult to use for creating extensions. It does not say what its default path is, but it appears to be tiled.applicationDirPath. This is not helpful to any use case.

Describe the solution you'd like

When giving a rulesOrMapFile arg that is not an absolute path, it might be useful to apply the default search path for rules.txt that the menu option uses.

It might be more useful, however, if that default search path put the path to the script file up front (or make it the only default path), so that it is easy to put your rules files with your scripts (without needing an absolute path with autoMap()).

Regardless of default search path or not, it would be helpful to provide something like a tiled.scriptPath property so that I can build the absolute path properly.

Describe alternatives you've considered

Currently, the best I have found thus far is to partially hard-code the path:

map.autoMap(FileInfo.path(map.fileName) + "/extensions/foo/foo-rules.txt")

... which requires the user to keep the extension in a specific place.

I am also considering not including automaps with the tilesets and scripts, and just scripting it all instead. More work, perhaps (could be less work, given the number of automaps required), but more flexibility as well, which I could certainly make use of. On the other hand, scripts might be more intimidating for users to mod than automaps are.


It does not say what its default path is, but it appears to be tiled.applicationDirPath. This is not helpful to any use case.

That might be the behavior on Windows, but I guess in the more general case, a non-absolute path will be considered relative to the current working directory of the Tiled process.

When giving a rulesOrMapFile arg that is not an absolute path, it might be useful to apply the default search path for rules.txt that the menu option uses.

That would mean interpreting it as relative to the respective map, though the map may not have been saved yet. I'm not really a fan of this solution since it may lead to inconsistent results and if you wanted this it would be easy to combine the relative path with map.fileName explicitly.

Could you try whether map.autoMap("ext:foo/foo-rules.txt") or even just map.autoMap("ext:foo-rules.txt") works? ext: refers to a virtual file path that looks up files in all installed extensions.

In addition, there is __filename in global scope for the current file, and see also tiled.extentionsPath. Usually the latter is no option though, since it's only the global extensions directory.

posted by bjorn over 2 years ago

Yeah, I don't like fuzzy solutions either and the default path thing felt too fuzzy as soon as I sent it. Still, defaulting to the script's path still sounds reasonable to me (and we know that path exists). But, I understand if that doesn't work either.

Yes, all of these work: map.autoMap("ext:/foo/foo-rules.txt") map.autoMap("ext:foo/foo-rules.txt") map.autoMap("ext:foo-rules.txt"). It seems it can find foo-rules.txt with or without specifying the /foo subfolder. This makes me then wonder about which rules.txt it might find if you have more than one in other script folders. I didn't test that deep. Thus, probably best to keep your rules.txt filenames somewhat unique given no other solution.

I remember seeing ext: mentioned somewhere while digging around the other day, but when I went back to see where, I couldn't find it again.

I also looked at tiled.extensionsPath before I posted. But, I see I had mistyped it: It was returning nothing and thus I thought it was set to Project Properties > Automapping Rules. Now, I see, yes, it returns the global dir as expected.

I've gotten nowhere with __filename and suspect I don't know how to use it. On its own, it gives a "not defined" error (as does window.__filename global.__filename globalThis.__filename ). With tiled.__filename and this.__filename it comes back as "undefined".

posted by juanitogan over 2 years ago

Still, defaulting to the script's path still sounds reasonable to me (and we know that path exists). But, I understand if that doesn't work either.

I'm not sure if that's possible, but I don't really want to go down that path. It would mean looking up the script filename on each function that takes a path parameter and using it to resolve the absolute path. This is hard to pull off consistently and even then might surprise users more than using the current working directory.

This makes me then wonder about which rules.txt it might find if you have more than one in other script folders. I didn't test that deep. Thus, probably best to keep your rules.txt filenames somewhat unique given no other solution.

Yes, all extensions are added to the search path, in unspecified order, so best to choose a somewhat unique name in this case.

I remember seeing ext: mentioned somewhere while digging around the other day, but when I went back to see where, I couldn't find it again.

Hmm, I had a look, but I guess it may not actually be documented...

I've gotten nowhere with __filename and suspect I don't know how to use it. On its own, it gives a "not defined" error (as does window.__filename global.__filename globalThis.__filename ). With tiled.__filename and this.__filename it comes back as "undefined".

See the note at https://doc.mapeditor.org/en/stable/reference/scripting/#api-reference:

The file path of the current file being evaluated. Only available during initial evaluation of the file and not when later functions in that file get called. If you need it there, copy the value to local scope.

This means (and the docs could be clearer about this I guess), doing the following in the global scope of the file:

const filename = __filename;

Such that after the file finishes evaluation, you'll still have the file name of the script available in the filename variable.

posted by bjorn over 2 years ago

I remember seeing ext: mentioned somewhere while digging around the other day, but when I went back to see where, I couldn't find it again.

Hmm, I had a look, but I guess it may not actually be documented...

Then I must have seen it in the source code somewhere... So, yeah, might need to doc it.

I've gotten nowhere with __filename and suspect I don't know how to use it. On its own, it gives a "not defined" error (as does window.__filename global.__filename globalThis.__filename ). With tiled.__filename and this.__filename it comes back as "undefined".

See the note at https://doc.mapeditor.org/en/stable/reference/scripting/#api-reference:

The file path of the current file being evaluated. Only available during initial evaluation of the file and not when later functions in that file get called. If you need it there, copy the value to local scope.

This means (and the docs could be clearer about this I guess), doing the following in the global scope of the file:

const filename = __filename;

Such that after the file finishes evaluation, you'll still have the file name of the script available in the filename variable.

Oh.................. yes, I do remember reading this before I started scripting... and, yes, I forgot about it later because it is not in the API docs (as it says). I blame Node. It's always fun to blame Node when you can. I even went back to this page several times to to read the Qt docs and other links, looking for a solution, and still missed this note on the page. That's on me. Anyhow, yes, this works fine and I can work with it.

Anyway, I've moved beyond using autoMap and am now scripting all autogen stuff for the toolset I'm about to release. Thus, I don't know when I might need __filename again, but I'm not likely to forget about it again. Thanks for the help. You can close this if you're done with all points here.

posted by juanitogan over 2 years ago

Fund this Issue

$0.00
Funded
Only logged in users can fund an issue

Pull requests