Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

Tilengine

2D retro grapics engine with true raster effects for creating 8/16 bit style games · By megamarc

Strange results with empty tiles in layers

A topic by vonhoff created Jul 18, 2022 Views: 509 Replies: 7
Viewing posts 1 to 2

Hi Marc, 

I'm really enjoying Tilengine so far! 

I'm getting some strange results with empty tiles in layers when I launch my application. I'm not sure what's causing the problem, but I'm hoping you might have some ideas. It seems that it gives different results every time I launch the executable, but it doesn't happen all the time. Perhaps I'm missing a few important lines of code to get the desired result, but I can't figure it out. 

I've included a few screenshots of the problem occurring, as well as the source code I used to build the application below. I'm using the latest version of Tilengine (v2.9.6) and the CsTilenginePure binding that I wrote a few weeks ago. My target platform is Windows 11. 

I appreciate any help you can provide.

Source code: TestApplication.zip - Google Drive

Developer

Hi!

Glad to know you're enjoying Tilengine so far :-)

I've observed missing random missing tiles in my own "Python Platformer" sister project, that uses the same assets you're using in your test project for the C# binding. However, your screenshots suffer much more from this effect than mine. I don't know the cause because the effect is random, but I'll do a small test in C with these assets, hoping to reproduce the issue and debug into the library (I can't debug from a foreign language binding).

(1 edit)

I had a theory about where the missing tiles might be, because I couldn't find any direct errors in the source code for loading the tiles. My theory was that the tiles are not actually missing, but are drawn behind all the layers. To test that theory, I wrote the same application in C, where I added code that turns off the background layer when the first action button is pressed. 

When I turned off the background layer, the tiles that were missing became visible. So now we know that the tiles are not actually missing, they are just drawn behind all the other layers. Maybe it's because of the priority of the layers, but I'm not sure. What do you think?

Developer

Hi!

I'm out on holydays for a week without my laptop so I can't check your theory. But I wanted to thank you for your interest on this issue and your help for improving and polishing Tilengine.

I'll check what happens with these missing tiles hiding behind the background layer. Let's keep in touch.

Regards and happy holidays!

Hi Marc,

I hope you're doing well. I took another look at the issue this afternoon and found a potential fix!

The issue seemed to occur randomly, and when something seems random it could have something to do with memory allocations. I managed to fix the issue by moving line 167 in LoadTileset.c to line 100. It should execute after the tilecount assignment.

After performing this fix, I no longer got randomly missing tiles, which is great. I'm not sure whether there would be a better fix, perhaps you might have an idea. I could make a pull request with the changes if you would like.

Developer

Hi vonhoff!

I revised your possible fix. I can't see the logic behind it, I'll share my thoughts here:

  • block around line 100 is called for every xml attribute found inside the main "tileset" tag. Here the loader is just gathering all the attributes
  • block around line 167 is called after the last "tileset" attribute has been issued, but before starting to process the next xml tag. Here the loader has all the xml attributes, so it proceeds to allocate memory for the required structures
  • "property" and "tile" xml tags are always found after main "tileset", so the required structures are always found to be already created.

Moving the creation of structures inside the parsing of a single attribute before the whole set of attributes has been gathered would be premature, and potentially dangerous. So I won't do a pull request with a fix until we don't understand why it works.

That said, you're right wit the assumption that nondeterministic (random) behaviour happens with memory management issues, as well as with threading. These two components change their state outside the control of the application, so they can present a different state each time if not properly managed.

I'll do some tests, as the "cliffs" tileset is very prone to exhibit this behaviour.

Thanks a lot for your support!

You're right, on second thought I don't see it as a solution either. The bug still persists with the incorrect solution I thought I had found. I'm just not that experienced with software development yet, I'm still learning.

I hope you can find something that could resolve the issue. Keep me up to date :-)

Developer

Hi!

I've found the cause, now I can proceed to write a fix. Quick fix for now: just open "layer_background.tsx" with Tiled version 0.13 or newer (released on August 2015) and save it without editing anything.

Tilengine relies on a tsx property called "tilecount" to determine how much memory the custom properties array will need. This property was introduced on Tiled 0.13. It seems that I created come of these tilesets long ago with an older version, so this property is missing. The loader doesn't check this value, so it allocates a 0 bytes array that gets filled with random garbage padding (legit arrays are properly zero-filled). This garbage causes that some tiles get priority property randomly set, making them appear in front of the front layer.

Regards,