Kode / khamake

Kha's build tool.
http://kha.tech
15 stars 45 forks source link

Store/query mapping from original asset filenames to renamed/converted asset filenames #265

Open MoritzBrueckner opened 1 year ago

MoritzBrueckner commented 1 year ago

There are situations where one cannot use Kha's asset macros, e.g. if you don't know the asset names at the time of writing the code but only upon compilation or runtime. In this case it can be tricky to predict what Khamake will do with a file without adding a redundant implementation to the project's sources that also computes the file renaming & extension change. This redundant implementation may then suddenly fail if the upstream repos change, and in the worst case it could go unnoticed for quite some time since the change may only touch some edge cases... In general, projects should depend as little as possible on unspecified Khamake internals.

An example case for this is Armory, where it can happen that a user adds an asset to the compilation, Khamake then renames and/or converts it, and Armory still expects the exported file to be called like the original file.

So if Khamake was storing some kind of mapping between the original files and the output files that could be queried, an entire class of errors (e.g. Krom's infamous "Unknown error" when loading assets with a wrong name) or additional redundancy due to workarounds could be eliminated. The original files could for example be identified via the file path used in the Khafile then (I also thought about optionally using user-specified identifiers, but this could be difficult with wildcard asset paths).

A Kha function querying this mapping could look like the following:

// Using the example from https://github.com/Kode/Kha/wiki/khafile.js#advanced
// This could even be a macro since it obviously only works and makes sense for files that were included in the Khafile,
//     as a positive side effect no path information would be included in the build output
kha.Assets.filenameToAssetName("assets/folder1/map.txt"); // returns "folder1_map_txt"
kha.Assets.filenameToAssetName("assets/folder2/map.txt"); // returns "folder2_map_txt"

Or if the information shouldn't be accessible from Kha and only at/around build time, something like this could work:

Kha/make --getFilenameMapping filename_mapping.json

In this case, Khamake would only do a dry run of the build in which the mapping file is generated (does not have to be json, that's just an example), and engines like Armory could then work with the asset names even before any Haxe sources are compiled. But to me the first approach (Kha API with a macro) looks better and probably more efficient in terms of overall build times.

Additionally, I think it would make sense to add another option similar like notinlist for assets that would specify whether an asset file needs to be included in the mapping file to keep the build size small. IMO it wouldn't make sense to use notinlist for this since if that option is false an asset would be included in the current asset macro generation which cannot be used in this use case anyways.

Thanks :)