-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat: add binmap plugin #4235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat: add binmap plugin #4235
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm actually a bit reluctant to merge this because "simple binary formats" come in so many flavors, given that "simple" usually means leaving out a bunch of information and different projects will need different subsets of the information available.
So you apparently only care about tile layers and might not care about image collections, isometric staggered, custom properties, the list of tilesets, parallax settings, layer blend modes, etc. But what's the use of shipping this "binmap" plugin, which presents this subset to many others who'll likely find some of the information they need missing?
As such, I do think the binmap-format.js
can be helpful. For those who need just that, they can copy it over, but for those who need a little more or even less information, they can easily tweak it to their needs. But I'm not sure it makes sense to ship this extension with Tiled. What about using it as an example binary map format in mapeditor/tiled-extensions and linking to it from the documentation?
hu16[5] = map.tileWidth; | ||
hu16[6] = map.tileHeight; | ||
/* looks like the Javascript API can't handle hexagonal maps */ | ||
hu16[7] = map.Isometric ? 1 : 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
map.Isometric
doesn't exist. What you're looking for is map.orientation
, which will beTileMap.Orthogonal
, TileMap.Isometric
, TileMap.Staggered
or TileMap.Hexagonal
.
|
||
write: (map, fileName) => { | ||
let numLayers = 0, gid = 1; | ||
/* fix missing firstgid properties on tilesets */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a "fix". "First global IDs" simply don't exist outside of the file format. It's fine to assign them as dynamic properties like this, but you'll want to reword that comment. :-)
/* fix missing firstgid properties on tilesets */ | ||
for (let i = 0; i < map.tilesets.length; ++i) { | ||
map.tilesets[i].firstgid = gid; | ||
gid += map.tilesets[i].tileCount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll have to note that using tileCount
unfortunately only works when there are no gaps in the tile IDs. Image collection tilesets can contain gaps, since when you remove tiles from such a tileset the other tiles don't change their ID.
If you want to support image collection tilesets, you'd currently need to iterate all tiles to find the maximum used tile ID.
case Map::Isometric: header.orientation = O_ISO; break; | ||
case Map::Hexagonal: header.orientation = map->staggerAxis() == Map::StaggerX ? O_HEXH : O_HEXV; break; | ||
default: | ||
mError = QCoreApplication::translate("File Errors", "Unsupported map format."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not support Map::Staggered
in this file format? Seems like it'd just take one more possible orientation value. At least, since staggerIndex
is not getting exported.
const tile = layer.tileAt(x, y); | ||
/* convert local tile id to global tile id */ | ||
iu16[0] = tile == null ? 0 : tile.id + (tile.tileset ? tile.tileset.firstgid : 1); | ||
file.write(item); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a performance perspective I'd suggest writing entire layers at once rather than tile-by-tile.
Precisely. This format is specifically for those who don't need anything else (99% of beginner projects) and find including an XML parser an overkill and overcomplicated.
Unfortunately it can't work correctly without firstGid properties. Current workaround isn't perfect as you've noted.
I've tried to use that, but didn't work. I'm open to whatever suggestion to query the TileMap format. Although this isn't an issue in the C++ version, that works well.
This is exactly why the C++ implementation is needed because that uses the GidMapper class so it can save global tile ids correctly. |
It should work, so please provide more details so we may find out what was going wrong here. A quick test in the Console view didn't reveal a problem to me:
While it does highlight a missing property in the scripting API, it can be worked around with minimal code: maxTileId = tileset.tiles.reduce((maxId, tile) => Math.max(maxId, tile.id), -1);
// instead of tileset.tileCount, use maxTileId + 1 Internally tilesets have a
While I entirely agree the format is simple to write and read, I still think it's better served as example and a starting point rather than a fixed format. |
Tiled BinMap Export Plugin
This is a Tiled plugin to dump tilemaps into a brainfuckingly simple binary format.
It ships BinMap as a plugin (which can be compiled into an .so file) as well as an extension (a .js file).
Installation
You'll only need one of these, as they do exactly the same.
JavaScript Extension
Copy
src/plugins/binmap/binmap-format.js
into~/.config/tiled/extensions
.Tiled Plugin
src/plugins/binmap
directory into the downloaded repository.src/plugins/plugins.qbs
and add"binmap",
to the list.qbs
.Documentation
The file format specification can be found here. It is the simplest format possible,
just contains a fixed sized header and the uncompressed tile ids for each layer, that's all.