Need help understanding exported flipped tiles

Hey, I need some help.
I’m completely new to Tiled, but it makes my workflow so much more efficient. I’m using my imported tile map to create my level, but the problem I’m coming into involves exporting flipped tiles.

Since I discovered Tiled so late into the development of my game, I’m finding it hard to implement some of the data.

It follows this psuedocode:


Import ‘terrain.csv’ as file
for each item in file
//need help here
var id = item
create tile and apply image

This works for all non-rotated tiles, but on some rotated tiles it returns numbers like

1610612908

I saw on the documentation about tile flipping: TMX Map Format — Tiled 1.7.2 documentation, but my knowledge of CS in general isn’t developed enough to completely understand what I need to implement.

I want to create a procedure that takes the number, and returns a set of booleans and the original ID.

id = 1610612908
def decode(id)
	//decode and stuff
	bool horizontal_flip = True/False
	bool vertical_flip = True/False
	bool diagonal_flip = True/False

	id = <decoded id>
	Return id, horizontal_flip, vertical_flip, diagonal_flip
	

Any idea if there is a module for this, or where I could start? I found pytmx, but again, I have no starting point to know where to look.

The newer docs in the “latest” branch cover the process in a little more detail: Global Tile IDs — Tiled 1.8.0 documentation

You first need to get the flags by doing a bitwise AND of the ID, then you need to clear those flags by setting them to 0. The syntax for doing both of these is similar across languages, so the C++ example in the docs should help. If you don’t understand bitfields like this, the bit field article on Wikipedia may help. You will first need to understand bitwise logic though, since bitfields are set and read using bitwise operators. The basic gist is that instead of the value as a whole having some meaning, some of the bits have individual meanings. You first read these individual bits to set your bools, then you clear those bits, and the value that remains is your global tile ID.

At that point, you’re still not done, because you also need to figure out which tileset the tile comes from, since Tiled maps can use multiple tilesets. The process for this is also described in the docs, and is included in the sample code.

Because of the tileset stuff, you should consider having some sort of “Tile” structure in your code that has a reference to the tileset the tile comes from, and instructions on how to draw it (e.g. the texture to use, the size and location within that texture). The flip flags should be stored separately from the tile, since a given Tile may be used in many places on the map, with different flips. So, when drawing the tiles, you’d have something like drawTile(x, y, tile, flags).

When deciding which way to orient the image based on the flags, look at the diagonal flip first. After flipping the tile antidiagonally (which is swapping its bottom left and top right corners), you can apply the horizontal and vertical flips in any order.

I think I may understand what you are saying. Sorry for my questions, I just started to learn to code this year.

So I would take the number mentioned in my post, which I do not need to decode or decompress, since I am using CSV files

1610612908

and convert it to binary, where it returns this 30 bit binary number

1100000000000000000000010101100

i read the first 3 digits, which are

110

and use them to set the booleans.

1 = hoz_flip -> True
1 = vert_flip -> True
0 = anti-diag flip -> False

i set these to 0, and use the remaining

00000000000000000000000010101100

to find my id, which is

172

My only question is, when I convert the original number to binary, shouldn’t it return a 32 bit number, rather than a 30 bit number?

Also, I am going to implement a ‘Tile’ structure with reference to the tile set, thanks for the advice!

You’ve got the idea, but made a couple of mistakes:

  1. Even if you’re only reading the horizontal, vertical, and antidiagonal flip bits, you should still clear the hexagonal 120 degree rotation bit, as it may be set (if you convert a hex map to an orthogonal map, the flag will no longer be used, but it’ll still be kept).
  2. 1610612908 is 0110 0000 0000 0000 0000 0000 1010 1100 in binary (note the leading 0). This is 32 bits. You provided 31 bits of it by cutting off the leading 0, which you then miscounted as 30. The 32nd bit (horizontal flip) is 0, the 31st bit (vertical flip) is 1, the 30th bit (antidiagonal flip) is 1, and the 29th bit (hex 120 rotation bit) is 0. The tile is flipped vertically and antidiagonally, which means it’s rotated 90 degrees anticlockwise.

172 is indeed your ID, but remember that this is still a global ID that needs to be converted to a tileset local ID before you know which tile it actually is.

Got it, that makes sense. What should I do with negative numbers? Would I use their complement, or?

You should be parsing the data as unsigned int32, not signed. There are no negative numbers.
If the language you’re using doesn’t offer that though, just looking at the raw bits and clearing them will get rid of any negatives anyway. It’s all the same bits, the difference is just how they’re interpreted.

Screenshot 2021-12-09 130042

It gives me this number in cell F7. Due to the limits of the project I am working on, I can only use python, so I cannot used unsigned. I convert this number to binary

-1111111111111111111111101011010

this obviously will not give me a proper global id after I clear the flags. However, I can take it’s signed 2’s complement, and it returns

10000000000000000000000010100110

This can be put ‘deflagged’ and decoded to get the global id, but I am not sure that it is returning the right number.

I highly recommend doing this in code rather than a spreadsheet, as they will handle numbers in different ways, and you’re making things more complicated than they normally would be xP

The numbers coming in from parsing the TMX/JSON will always be positive and Python will parse them correctly as far as the bits go, because AFAIK it uses a sign bit instead of using two’s complement like you did in your conversion. The actual bit used for the sign will vary based on implementation and the value, but once you clear the flags, you’ll be left with a positive integer no matter what representation was used.

Cool cool, this works! Last question, is their a chart or something of that sort of anti-diagonal flipping to rotations and flips?

Something like:
vertical + antidiagonal = 270 degrees rotation, no horizontal flip, no vertical flip
horizontal + antidiagonal = ~~ degrees rotation, ~~ horizontal flip, ~~vertical flip
vertical + horizonal + antidiagonal = ~~degrees rotation, ~~ horizontal flip, ~~vertical flip
etc.

I cannot use anti-diagonal flipping, as I am limited by my software. Thanks!

Place the different rotations/flips in Tiled, and then you can mouse over them to see the flags. That’ll probably be more intuitive for you, and it avoids issues relating to rotations in degrees that you might encounter in a chart, as engines vary in which direction those rotations are in, which means a given orientation may have different angles in different engines.