[+][BUG][PL] Level Select Menu: Crash after multiple clicks

Started by Flopsy, August 23, 2026, 02:34:52 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Flopsy

So I was recording NeoLemmix 30 episodes today and I encountered crashes during one of my videos. The video is not live until mid September but I did record another video replicating what I did. It does seem to happen pretty randomly but when I click to open a tree of levels, the window might sometimes freeze and if I were to click again in this timeframe, I'll get the (not responding) on the window top line. Pressing X on the window then leads to the NeoLemmix is not responding window popping up.

This happens when I clicked the God Save The Queen pack in the embedded video, it's nothing to do with that pack, it's just a random thing that happens.


WillLem

The Level Select Menu going unresponsive is something I've been continually working to prevent ever since I started working on SuperLemmix. It's come a long way, but clearly could go further. I discovered the other day that the Search feature can still crash; I thought this was sorted, but it isn't.

This seems to happen most often with large level collections; measures have been taken to make larger collections more manageable, but there is still more to do.

Best guess: the message queue is being flooded with each click, and the UI doesn't have time to fully update before being given more clicks to resolve. I imagine that the best way to handle this is to find a way to actively ditch the existing queue whenever a new click is made. I'm not even sure if that's possible (or if it's standard programming practice), it's just what I'm guessing.

I'll investigate this again soon. Optimizing/improving the Level Select menu is one of my favourite things to do.

WillLem

Looking at the video again, this is a repeat of this bug in SuperLemmix. I never did figure out exactly what was causing it because it's impossible to test for. It happens randomly, and there are no definite steps that will cause it to happen. I can click many times in the Level Select menu and not duplicate the reported behaviour.

So, unless anyone has any debugging suggestions, this might be another one we just have to live with.

Simon

Flopsy filed this after a discussion that his level loading was slow. He said that some Lix levels took 5 seconds to load on cold disk cache, and similarly NL levels took a while to load. This can be mere coincidence, or it can point at a real connection.

Debugging idea: Introduce artificial delay in level loading or in tile loading. E.g., every tile loaded freshly from disk should make its loading thread sleep for 100 ms, or do some absurd extra file I/O like logging numbers from 1 through 10,000. Maybe the delay helps with reproducing this bug?

-- Simon

WillLem

Quote from: Simon on August 23, 2026, 11:38:59 PMDebugging idea

Thanks for the ideas :)

For now, I've guarded against re-entrancy for treeview and preview loading, both of which are relatively expensive tasks. They've already been fairly well optimized, but I realised that there's nothing actually preventing them from being called multiple times. Multiple quick-succession clicks would be a problem, then.

The re-entrancy guard should hopefully do it. Flopsy is testing now.

Caching is a very good idea, but... it would need to perform a cache every time it opens/closes to keep it up to date (potentially?).

WillLem

OK... guarding against re-entrancy didn't work (although I still can't shake the suspicion that this is what's responsible, albeit maybe from the Windows side).

I'll make an experimental build that logs clicks and ask Flopsy to test it, but... thinking about it, I'm beginning to wonder if it's time to just re-think the entire Level Select menu.

I'd like to set the treeview on fire and display the levels some other way.

Lix is able to search 1000+ levels in seconds. How does Lix store levels in the menu? Does it cache on load? Does it store them as a simple list and worry about connecting the level to data later, or is storage fully object-based?

The fact that Lix lists the levels on buttons is clever; the buttons cannot be clicked twice, which is an elegant way to prevent having to re-load the same level.

Simon

Hunch: Do the event handlers (callback functions) for on-click run in separate threads? Or somehow else separated from the main logic? And do they accomplish a lot of work by loading the level during the callback? Then: I'd try to make the event handlers lightweight. They should merely notify the main logic that filename/level X should be loaded. Later, the main logic opens the file. We can't get a race bug if only one thread ever opens files ...

... which means progess if these assumptions hold:
  • Avoiding such a race will actually fix the symptom.
  • Windows file I/O, or your UI library, can have such races in the first place.

I've written all the Lix UI myself (no UI library, only Allegro for the graphical primitives) and the UI runs single-threaded in the main thread. I can't run into a threading bug by design. The downside is that everything fast/parallelized/coroutine-like needs explicit and hand-written support for this in the UI widget that wants to parallelize. It's rare enough (only the level search) that it was fine to implement a coroutine by hand: Load level metadata from disk for several levels until N milliseconds have passed, then memorize progress and stop, and when the UI calls us next tick, load some more.

Level metadata loading is opening file, reading line-by-line until we have found author and title, and then closing it immediately. It duplicates part of the normal level loading, but that's okay, it's a speed hack. Windows file I/O still has to open the file in both cases for reading, I can't get around that in a level tree of loose files.

More details when I have more time.

-- Simon

WillLem

Quote from: Simon on August 27, 2026, 04:48:46 AMHunch: Do the event handlers (callback functions) for on-click run in separate threads?

I'm not entirely sure to be honest. I certainly haven't implemented any sort of threading, but it may have been done by one of the previous devs.

Quote from: Simon on August 27, 2026, 04:48:46 AMAnd do they accomplish a lot of work by loading the level during the callback? Then: I'd try to make the event handlers lightweight. They should merely notify the main logic that filename/level X should be loaded. Later, the main logic opens the file.

I'm about 60% sure that the click is too heavy; the handler calls a method which includes loading level info and all sorts of other stuff. I've tried making it more lightweight by only processing exactly what we can see at any given time, but the click certainly could be more optimized.

Do you imagine: the click should 'request' that we load the level? Then, once the click has been eaten by Windows, then and only then load the level? (And, suppress further clicks until the level loading is complete?)

That could work!

Another collaboration session might be due. It would be good to look at a few bugs with you. We can look at Lix as well, it would be good to get the 'release mouse' hotkey finished.